Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vroad/d1a2e2cfe57ed7c9f5d7 to your computer and use it in GitHub Desktop.
Save vroad/d1a2e2cfe57ed7c9f5d7 to your computer and use it in GitHub Desktop.
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