Created
August 28, 2013 15:33
-
-
Save vroad/d1a2e2cfe57ed7c9f5d7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From a4667475861aef81f2ed667c6a0618a8095702c9 Mon Sep 17 00:00:00 2001 | |
From: vroad | |
Date: Tue, 27 Aug 2013 16:56:43 +0900 | |
Subject: [PATCH] Add an ability to draw 2d vertices with materials enabled | |
--- | |
examples/06.2DGraphics/main.cpp | 85 +++++++++++- | |
include/IVideoDriver.h | 20 +-- | |
include/irrlicht.h | 3 +- | |
source/Irrlicht/CAttributeImpl.h | 9 +- | |
source/Irrlicht/CD3D9Driver.cpp | 189 ++++++++++++++----------- | |
source/Irrlicht/CD3D9Driver.h | 13 +- | |
source/Irrlicht/CD3D9Texture.cpp | 18 ++- | |
source/Irrlicht/CD3D9Texture.h | 4 + | |
source/Irrlicht/CNullDriver.cpp | 24 ++-- | |
source/Irrlicht/CNullDriver.h | 9 +- | |
source/Irrlicht/COpenGLDriver.cpp | 275 +++++++++++++++++++------------------ | |
source/Irrlicht/COpenGLDriver.h | 6 +- | |
source/Irrlicht/COpenGLTexture.cpp | 24 +++- | |
source/Irrlicht/COpenGLTexture.h | 4 + | |
14 files changed, 417 insertions(+), 266 deletions(-) | |
diff --git a/examples/06.2DGraphics/main.cpp b/examples/06.2DGraphics/main.cpp | |
index 40e311a..a7396d6 100644 | |
--- a/examples/06.2DGraphics/main.cpp | |
+++ b/examples/06.2DGraphics/main.cpp | |
@@ -18,6 +18,28 @@ using namespace irr; | |
#pragma comment(lib, "Irrlicht.lib") | |
#endif | |
+video::SMaterial createInitMaterial2D() | |
+{ | |
+ video::SMaterial initMaterial2D; | |
+ initMaterial2D.AntiAliasing=video::EAAM_OFF; | |
+ initMaterial2D.Lighting=false; | |
+ initMaterial2D.ZWriteEnable=false; | |
+ initMaterial2D.ZBuffer=video::ECFN_NEVER; | |
+ initMaterial2D.UseMipMaps=false; | |
+ for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i) | |
+ { | |
+ initMaterial2D.TextureLayer[i].BilinearFilter=false; | |
+ initMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT; | |
+ initMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT; | |
+ } | |
+ return initMaterial2D; | |
+} | |
+ | |
+float frand(unsigned v) { | |
+ unsigned res = (v>>9) | 0x3f800000; | |
+ return (*(float*)&res) - 1.0f; | |
+} | |
+ | |
/* | |
At first, we let the user select the driver type, then start up the engine, set | |
a caption, and get a pointer to the video driver. | |
@@ -40,6 +62,7 @@ int main() | |
device->setWindowCaption(L"Irrlicht Engine - 2D Graphics Demo"); | |
video::IVideoDriver* driver = device->getVideoDriver(); | |
+ driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true); | |
/* | |
All 2d graphics in this example are put together into one texture, | |
@@ -56,6 +79,7 @@ int main() | |
*/ | |
video::ITexture* images = driver->getTexture("../../media/2ddemo.png"); | |
driver->makeColorKeyTexture(images, core::position2d<s32>(0,0)); | |
+ video::ITexture* fireImage = driver->getTexture("../../media/fireball.bmp"); | |
/* | |
To be able to draw some text with two different fonts, we first load | |
@@ -74,8 +98,29 @@ int main() | |
/* | |
Prepare a nicely filtering 2d render mode for special cases. | |
*/ | |
- driver->getMaterial2D().TextureLayer[0].BilinearFilter=true; | |
- driver->getMaterial2D().AntiAliasing=video::EAAM_FULL_BASIC; | |
+ video::SMaterial material2D = createInitMaterial2D(); | |
+ material2D.TextureLayer[0].BilinearFilter=true; | |
+ material2D.AntiAliasing=video::EAAM_FULL_BASIC; | |
+ video::SMaterial fireMaterial = createInitMaterial2D(); | |
+ fireMaterial.MaterialType=video::EMT_ONETEXTURE_BLEND; | |
+ fireMaterial.MaterialTypeParam=video::pack_textureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE, video::EMFN_MODULATE_1X, video::EAS_VERTEX_COLOR); | |
+ | |
+ struct SSprite | |
+ { | |
+ SSprite(const core::vector2df &pos, const core::vector2df &velocity, f32 alpha) | |
+ : Position(pos), Velocity(velocity), Alpha(alpha) {} | |
+ | |
+ core::vector2df Position; | |
+ core::vector2df Velocity; | |
+ f32 Alpha; | |
+ }; | |
+ core::list<SSprite> sprites; | |
+ core::array<u32> freeSpriteNo; | |
+ | |
+ IRandomizer* rand = device->getRandomizer(); | |
+ rand->reset(device->getTimer()->getRealTime()); | |
+ | |
+ u32 prevTime = device->getTimer()->getTime(); | |
/* | |
Everything is prepared, now we can draw everything in the draw loop, | |
@@ -141,8 +186,44 @@ int main() | |
the image we use the prepared filter mode. | |
*/ | |
driver->enableMaterial2D(); | |
+ driver->setMaterial(material2D); | |
driver->draw2DImage(images, core::rect<s32>(10,10,108,48), | |
core::rect<s32>(354,87,442,118)); | |
+ | |
+ u32 currentTime = device->getTimer()->getTime(); | |
+ u32 elapsedTime = currentTime - prevTime; | |
+ prevTime = currentTime; | |
+ | |
+ // draw fires | |
+ driver->setMaterial(fireMaterial); | |
+ core::list<SSprite>::Iterator it = sprites.begin(); | |
+ while(it != sprites.end()) | |
+ { | |
+ if ((*it).Alpha != 0) | |
+ driver->draw2DImage(fireImage, core::vector2di((s32)(*it).Position.X, (s32)(*it).Position.Y), | |
+ core::rect<s32>(0, 0, 64, 64), 0, video::SColor((u32)((*it).Alpha * 255.0f), 255, 255, 255)); | |
+ (*it).Position += (*it).Velocity * (f32)elapsedTime / 100.0f; | |
+ (*it).Alpha -= 0.25f * elapsedTime / 100.0f; | |
+ if ((*it).Alpha < 0.0f) | |
+ { | |
+ core::list<SSprite>::Iterator prevIt = it; | |
+ ++it; | |
+ sprites.erase(prevIt); | |
+ } | |
+ else | |
+ ++it; | |
+ } | |
+ | |
+ // spawn a fire | |
+ core::vector2df pos(224, 160); | |
+ f32 speed = 10.0f + frand(rand->rand()) * 30.0f; | |
+ core::vector2df velocity; | |
+ f32 angle = frand(rand->rand()) * core::PI * 4.0f; | |
+ velocity.X = sin(angle) * speed; | |
+ velocity.Y = cos(angle) * speed; | |
+ f32 alpha = 1.0f; | |
+ sprites.push_back(SSprite(pos, velocity, alpha)); | |
+ | |
driver->enableMaterial2D(false); | |
/* | |
diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h | |
index 8af6607..7ace386 100644 | |
--- a/include/IVideoDriver.h | |
+++ b/include/IVideoDriver.h | |
@@ -1018,6 +1018,10 @@ namespace video | |
/** \param mb Buffer to draw */ | |
virtual void drawMeshBuffer(const scene::IMeshBuffer* mb) =0; | |
+ //! Draws a mesh buffer in 2d mode | |
+ /** \param mb Buffer to draw */ | |
+ virtual void draw2DMeshBuffer(const scene::IMeshBuffer* mb) =0; | |
+ | |
//! Draws normals of a mesh buffer | |
/** \param mb Buffer to draw the normals of | |
\param length length scale factor of the normals | |
@@ -1411,22 +1415,6 @@ namespace video | |
\return Reference to the Override Material. */ | |
virtual SOverrideMaterial& getOverrideMaterial() =0; | |
- //! Get the 2d override material for altering its values | |
- /** The 2d override materual allows to alter certain render | |
- states of the 2d methods. Not all members of SMaterial are | |
- honored, especially not MaterialType and Textures. Moreover, | |
- the zbuffer is always ignored, and lighting is always off. All | |
- other flags can be changed, though some might have to effect | |
- in most cases. | |
- Please note that you have to enable/disable this effect with | |
- enableInitMaterial2D(). This effect is costly, as it increases | |
- the number of state changes considerably. Always reset the | |
- values when done. | |
- \return Material reference which should be altered to reflect | |
- the new settings. | |
- */ | |
- virtual SMaterial& getMaterial2D() =0; | |
- | |
//! Enable the 2d override material | |
/** \param enable Flag which tells whether the material shall be | |
enabled or disabled. */ | |
diff --git a/include/irrlicht.h b/include/irrlicht.h | |
index 74783ce..ac1b848 100644 | |
--- a/include/irrlicht.h | |
+++ b/include/irrlicht.h | |
@@ -185,7 +185,8 @@ | |
#include "SViewFrustum.h" | |
#include "triangle3d.h" | |
#include "vector2d.h" | |
-#include "vector3d.h" | |
+#include "vector3d.h" | |
+#include "irrUString.h" | |
/*! \mainpage Irrlicht Engine 1.8 API documentation | |
* | |
diff --git a/source/Irrlicht/CAttributeImpl.h b/source/Irrlicht/CAttributeImpl.h | |
index f59c27c..7a66595 100644 | |
--- a/source/Irrlicht/CAttributeImpl.h | |
+++ b/source/Irrlicht/CAttributeImpl.h | |
@@ -1270,12 +1270,17 @@ public: | |
setInt((s32)floatValue); | |
} | |
- virtual core::stringw getStringW() | |
+ virtual core::stringc getString() | |
{ | |
char tmp[10]; | |
const video::SColor c = getColor(); | |
sprintf(tmp, "%02x%02x%02x%02x", c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); | |
- return core::stringw(tmp); | |
+ return core::stringc(tmp); | |
+ } | |
+ | |
+ virtual core::stringw getStringW() | |
+ { | |
+ return core::stringw(getString()); | |
} | |
virtual void setString(const char* text) | |
diff --git a/source/Irrlicht/CD3D9Driver.cpp b/source/Irrlicht/CD3D9Driver.cpp | |
index 7404894..9b2e527 100644 | |
--- a/source/Irrlicht/CD3D9Driver.cpp | |
+++ b/source/Irrlicht/CD3D9Driver.cpp | |
@@ -696,17 +696,18 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const | |
void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, | |
const core::matrix4& mat) | |
{ | |
- Transformation3DChanged = true; | |
- | |
switch(state) | |
{ | |
case ETS_VIEW: | |
+ Transformation3DChanged = true; | |
pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); | |
break; | |
case ETS_WORLD: | |
+ Transformation3DChanged = true; | |
pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); | |
break; | |
case ETS_PROJECTION: | |
+ Transformation3DChanged = true; | |
pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); | |
break; | |
case ETS_COUNT: | |
@@ -821,6 +822,9 @@ bool CD3D9Driver::setRenderTarget(video::ITexture* texture, | |
// First texture handled elsewhere | |
pID3DDevice->SetRenderTarget(i, NULL); | |
} | |
+ | |
+ core::dimension2d<u32> prevRttSize = getCurrentRenderTargetSize(); | |
+ | |
if (tex == 0) | |
{ | |
if (PrevRenderTarget) | |
@@ -869,7 +873,8 @@ bool CD3D9Driver::setRenderTarget(video::ITexture* texture, | |
os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); | |
} | |
} | |
- Transformation3DChanged=true; | |
+ if (prevRttSize != getCurrentRenderTargetSize()) | |
+ Transformation3DChanged=true; | |
if (clearBackBuffer || clearZBuffer) | |
{ | |
@@ -1265,7 +1270,7 @@ void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) | |
//! Draw hardware buffer | |
-void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) | |
+void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer, bool is2D) | |
{ | |
if (!_HWBuffer) | |
return; | |
@@ -1292,7 +1297,10 @@ void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) | |
iPtr=0; | |
} | |
- drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
+ if (!is2D) | |
+ drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
+ else | |
+ draw2DVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
if (HWBuffer->vertexBuffer) | |
pID3DDevice->SetStreamSource(0, 0, 0, 0); | |
@@ -1462,6 +1470,9 @@ void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices, | |
} | |
else | |
{ | |
+ if (OverrideMaterial2DEnabled) | |
+ setRenderStates2DMode(true, true, true); // call the method with dummy parameter. | |
+ else | |
if (Material.MaterialType==EMT_ONETEXTURE_BLEND) | |
{ | |
E_BLEND_FACTOR srcFact; | |
@@ -1581,7 +1592,7 @@ void CD3D9Driver::draw2DImage(const video::ITexture* texture, | |
if(!texture) | |
return; | |
- const core::dimension2d<u32>& ss = texture->getOriginalSize(); | |
+ const core::dimension2d<u32>& ss = ((CD3D9Texture*)texture)->get2dRenderingSize(); | |
core::rect<f32> tcoords; | |
tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; | |
tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; | |
@@ -1749,10 +1760,11 @@ void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture, | |
// now draw it. | |
core::rect<f32> tcoords; | |
- tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; | |
- tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; | |
- tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); | |
- tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); | |
+ const core::dimension2d<u32>& ss = ((CD3D9Texture*)texture)->get2dRenderingSize(); | |
+ tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / ss.Width ; | |
+ tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / ss.Height; | |
+ tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / ss.Width); | |
+ tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / ss.Height); | |
const core::rect<s32> poss(targetPos, sourceSize); | |
@@ -1890,10 +1902,11 @@ void CD3D9Driver::draw2DImage(const video::ITexture* texture, | |
// now draw it. | |
core::rect<f32> tcoords; | |
- tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; | |
- tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; | |
- tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); | |
- tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); | |
+ const core::dimension2d<u32>& ss = ((CD3D9Texture*)texture)->get2dRenderingSize(); | |
+ tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / ss.Width ; | |
+ tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / ss.Height; | |
+ tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / ss.Width); | |
+ tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / ss.Height); | |
const core::rect<s32> poss(targetPos, sourceSize); | |
@@ -2568,39 +2581,27 @@ void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) | |
} | |
-//! Enable the 2d override material | |
-void CD3D9Driver::enableMaterial2D(bool enable) | |
-{ | |
- if (!enable) | |
- CurrentRenderMode = ERM_NONE; | |
- CNullDriver::enableMaterial2D(enable); | |
-} | |
- | |
- | |
//! sets the needed renderstates | |
void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) | |
{ | |
if (!pID3DDevice) | |
return; | |
- if (CurrentRenderMode != ERM_2D || Transformation3DChanged) | |
+ // unset last 3d/2d material | |
+ bool resetMode = CurrentRenderMode != ERM_2D && CurrentRenderMode != ERM_2D_OVERRIDE_MATERIAL; | |
+ bool switchedTo2D = !OverrideMaterial2DEnabled && CurrentRenderMode != ERM_2D; | |
+ bool resetMaterial = LastMaterial != Material || ResetRenderStates; | |
+ if (resetMode || switchedTo2D || resetMaterial) | |
{ | |
- // unset last 3d material | |
- if (CurrentRenderMode == ERM_3D) | |
- { | |
- if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) | |
- MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | |
- } | |
- if (!OverrideMaterial2DEnabled) | |
- { | |
- setBasicRenderStates(InitMaterial2D, LastMaterial, true); | |
- LastMaterial=InitMaterial2D; | |
+ if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) | |
+ MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | |
+ } | |
- // fix everything that is wrongly set by InitMaterial2D default | |
- pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); | |
- pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); | |
- } | |
+ if (resetMode || Transformation3DChanged) | |
+ { | |
+ pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9); | |
+ | |
core::matrix4 m; | |
// this fixes some problems with pixel exact rendering, but also breaks nice texturing | |
// moreover, it would have to be tested in each call, as the texture flag can change each time | |
@@ -2623,63 +2624,93 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan | |
Transformation3DChanged = false; | |
} | |
- if (OverrideMaterial2DEnabled) | |
+ | |
+ if (!OverrideMaterial2DEnabled) | |
{ | |
- OverrideMaterial2D.Lighting=false; | |
- setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); | |
- LastMaterial = OverrideMaterial2D; | |
- } | |
+ // reset renderstates set by other render mode | |
+ if (CurrentRenderMode != ERM_2D) | |
+ { | |
+ setBasicRenderStates(InitMaterial2D, LastMaterial, true); | |
+ LastMaterial=InitMaterial2D; | |
- // no alphaChannel without texture | |
- alphaChannel &= texture; | |
+ // fix everything that is wrongly set by InitMaterial2D default | |
+ pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); | |
- if (alpha || alphaChannel) | |
- { | |
- pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | |
- pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); | |
- pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); | |
- } | |
- else | |
- pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); | |
- if (texture) | |
- { | |
- setTransform(ETS_TEXTURE_0, core::IdentityMatrix); | |
- // Due to the transformation change, the previous line would call a reset each frame | |
- // but we can safely reset the variable as it was false before | |
- Transformation3DChanged=false; | |
- } | |
- if (alphaChannel) | |
- { | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
+ pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); // ? | |
+ } | |
- if (alpha) | |
+ // no alphaChannel without texture | |
+ alphaChannel &= texture; | |
+ | |
+ if (alpha || alphaChannel) | |
{ | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
+ pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | |
+ pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); | |
+ pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); | |
} | |
else | |
+ pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); | |
+ if (texture) | |
{ | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | |
+ setTransform(ETS_TEXTURE_0, core::IdentityMatrix); | |
+ // Due to the transformation change, the previous line would call a reset each frame | |
+ // but we can safely reset the variable as it was false before | |
+ Transformation3DChanged=false; | |
+ pID3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); | |
+ pID3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); | |
+ pID3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); | |
} | |
- } | |
- else | |
- { | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
- if (alpha) | |
+ if (alphaChannel) | |
{ | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
+ | |
+ if (alpha) | |
+ { | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
+ } | |
+ else | |
+ { | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | |
+ } | |
} | |
else | |
{ | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
- pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
+ if (alpha) | |
+ { | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); | |
+ } | |
+ else | |
+ { | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
+ pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ // set new material. | |
+ if (resetMaterial) | |
+ { | |
+ if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) | |
+ MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( | |
+ Material, LastMaterial, ResetRenderStates, this); | |
} | |
+ | |
+ bool shaderOK = true; | |
+ if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) | |
+ shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); | |
+ | |
+ LastMaterial = Material; | |
+ | |
+ ResetRenderStates = false; | |
} | |
- CurrentRenderMode = ERM_2D; | |
+ CurrentRenderMode = OverrideMaterial2DEnabled ? ERM_2D_OVERRIDE_MATERIAL : ERM_2D; | |
} | |
diff --git a/source/Irrlicht/CD3D9Driver.h b/source/Irrlicht/CD3D9Driver.h | |
index 095ae9d..4f3e7ad 100644 | |
--- a/source/Irrlicht/CD3D9Driver.h | |
+++ b/source/Irrlicht/CD3D9Driver.h | |
@@ -122,7 +122,7 @@ namespace video | |
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); | |
//! Draw hardware buffer | |
- virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); | |
+ virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer, bool is2D); | |
//! Create occlusion query. | |
/** Use node for identification and mesh for occlusion test. */ | |
@@ -306,9 +306,6 @@ namespace video | |
//! Returns the graphics card vendor name. | |
virtual core::stringc getVendorInfo() {return VendorName;} | |
- //! Enable the 2d override material | |
- virtual void enableMaterial2D(bool enable=true); | |
- | |
//! Check if the driver was recently reset. | |
virtual bool checkDriverReset() {return DriverWasReset;} | |
@@ -344,6 +341,7 @@ namespace video | |
{ | |
ERM_NONE = 0, // no render state has been set yet. | |
ERM_2D, // 2d drawing rendermode | |
+ ERM_2D_OVERRIDE_MATERIAL, // 2d override material rendermode | |
ERM_3D, // 3d rendering mode | |
ERM_STENCIL_FILL, // stencil fill mode | |
ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode | |
@@ -467,13 +465,6 @@ namespace video | |
f32 MaxLightDistance; | |
s32 LastSetLight; | |
- enum E_CACHE_2D_ATTRIBUTES | |
- { | |
- EC2D_ALPHA = 0x1, | |
- EC2D_TEXTURE = 0x2, | |
- EC2D_ALPHA_CHANNEL = 0x4 | |
- }; | |
- | |
ECOLOR_FORMAT ColorFormat; | |
D3DFORMAT D3DColorFormat; | |
bool DeviceLost; | |
diff --git a/source/Irrlicht/CD3D9Texture.cpp b/source/Irrlicht/CD3D9Texture.cpp | |
index 122ee2a..8f55053 100644 | |
--- a/source/Irrlicht/CD3D9Texture.cpp | |
+++ b/source/Irrlicht/CD3D9Texture.cpp | |
@@ -34,7 +34,7 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si | |
const io::path& name, const ECOLOR_FORMAT format) | |
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), | |
TextureSize(size), ImageSize(size), Pitch(0), ColorFormat(ECF_UNKNOWN), | |
- HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true) | |
+ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true), AllowNpot(false) | |
{ | |
#ifdef _DEBUG | |
setDebugName("CD3D9Texture"); | |
@@ -44,6 +44,8 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si | |
if (Device) | |
Device->AddRef(); | |
+ AllowNpot = Driver->getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2); | |
+ | |
createRenderTarget(format); | |
} | |
@@ -53,7 +55,7 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, | |
u32 flags, const io::path& name, void* mipmapData) | |
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), | |
TextureSize(0,0), ImageSize(0,0), Pitch(0), ColorFormat(ECF_UNKNOWN), | |
- HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) | |
+ HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false), AllowNpot(false) | |
{ | |
#ifdef _DEBUG | |
setDebugName("CD3D9Texture"); | |
@@ -65,6 +67,8 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, | |
if (Device) | |
Device->AddRef(); | |
+ AllowNpot = Driver->getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2); | |
+ | |
if (image) | |
{ | |
if (createTexture(flags, image)) | |
@@ -368,7 +372,10 @@ bool CD3D9Texture::copyTexture(IImage * image) | |
} | |
Pitch = rect.Pitch; | |
- image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); | |
+ if (AllowNpot) | |
+ image->copyToScaling(rect.pBits, ImageSize.Width, ImageSize.Height, ColorFormat, Pitch); | |
+ else | |
+ image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); | |
hr = Texture->UnlockRect(0); | |
if (FAILED(hr)) | |
@@ -466,6 +473,11 @@ const core::dimension2d<u32>& CD3D9Texture::getSize() const | |
return TextureSize; | |
} | |
+//! Returns size of the texture, that is used in 2d rendering | |
+const core::dimension2d<u32>& CD3D9Texture::get2dRenderingSize() const | |
+{ | |
+ return AllowNpot ? TextureSize : ImageSize; | |
+} | |
//! returns driver type of texture (=the driver, who created the texture) | |
E_DRIVER_TYPE CD3D9Texture::getDriverType() const | |
diff --git a/source/Irrlicht/CD3D9Texture.h b/source/Irrlicht/CD3D9Texture.h | |
index 812aa71..aca3286 100644 | |
--- a/source/Irrlicht/CD3D9Texture.h | |
+++ b/source/Irrlicht/CD3D9Texture.h | |
@@ -53,6 +53,9 @@ public: | |
//! Returns (=size) of the texture. | |
virtual const core::dimension2d<u32>& getSize() const; | |
+ //! Returns size of the texture, that is used in 2d rendering | |
+ const core::dimension2d<u32>& get2dRenderingSize() const; | |
+ | |
//! returns driver type of texture (=the driver, who created the texture) | |
virtual E_DRIVER_TYPE getDriverType() const; | |
@@ -117,6 +120,7 @@ private: | |
bool HasMipMaps; | |
bool HardwareMipMaps; | |
bool IsRenderTarget; | |
+ bool AllowNpot; | |
}; | |
diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp | |
index 3d02abe..8c9d508 100644 | |
--- a/source/Irrlicht/CNullDriver.cpp | |
+++ b/source/Irrlicht/CNullDriver.cpp | |
@@ -198,7 +198,6 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre | |
InitMaterial2D.TextureLayer[i].TextureWrapU=video::ETC_REPEAT; | |
InitMaterial2D.TextureLayer[i].TextureWrapV=video::ETC_REPEAT; | |
} | |
- OverrideMaterial2D=InitMaterial2D; | |
} | |
@@ -1516,11 +1515,25 @@ void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) | |
SHWBufferLink *HWBuffer=getBufferLink(mb); | |
if (HWBuffer) | |
- drawHardwareBuffer(HWBuffer); | |
+ drawHardwareBuffer(HWBuffer, false); | |
else | |
drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
} | |
+//! Draws a mesh buffer in 2d mode | |
+void CNullDriver::draw2DMeshBuffer(const scene::IMeshBuffer* mb) | |
+{ | |
+ if (!mb) | |
+ return; | |
+ | |
+ //IVertexBuffer and IIndexBuffer later | |
+ SHWBufferLink *HWBuffer=getBufferLink(mb); | |
+ | |
+ if (HWBuffer) | |
+ drawHardwareBuffer(HWBuffer, true); | |
+ else | |
+ draw2DVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
+} | |
//! Draws the normals of a mesh buffer | |
void CNullDriver::drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length, SColor color) | |
@@ -2407,13 +2420,6 @@ SOverrideMaterial& CNullDriver::getOverrideMaterial() | |
} | |
-//! Get the 2d override material for altering its values | |
-SMaterial& CNullDriver::getMaterial2D() | |
-{ | |
- return OverrideMaterial2D; | |
-} | |
- | |
- | |
//! Enable the 2d override material | |
void CNullDriver::enableMaterial2D(bool enable) | |
{ | |
diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h | |
index ead4776..f0148bf 100644 | |
--- a/source/Irrlicht/CNullDriver.h | |
+++ b/source/Irrlicht/CNullDriver.h | |
@@ -372,6 +372,9 @@ namespace video | |
//! Draws a mesh buffer | |
virtual void drawMeshBuffer(const scene::IMeshBuffer* mb); | |
+ //! Draws a mesh buffer in 2d mode | |
+ virtual void draw2DMeshBuffer(const scene::IMeshBuffer* mb); | |
+ | |
//! Draws the normals of a mesh buffer | |
virtual void drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length=10.f, SColor color=0xffffffff); | |
@@ -408,7 +411,7 @@ namespace video | |
virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer) {return false;} | |
//! Draw hardware buffer (only some drivers can) | |
- virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer) {} | |
+ virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer, bool is2D) {} | |
//! Delete hardware buffer | |
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); | |
@@ -630,9 +633,6 @@ namespace video | |
meshbuffer being rendered. */ | |
virtual SOverrideMaterial& getOverrideMaterial(); | |
- //! Get the 2d override material for altering its values | |
- virtual SMaterial& getMaterial2D(); | |
- | |
//! Enable the 2d override material | |
virtual void enableMaterial2D(bool enable=true); | |
@@ -830,7 +830,6 @@ namespace video | |
io::IAttributes* DriverAttributes; | |
SOverrideMaterial OverrideMaterial; | |
- SMaterial OverrideMaterial2D; | |
SMaterial InitMaterial2D; | |
bool OverrideMaterial2DEnabled; | |
diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp | |
index 1caa9c6..9706628 100644 | |
--- a/source/Irrlicht/COpenGLDriver.cpp | |
+++ b/source/Irrlicht/COpenGLDriver.cpp | |
@@ -937,12 +937,12 @@ const core::matrix4& COpenGLDriver::getTransform(E_TRANSFORMATION_STATE state) c | |
void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) | |
{ | |
Matrices[state] = mat; | |
- Transformation3DChanged = true; | |
switch (state) | |
{ | |
case ETS_VIEW: | |
case ETS_WORLD: | |
+ Transformation3DChanged = true; | |
{ | |
// OpenGL only has a model matrix, view and world is not existent. so lets fake these two. | |
glMatrixMode(GL_MODELVIEW); | |
@@ -960,6 +960,7 @@ void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matri | |
} | |
break; | |
case ETS_PROJECTION: | |
+ Transformation3DChanged = true; | |
{ | |
glMatrixMode(GL_PROJECTION); | |
glLoadMatrixf(mat.pointer()); | |
@@ -1271,7 +1272,7 @@ void COpenGLDriver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) | |
//! Draw hardware buffer | |
-void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) | |
+void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer, bool is2D) | |
{ | |
if (!_HWBuffer) | |
return; | |
@@ -1298,7 +1299,10 @@ void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) | |
indexList=0; | |
} | |
- drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
+ if (!is2D) | |
+ drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
+ else | |
+ draw2DVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); | |
if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) | |
extGlBindBuffer(GL_ARRAY_BUFFER, 0); | |
@@ -1768,7 +1772,10 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo | |
getColorBuffer(vertices, vertexCount, vType); | |
// draw everything | |
- this->setActiveTexture(0, Material.getTexture(0)); | |
+ //this->setActiveTexture(0, Material.getTexture(0)); | |
+ if (OverrideMaterial2DEnabled) | |
+ setRenderStates2DMode(true, true, true); // call the method with dummy parameter. | |
+ else | |
if (Material.MaterialType==EMT_ONETEXTURE_BLEND) | |
{ | |
E_BLEND_FACTOR srcFact; | |
@@ -1916,7 +1923,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, | |
const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); | |
- const core::dimension2d<u32>& ss = texture->getOriginalSize(); | |
+ const core::dimension2d<u32>& ss = ((COpenGLTexture*)texture)->get2dRenderingSize(); | |
const f32 invW = 1.f / static_cast<f32>(ss.Width); | |
const f32 invH = 1.f / static_cast<f32>(ss.Height); | |
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | |
@@ -2135,7 +2142,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, | |
// ok, we've clipped everything. | |
// now draw it. | |
- const core::dimension2d<u32>& ss = texture->getOriginalSize(); | |
+ const core::dimension2d<u32>& ss = ((COpenGLTexture*)texture)->get2dRenderingSize(); | |
const f32 invW = 1.f / static_cast<f32>(ss.Width); | |
const f32 invH = 1.f / static_cast<f32>(ss.Height); | |
const core::rect<f32> tcoords( | |
@@ -2178,7 +2185,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect | |
if (!texture) | |
return; | |
- const core::dimension2d<u32>& ss = texture->getOriginalSize(); | |
+ const core::dimension2d<u32>& ss = ((COpenGLTexture*)texture)->get2dRenderingSize(); | |
const f32 invW = 1.f / static_cast<f32>(ss.Width); | |
const f32 invH = 1.f / static_cast<f32>(ss.Height); | |
const core::rect<f32> tcoords( | |
@@ -2271,7 +2278,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, | |
clipRect->getWidth(),clipRect->getHeight()); | |
} | |
- const core::dimension2d<u32>& ss = texture->getOriginalSize(); | |
+ const core::dimension2d<u32>& ss = ((COpenGLTexture*)texture)->get2dRenderingSize(); | |
core::position2d<s32> targetPos(pos); | |
const f32 invW = 1.f / static_cast<f32>(ss.Width); | |
const f32 invH = 1.f / static_cast<f32>(ss.Height); | |
@@ -3188,167 +3195,173 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater | |
} | |
-//! Enable the 2d override material | |
-void COpenGLDriver::enableMaterial2D(bool enable) | |
-{ | |
- if (!enable) | |
- CurrentRenderMode = ERM_NONE; | |
- CNullDriver::enableMaterial2D(enable); | |
-} | |
- | |
- | |
//! sets the needed renderstates | |
void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) | |
{ | |
- if (CurrentRenderMode != ERM_2D || Transformation3DChanged) | |
+ // unset last 3d/2d material | |
+ bool resetMode = CurrentRenderMode != ERM_2D && CurrentRenderMode != ERM_2D_OVERRIDE_MATERIAL; | |
+ bool switchedTo2D = !OverrideMaterial2DEnabled && CurrentRenderMode != ERM_2D; | |
+ bool resetMaterial = LastMaterial != Material || ResetRenderStates; | |
+ if (resetMode || switchedTo2D || resetMaterial) | |
{ | |
- // unset last 3d material | |
- if (CurrentRenderMode == ERM_3D) | |
- { | |
- if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) | |
- MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | |
- } | |
- if (Transformation3DChanged) | |
- { | |
- glMatrixMode(GL_PROJECTION); | |
+ if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) | |
+ MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | |
+ } | |
- const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | |
- core::matrix4 m(core::matrix4::EM4CONST_NOTHING); | |
- m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f); | |
- m.setTranslation(core::vector3df(-1,1,0)); | |
- glLoadMatrixf(m.pointer()); | |
+ if (resetMode || Transformation3DChanged) | |
+ { | |
+ glMatrixMode(GL_PROJECTION); | |
- glMatrixMode(GL_MODELVIEW); | |
- glLoadIdentity(); | |
- glTranslatef(0.375f, 0.375f, 0.0f); | |
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | |
+ core::matrix4 m(core::matrix4::EM4CONST_NOTHING); | |
+ m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f); | |
+ m.setTranslation(core::vector3df(-1,1,0)); | |
+ glLoadMatrixf(m.pointer()); | |
- // Make sure we set first texture matrix | |
- if (MultiTextureExtension) | |
- extGlActiveTexture(GL_TEXTURE0_ARB); | |
+ glMatrixMode(GL_MODELVIEW); | |
+ glLoadIdentity(); | |
+ glTranslatef(0.375f, 0.375f, 0.0f); | |
- Transformation3DChanged = false; | |
- } | |
- if (!OverrideMaterial2DEnabled) | |
+ // Make sure we set first texture matrix | |
+ if (MultiTextureExtension) | |
+ extGlActiveTexture(GL_TEXTURE0_ARB); | |
+ | |
+ Transformation3DChanged = false; | |
+ } | |
+ if (!OverrideMaterial2DEnabled) | |
+ { | |
+ // reset renderstates set by other render mode | |
+ if (CurrentRenderMode != ERM_2D) | |
{ | |
setBasicRenderStates(InitMaterial2D, LastMaterial, true); | |
LastMaterial = InitMaterial2D; | |
- } | |
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
#ifdef GL_EXT_clip_volume_hint | |
- if (FeatureAvailable[IRR_EXT_clip_volume_hint]) | |
- glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); | |
+ if (FeatureAvailable[IRR_EXT_clip_volume_hint]) | |
+ glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); | |
#endif | |
+ } | |
- } | |
- if (OverrideMaterial2DEnabled) | |
- { | |
- OverrideMaterial2D.Lighting=false; | |
- setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); | |
- LastMaterial = OverrideMaterial2D; | |
- } | |
- | |
- // no alphaChannel without texture | |
- alphaChannel &= texture; | |
- | |
- if (alphaChannel || alpha) | |
- { | |
- glEnable(GL_BLEND); | |
- glEnable(GL_ALPHA_TEST); | |
- glAlphaFunc(GL_GREATER, 0.f); | |
- } | |
- else | |
- { | |
- glDisable(GL_BLEND); | |
- glDisable(GL_ALPHA_TEST); | |
- } | |
+ // no alphaChannel without texture | |
+ alphaChannel &= texture; | |
- if (texture) | |
- { | |
- if (!OverrideMaterial2DEnabled) | |
+ if (alphaChannel || alpha) | |
{ | |
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
+ glEnable(GL_BLEND); | |
+ glEnable(GL_ALPHA_TEST); | |
+ glAlphaFunc(GL_GREATER, 0.f); | |
+ } | |
+ else | |
+ { | |
+ glDisable(GL_BLEND); | |
+ glDisable(GL_ALPHA_TEST); | |
} | |
- Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0])); | |
- setTransform(ETS_TEXTURE_0, core::IdentityMatrix); | |
- // Due to the transformation change, the previous line would call a reset each frame | |
- // but we can safely reset the variable as it was false before | |
- Transformation3DChanged=false; | |
- if (alphaChannel) | |
+ if (texture) | |
{ | |
- // if alpha and alpha texture just modulate, otherwise use only the alpha channel | |
- if (alpha) | |
+ //if (!OverrideMaterial2DEnabled) | |
{ | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
} | |
- else | |
+ Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0])); | |
+ setTransform(ETS_TEXTURE_0, core::IdentityMatrix); | |
+ // Due to the transformation change, the previous line would call a reset each frame | |
+ // but we can safely reset the variable as it was false before | |
+ Transformation3DChanged=false; | |
+ | |
+ if (alphaChannel) | |
{ | |
-#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) | |
- if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) | |
+ // if alpha and alpha texture just modulate, otherwise use only the alpha channel | |
+ if (alpha) | |
+ { | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
+ } | |
+ else | |
{ | |
+#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) | |
+ if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) | |
+ { | |
#ifdef GL_ARB_texture_env_combine | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); | |
- // rgb always modulates | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); | |
+ // rgb always modulates | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); | |
#else | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); | |
- // rgb always modulates | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); | |
+ // rgb always modulates | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); | |
#endif | |
- } | |
- else | |
+ } | |
+ else | |
#endif | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
+ } | |
} | |
- } | |
- else | |
- { | |
- if (alpha) | |
+ else | |
{ | |
-#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) | |
- if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) | |
+ if (alpha) | |
{ | |
+#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) | |
+ if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) | |
+ { | |
#ifdef GL_ARB_texture_env_combine | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); | |
- // rgb always modulates | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); | |
+ // rgb always modulates | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); | |
#else | |
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); | |
- // rgb always modulates | |
- glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); | |
- glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); | |
+ // rgb always modulates | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); | |
+ glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); | |
+#endif | |
+ } | |
+ else | |
#endif | |
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
} | |
else | |
-#endif | |
+ { | |
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
+ } | |
} | |
- else | |
- { | |
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
- } | |
} | |
} | |
+ else | |
+ { | |
+ // set new material. | |
+ if (resetMaterial) | |
+ { | |
+ if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) | |
+ MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( | |
+ Material, LastMaterial, ResetRenderStates, this); | |
+ } | |
+ | |
+ if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) | |
+ MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD); | |
+ | |
+ LastMaterial = Material; | |
+ ResetRenderStates = false; | |
+ } | |
+ | |
- CurrentRenderMode = ERM_2D; | |
+ CurrentRenderMode = OverrideMaterial2DEnabled ? ERM_2D_OVERRIDE_MATERIAL : ERM_2D; | |
} | |
@@ -4145,6 +4158,7 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff | |
RenderTargetTexture->unbindRTT(); | |
} | |
+ core::dimension2d<u32> prevRttSize = getCurrentRenderTargetSize(); | |
if (texture) | |
{ | |
// we want to set a new target. so do this. | |
@@ -4164,7 +4178,8 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff | |
glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT); | |
} | |
// we need to update the matrices due to the rendersize change. | |
- Transformation3DChanged=true; | |
+ if (prevRttSize != getCurrentRenderTargetSize()) | |
+ Transformation3DChanged=true; | |
} | |
clearBuffers(clearBackBuffer, clearZBuffer, false, color); | |
diff --git a/source/Irrlicht/COpenGLDriver.h b/source/Irrlicht/COpenGLDriver.h | |
index 693052c..0f4c589 100644 | |
--- a/source/Irrlicht/COpenGLDriver.h | |
+++ b/source/Irrlicht/COpenGLDriver.h | |
@@ -102,7 +102,7 @@ namespace video | |
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); | |
//! Draw hardware buffer | |
- virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); | |
+ virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer, bool is2D); | |
//! Create occlusion query. | |
/** Use node for identification and mesh for occlusion test. */ | |
@@ -381,9 +381,6 @@ namespace video | |
//! \param enable: If true, enable the clipping plane else disable it. | |
virtual void enableClipPlane(u32 index, bool enable); | |
- //! Enable the 2d override material | |
- virtual void enableMaterial2D(bool enable=true); | |
- | |
//! Returns the graphics card vendor name. | |
virtual core::stringc getVendorInfo() {return VendorName;} | |
@@ -467,6 +464,7 @@ namespace video | |
{ | |
ERM_NONE = 0, // no render state has been set yet. | |
ERM_2D, // 2d drawing rendermode | |
+ ERM_2D_OVERRIDE_MATERIAL, // 2d override material rendermode | |
ERM_3D // 3d rendering mode | |
}; | |
diff --git a/source/Irrlicht/COpenGLTexture.cpp b/source/Irrlicht/COpenGLTexture.cpp | |
index 3cc41c0..13b1a01 100644 | |
--- a/source/Irrlicht/COpenGLTexture.cpp | |
+++ b/source/Irrlicht/COpenGLTexture.cpp | |
@@ -25,13 +25,14 @@ COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mi | |
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), | |
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true), | |
IsRenderTarget(false), AutomaticMipmapUpdate(false), | |
- ReadOnlyLock(false), KeepImage(true) | |
+ ReadOnlyLock(false), KeepImage(true), AllowNpot(false) | |
{ | |
#ifdef _DEBUG | |
setDebugName("COpenGLTexture"); | |
#endif | |
HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); | |
+ AllowNpot = driver->getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2); | |
getImageValues(origImage); | |
glGenTextures(1, &TextureName); | |
@@ -44,8 +45,15 @@ COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mi | |
else | |
{ | |
Image = Driver->createImage(ColorFormat, TextureSize); | |
- // scale texture | |
- origImage->copyToScaling(Image); | |
+ if (AllowNpot) | |
+ { | |
+ origImage->copyTo(Image); | |
+ } | |
+ else | |
+ { | |
+ // scale texture | |
+ origImage->copyToScaling(Image); | |
+ } | |
} | |
uploadTexture(true, mipmapData); | |
if (!KeepImage) | |
@@ -62,11 +70,13 @@ COpenGLTexture::COpenGLTexture(const io::path& name, COpenGLDriver* driver) | |
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), | |
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), HasMipMaps(true), | |
MipmapLegacyMode(true), IsRenderTarget(false), AutomaticMipmapUpdate(false), | |
- ReadOnlyLock(false), KeepImage(true) | |
+ ReadOnlyLock(false), KeepImage(true), AllowNpot(false) | |
{ | |
#ifdef _DEBUG | |
setDebugName("COpenGLTexture"); | |
#endif | |
+ | |
+ AllowNpot = driver->getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2); | |
} | |
@@ -542,6 +552,12 @@ const core::dimension2d<u32>& COpenGLTexture::getSize() const | |
return TextureSize; | |
} | |
+//! Returns size of the texture, that is used in 2d rendering | |
+const core::dimension2d<u32>& COpenGLTexture::get2dRenderingSize() const | |
+{ | |
+ return AllowNpot ? TextureSize : ImageSize; | |
+} | |
+ | |
//! returns driver type of texture, i.e. the driver, which created the texture | |
E_DRIVER_TYPE COpenGLTexture::getDriverType() const | |
diff --git a/source/Irrlicht/COpenGLTexture.h b/source/Irrlicht/COpenGLTexture.h | |
index 1fd4ca2..ce34a88 100644 | |
--- a/source/Irrlicht/COpenGLTexture.h | |
+++ b/source/Irrlicht/COpenGLTexture.h | |
@@ -68,6 +68,9 @@ public: | |
//! Returns size of the texture. | |
virtual const core::dimension2d<u32>& getSize() const; | |
+ //! Returns size of the texture, that is used in 2d rendering | |
+ const core::dimension2d<u32>& get2dRenderingSize() const; | |
+ | |
//! returns driver type of texture (=the driver, that created it) | |
virtual E_DRIVER_TYPE getDriverType() const; | |
@@ -143,6 +146,7 @@ protected: | |
bool AutomaticMipmapUpdate; | |
bool ReadOnlyLock; | |
bool KeepImage; | |
+ bool AllowNpot; | |
}; | |
//! OpenGL FBO texture. | |
-- | |
1.8.1.msysgit.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment