Commit fface044 authored by nadro's avatar nadro

- Rewritten OpenGL textures cache.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5154 dfc29bdd-3216-0410-991c-e03cc46cb475
parent be22e335
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Fix problem with OpenGL textures cache.
- Add clear buffer flags and marked some methods used for clear buffers as deprecated. - Add clear buffer flags and marked some methods used for clear buffers as deprecated.
- Fix: CGUIImage no longer scales wrong when working with textures which don't have the original image size. - Fix: CGUIImage no longer scales wrong when working with textures which don't have the original image size.
- Fix CSoftwareTexture2 calculation for OriginalSize of ITexture. It was returning the changed texture size instead of the original one before. - Fix CSoftwareTexture2 calculation for OriginalSize of ITexture. It was returning the changed texture size instead of the original one before.
......
...@@ -605,7 +605,7 @@ COpenGLDriver::~COpenGLDriver() ...@@ -605,7 +605,7 @@ COpenGLDriver::~COpenGLDriver()
deleteMaterialRenders(); deleteMaterialRenders();
CurrentTexture.clear(); BridgeCalls->TextureCache.clear();
// I get a blue screen on my laptop, when I do not delete the // I get a blue screen on my laptop, when I do not delete the
// textures manually before releasing the dc. Oh how I love this. // textures manually before releasing the dc. Oh how I love this.
removeAllRenderTargets(); removeAllRenderTargets();
...@@ -657,11 +657,11 @@ bool COpenGLDriver::genericDriverInit() ...@@ -657,11 +657,11 @@ bool COpenGLDriver::genericDriverInit()
} }
u32 i; u32 i;
CurrentTexture.clear();
// load extensions // load extensions
initExtensions(Params.Stencilbuffer); initExtensions(Params.Stencilbuffer);
if (!BridgeCalls) delete BridgeCalls;
BridgeCalls = new COpenGLCallBridge(this); BridgeCalls = new COpenGLCallBridge(this);
if (queryFeature(EVDF_ARB_GLSL)) if (queryFeature(EVDF_ARB_GLSL))
...@@ -1440,7 +1440,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -1440,7 +1440,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0); glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0);
} }
if (MultiTextureExtension && CurrentTexture[1]) if (MultiTextureExtension && BridgeCalls->TextureCache[1])
{ {
BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB); BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
...@@ -1519,7 +1519,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -1519,7 +1519,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
BridgeCalls->setClientActiveTexture(GL_TEXTURE2_ARB); BridgeCalls->setClientActiveTexture(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
if ((vType!=EVT_STANDARD) || CurrentTexture[1]) if ((vType!=EVT_STANDARD) || BridgeCalls->TextureCache[1])
{ {
BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB); BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
...@@ -1695,7 +1695,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo ...@@ -1695,7 +1695,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
getColorBuffer(vertices, vertexCount, vType); getColorBuffer(vertices, vertexCount, vType);
// draw everything // draw everything
this->setActiveTexture(0, Material.getTexture(0)); BridgeCalls->TextureCache.set(0, Material.getTexture(0));
if (Material.MaterialType==EMT_ONETEXTURE_BLEND) if (Material.MaterialType==EMT_ONETEXTURE_BLEND)
{ {
E_BLEND_FACTOR srcFact; E_BLEND_FACTOR srcFact;
...@@ -1760,7 +1760,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo ...@@ -1760,7 +1760,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), 0); glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), 0);
} }
if (MultiTextureExtension && CurrentTexture[1]) if (MultiTextureExtension && BridgeCalls->TextureCache[1])
{ {
BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB); BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
...@@ -1813,7 +1813,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo ...@@ -1813,7 +1813,7 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
if (MultiTextureExtension) if (MultiTextureExtension)
{ {
if ((vType!=EVT_STANDARD) || CurrentTexture[1]) if ((vType!=EVT_STANDARD) || BridgeCalls->TextureCache[1])
{ {
BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB); BridgeCalls->setClientActiveTexture(GL_TEXTURE1_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
...@@ -1843,7 +1843,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, ...@@ -1843,7 +1843,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
disableTextures(1); disableTextures(1);
if (!setActiveTexture(0, texture)) if (!BridgeCalls->TextureCache.set(0, texture))
return; return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
...@@ -2090,7 +2090,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -2090,7 +2090,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
const core::rect<s32> poss(targetPos, sourceSize); const core::rect<s32> poss(targetPos, sourceSize);
disableTextures(1); disableTextures(1);
if (!setActiveTexture(0, texture)) if (!BridgeCalls->TextureCache.set(0, texture))
return; return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
...@@ -2162,7 +2162,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -2162,7 +2162,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
const video::SColor* const useColor = colors ? colors : temp; const video::SColor* const useColor = colors ? colors : temp;
disableTextures(1); disableTextures(1);
if (!setActiveTexture(0, texture)) if (!BridgeCalls->TextureCache.set(0, texture))
return; return;
setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 ||
useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255,
...@@ -2239,7 +2239,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, ...@@ -2239,7 +2239,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
return; return;
disableTextures(1); disableTextures(1);
if (!setActiveTexture(0, texture)) if (!BridgeCalls->TextureCache.set(0, texture))
return; return;
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
...@@ -2472,29 +2472,6 @@ void COpenGLDriver::drawPixel(u32 x, u32 y, const SColor &color) ...@@ -2472,29 +2472,6 @@ void COpenGLDriver::drawPixel(u32 x, u32 y, const SColor &color)
glDrawArrays(GL_POINTS, 0, 1); glDrawArrays(GL_POINTS, 0, 1);
} }
bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
{
if (stage >= MaxSupportedTextures)
return false;
if (CurrentTexture[stage]==texture)
return true;
CurrentTexture.set(stage,texture);
if (!texture)
return true;
else if (texture->getDriverType() != EDT_OPENGL)
{
CurrentTexture.set(stage, 0);
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
return false;
}
return true;
}
//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. //! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled.
//! Returns whether disabling was successful or not. //! Returns whether disabling was successful or not.
bool COpenGLDriver::disableTextures(u32 fromStage) bool COpenGLDriver::disableTextures(u32 fromStage)
...@@ -2502,8 +2479,7 @@ bool COpenGLDriver::disableTextures(u32 fromStage) ...@@ -2502,8 +2479,7 @@ bool COpenGLDriver::disableTextures(u32 fromStage)
bool result=true; bool result=true;
for (u32 i=fromStage; i<MaxSupportedTextures; ++i) for (u32 i=fromStage; i<MaxSupportedTextures; ++i)
{ {
result &= setActiveTexture(i, 0); result &= BridgeCalls->TextureCache.set(i, 0);
BridgeCalls->setTexture(i, true);
} }
return result; return result;
} }
...@@ -2556,7 +2532,7 @@ void COpenGLDriver::setMaterial(const SMaterial& material) ...@@ -2556,7 +2532,7 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
for (u32 i = 0; i < MaxTextureUnits; ++i) for (u32 i = 0; i < MaxTextureUnits; ++i)
{ {
setActiveTexture(i, material.getTexture(i)); BridgeCalls->TextureCache.set(i, material.getTexture(i));
setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + i), material.getTextureMatrix(i)); setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
} }
} }
...@@ -3208,26 +3184,26 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset ...@@ -3208,26 +3184,26 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
for (s32 i = MaxTextureUnits-1; i>= 0; --i) for (s32 i = MaxTextureUnits-1; i>= 0; --i)
{ {
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(CurrentTexture[i]);
bool fixedPipeline = false; bool fixedPipeline = false;
if(FixedPipelineState == EOFPS_ENABLE || FixedPipelineState == EOFPS_DISABLE_TO_ENABLE) if (FixedPipelineState == EOFPS_ENABLE || FixedPipelineState == EOFPS_DISABLE_TO_ENABLE)
{ {
if (i>0 && !MultiTextureExtension) if (i > 0 && !MultiTextureExtension)
break; break;
fixedPipeline = true; fixedPipeline = true;
} }
BridgeCalls->setTexture(i, fixedPipeline); const COpenGLTexture* tmpTexture = BridgeCalls->TextureCache[i];
if (!CurrentTexture[i]) if (!tmpTexture)
continue; continue;
BridgeCalls->setActiveTexture(GL_TEXTURE0_ARB + i);
if (fixedPipeline) if (fixedPipeline)
{ {
const bool isRTT = CurrentTexture[i]->isRenderTarget(); const bool isRTT = tmpTexture->isRenderTarget();
BridgeCalls->setMatrixMode(GL_TEXTURE); BridgeCalls->setMatrixMode(GL_TEXTURE);
...@@ -3296,7 +3272,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset ...@@ -3296,7 +3272,7 @@ void COpenGLDriver::setTextureRenderStates(const SMaterial& material, bool reset
tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter; tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
} }
if (material.UseMipMaps && CurrentTexture[i]->hasMipMaps()) if (material.UseMipMaps && tmpTexture->hasMipMaps())
{ {
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter || if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus) material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus)
...@@ -3442,7 +3418,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -3442,7 +3418,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
else else
setTextureRenderStates(InitMaterial2D, false); setTextureRenderStates(InitMaterial2D, false);
Material.setTexture(0, const_cast<video::ITexture*>(CurrentTexture[0])); Material.setTexture(0, const_cast<COpenGLTexture*>(BridgeCalls->TextureCache[0]));
setTransform(ETS_TEXTURE_0, core::IdentityMatrix); setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
// Due to the transformation change, the previous line would call a reset each frame // 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 // but we can safely reset the variable as it was false before
...@@ -4028,8 +4004,6 @@ void COpenGLDriver::removeTexture(ITexture* texture) ...@@ -4028,8 +4004,6 @@ void COpenGLDriver::removeTexture(ITexture* texture)
return; return;
CNullDriver::removeTexture(texture); CNullDriver::removeTexture(texture);
// Remove this texture from CurrentTexture as well
CurrentTexture.remove(texture);
} }
...@@ -4256,11 +4230,14 @@ bool COpenGLDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor ...@@ -4256,11 +4230,14 @@ bool COpenGLDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor
if (renderTargetTexture) if (renderTargetTexture)
{ {
setActiveTexture(0, renderTargetTexture); const COpenGLTexture* prevTexture = BridgeCalls->TextureCache[0];
BridgeCalls->setTexture(0, true);
BridgeCalls->TextureCache.set(0, renderTargetTexture);
const core::dimension2d<u32> size = renderTargetTexture->getSize(); const core::dimension2d<u32> size = renderTargetTexture->getSize();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.Width, size.Height); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.Width, size.Height);
BridgeCalls->TextureCache.set(0, prevTexture);
} }
} }
...@@ -4638,7 +4615,120 @@ COpenGLCallBridge* COpenGLDriver::getBridgeCalls() const ...@@ -4638,7 +4615,120 @@ COpenGLCallBridge* COpenGLDriver::getBridgeCalls() const
return BridgeCalls; return BridgeCalls;
} }
COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), /* COpenGLCallBridge::STextureCache */
COpenGLCallBridge::STextureCache::STextureCache(COpenGLCallBridge* cacheHandler, u32 textureCount) :
CacheHandler(cacheHandler), TextureCount(textureCount)
{
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
Texture[i] = 0;
}
}
COpenGLCallBridge::STextureCache::~STextureCache()
{
clear();
}
const COpenGLTexture* COpenGLCallBridge::STextureCache::operator[](int index) const
{
if (static_cast<u32>(index) < MATERIAL_MAX_TEXTURES)
return Texture[static_cast<u32>(index)];
return 0;
}
bool COpenGLCallBridge::STextureCache::set(u32 index, const ITexture* texture)
{
bool status = false;
E_DRIVER_TYPE type = EDT_OPENGL;
if (index < MATERIAL_MAX_TEXTURES && index < TextureCount)
{
CacheHandler->setActiveTexture(GL_TEXTURE0_ARB + index);
const COpenGLTexture* prevTexture = Texture[index];
if (texture != prevTexture)
{
if (texture)
{
type = texture->getDriverType();
if (type == EDT_OPENGL)
{
texture->grab();
if (!prevTexture)
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
}
else
{
texture = 0;
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
}
}
if (!texture)
{
glBindTexture(GL_TEXTURE_2D, 0);
if (prevTexture)
glDisable(GL_TEXTURE_2D);
}
Texture[index] = static_cast<const COpenGLTexture*>(texture);
if (prevTexture)
prevTexture->drop();
}
status = true;
}
return (status && type == EDT_OPENGL);
}
void COpenGLCallBridge::STextureCache::remove(ITexture* texture)
{
if (!texture)
return;
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
if (Texture[i] == texture)
{
Texture[i] = 0;
texture->drop();
}
}
}
void COpenGLCallBridge::STextureCache::clear()
{
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
if (Texture[i])
{
const COpenGLTexture* prevTexture = Texture[i];
Texture[i] = 0;
prevTexture->drop();
}
}
}
/* COpenGLCallBridge */
COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) :
TextureCache(STextureCache(this, driver->MaxSupportedTextures)), Driver(driver),
AlphaMode(GL_ALWAYS), AlphaRef(0.0f), AlphaTest(false), AlphaMode(GL_ALWAYS), AlphaRef(0.0f), AlphaTest(false),
ClientStateVertex(false), ClientStateNormal(false), ClientStateColor(false), ClientStateTexCoord0(false), ClientStateVertex(false), ClientStateNormal(false), ClientStateColor(false), ClientStateTexCoord0(false),
CullFaceMode(GL_BACK), CullFace(false), CullFaceMode(GL_BACK), CullFace(false),
...@@ -4675,12 +4765,6 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver), ...@@ -4675,12 +4765,6 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
ColorMask[i][j] = true; ColorMask[i][j] = true;
} }
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
Texture[i] = 0;
TextureFixedPipeline[i] = true;
}
// Initial OpenGL values from specification. // Initial OpenGL values from specification.
glAlphaFunc(GL_ALWAYS, 0.0f); glAlphaFunc(GL_ALWAYS, 0.0f);
...@@ -5057,53 +5141,6 @@ void COpenGLCallBridge::setClientActiveTexture(GLenum texture) ...@@ -5057,53 +5141,6 @@ void COpenGLCallBridge::setClientActiveTexture(GLenum texture)
} }
} }
void COpenGLCallBridge::resetTexture(const ITexture* texture)
{
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
setActiveTexture(GL_TEXTURE0_ARB + i);
if (Texture[i] == texture)
{
glBindTexture(GL_TEXTURE_2D, 0);
if (TextureFixedPipeline[i])
glDisable(GL_TEXTURE_2D);
Texture[i] = 0;
}
}
}
void COpenGLCallBridge::setTexture(GLuint stage, bool fixedPipeline)
{
if (stage < MATERIAL_MAX_TEXTURES)
{
setActiveTexture(GL_TEXTURE0_ARB + stage);
if((fixedPipeline && TextureFixedPipeline[stage] != fixedPipeline) || Texture[stage] != Driver->CurrentTexture[stage])
{
if(Driver->CurrentTexture[stage])
{
if(fixedPipeline)
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, static_cast<const COpenGLTexture*>(Driver->CurrentTexture[stage])->getOpenGLTextureName());
}
else
{
glBindTexture(GL_TEXTURE_2D, 0);
if(TextureFixedPipeline[stage])
glDisable(GL_TEXTURE_2D);
}
TextureFixedPipeline[stage] = fixedPipeline;
Texture[stage] = Driver->CurrentTexture[stage];
}
}
}
void COpenGLCallBridge::setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight) void COpenGLCallBridge::setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight)
{ {
if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight) if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight)
......
...@@ -310,10 +310,6 @@ namespace video ...@@ -310,10 +310,6 @@ namespace video
//! Int interface for the above. //! Int interface for the above.
virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_; virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
//! sets the current Texture
//! Returns whether setting was a success or not.
bool setActiveTexture(u32 stage, const video::ITexture* texture);
//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. //! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled.
//! Returns whether disabling was successful or not. //! Returns whether disabling was successful or not.
bool disableTextures(u32 fromStage=0); bool disableTextures(u32 fromStage=0);
...@@ -481,71 +477,6 @@ namespace video ...@@ -481,71 +477,6 @@ namespace video
SMaterial Material, LastMaterial; SMaterial Material, LastMaterial;
class STextureStageCache
{
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
public:
STextureStageCache()
{
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
CurrentTexture[i] = 0;
}
}
~STextureStageCache()
{
clear();
}
void set(u32 stage, const ITexture* tex)
{
if (stage<MATERIAL_MAX_TEXTURES)
{
const ITexture* oldTexture=CurrentTexture[stage];
if (tex)
tex->grab();
CurrentTexture[stage]=tex;
if (oldTexture)
oldTexture->drop();
}
}
const ITexture* operator[](int stage) const
{
if ((u32)stage<MATERIAL_MAX_TEXTURES)
return CurrentTexture[stage];
else
return 0;
}
void remove(ITexture* tex)
{
for (s32 i = MATERIAL_MAX_TEXTURES-1; i>= 0; --i)
{
if (CurrentTexture[i] == tex)
{
tex->drop();
CurrentTexture[i] = 0;
}
}
}
void clear()
{
// Drop all the CurrentTexture handles
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
if (CurrentTexture[i])
{
CurrentTexture[i]->drop();
CurrentTexture[i] = 0;
}
}
}
};
STextureStageCache CurrentTexture;
struct SUserClipPlane struct SUserClipPlane
{ {
SUserClipPlane() : Enabled(false) {} SUserClipPlane() : Enabled(false) {}
...@@ -604,11 +535,30 @@ namespace video ...@@ -604,11 +535,30 @@ namespace video
E_DEVICE_TYPE DeviceType; E_DEVICE_TYPE DeviceType;
}; };
//! This bridge between Irlicht pseudo OpenGL calls //! This is a bridge between Irlicht pseudo OpenGL calls and real OpenGL calls.
//! and true OpenGL calls.
class COpenGLCallBridge class COpenGLCallBridge
{ {
class STextureCache
{
public:
STextureCache(COpenGLCallBridge* cacheHandler, u32 textureCount);
~STextureCache();
const COpenGLTexture* operator[](int index) const;
bool set(u32 index, const ITexture* texture);
void remove(ITexture* texture);
void clear();
private:
COpenGLCallBridge* CacheHandler;
const COpenGLTexture* Texture[MATERIAL_MAX_TEXTURES];
u32 TextureCount;
};
public: public:
COpenGLCallBridge(COpenGLDriver* driver); COpenGLCallBridge(COpenGLDriver* driver);
~COpenGLCallBridge(); ~COpenGLCallBridge();
...@@ -673,18 +623,18 @@ namespace video ...@@ -673,18 +623,18 @@ namespace video
// Texture calls. // Texture calls.
void resetTexture(const ITexture* texture);
void setActiveTexture(GLenum texture); void setActiveTexture(GLenum texture);
void setClientActiveTexture(GLenum texture); void setClientActiveTexture(GLenum texture);
void setTexture(GLuint stage, bool fixedPipeline);
// Viewport calls. // Viewport calls.
void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight); void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight);
// Texture cache.
STextureCache TextureCache;
private: private:
COpenGLDriver* Driver; COpenGLDriver* Driver;
...@@ -722,9 +672,6 @@ namespace video ...@@ -722,9 +672,6 @@ namespace video
GLenum ActiveTexture; GLenum ActiveTexture;
GLenum ClientActiveTexture; GLenum ClientActiveTexture;
const ITexture* Texture[MATERIAL_MAX_TEXTURES];
bool TextureFixedPipeline[MATERIAL_MAX_TEXTURES];
GLint ViewportX; GLint ViewportX;
GLint ViewportY; GLint ViewportY;
GLsizei ViewportWidth; GLsizei ViewportWidth;
......
...@@ -108,6 +108,9 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32 ...@@ -108,6 +108,9 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32
setDebugName("COpenGLTexture"); setDebugName("COpenGLTexture");
#endif #endif
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
const COpenGLTexture* prevTexture = bridgeCalls->TextureCache[0];
DriverType = EDT_OPENGL; DriverType = EDT_OPENGL;
if (ECF_UNKNOWN == format) if (ECF_UNKNOWN == format)
...@@ -137,8 +140,7 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32 ...@@ -137,8 +140,7 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32
glGenTextures(1, &TextureName); glGenTextures(1, &TextureName);
Driver->setActiveTexture(0, this); bridgeCalls->TextureCache.set(0, this);
Driver->getBridgeCalls()->setTexture(0, true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
...@@ -154,20 +156,19 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32 ...@@ -154,20 +156,19 @@ COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, OriginalSize.Width, OriginalSize.Height, 0, PixelFormat, PixelType, 0); glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, OriginalSize.Width, OriginalSize.Height, 0, PixelFormat, PixelType, 0);
Driver->setActiveTexture(0, 0); bridgeCalls->TextureCache.set(0, prevTexture);
Driver->getBridgeCalls()->setTexture(0, true);
} }
//! destructor //! destructor
COpenGLTexture::~COpenGLTexture() COpenGLTexture::~COpenGLTexture()
{ {
Driver->getBridgeCalls()->TextureCache.remove(this);
if (TextureName) if (TextureName)
glDeleteTextures(1, &TextureName); glDeleteTextures(1, &TextureName);
if (Image) if (Image)
Image->drop(); Image->drop();
Driver->getBridgeCalls()->resetTexture(this);
} }
...@@ -477,6 +478,9 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level) ...@@ -477,6 +478,9 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
return; return;
} }
COpenGLCallBridge* bridgeCalls = Driver->getBridgeCalls();
const COpenGLTexture* prevTexture = bridgeCalls->TextureCache[0];
// get correct opengl color data values // get correct opengl color data values
GLenum oldInternalFormat = InternalFormat; GLenum oldInternalFormat = InternalFormat;
GLint filtering; GLint filtering;
...@@ -485,8 +489,7 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level) ...@@ -485,8 +489,7 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
if (!newTexture) if (!newTexture)
InternalFormat=oldInternalFormat; InternalFormat=oldInternalFormat;
Driver->setActiveTexture(0, this); bridgeCalls->TextureCache.set(0, this);
Driver->getBridgeCalls()->setTexture(0, true);
if (Driver->testGLError()) if (Driver->testGLError())
os::Printer::log("Could not bind Texture", ELL_ERROR); os::Printer::log("Could not bind Texture", ELL_ERROR);
...@@ -599,6 +602,8 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level) ...@@ -599,6 +602,8 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
if (Driver->testGLError()) if (Driver->testGLError())
os::Printer::log("Could not glTexImage2D", ELL_ERROR); os::Printer::log("Could not glTexImage2D", ELL_ERROR);
bridgeCalls->TextureCache.set(0, prevTexture);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment