Commit e0952a9c authored by nadro's avatar nadro

- Partially improved active texture handling in OpenGL (cause some issues with...

- Partially improved active texture handling in OpenGL (cause some issues with 2D rendering visible in example no. 11).

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4408 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 06193571
......@@ -764,10 +764,6 @@ bool COpenGLDriver::genericDriverInit()
// create matrix for flipping textures
TextureFlipMatrix.buildTextureTransform(0.0f, core::vector2df(0,0), core::vector2df(0,1.0f), core::vector2df(1.0f,-1.0f));
// Cached initial values.
for(u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
CacheLODBias[i] = -1;
// We need to reset once more at the beginning of the first rendering.
// This fixes problems with intermediate changes to the material during texture load.
ResetRenderStates = true;
......@@ -2444,45 +2440,17 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
if (CurrentTexture[stage]==texture)
return true;
if (MultiTextureExtension)
setGlActiveTexture(GL_TEXTURE0_ARB + stage);
CurrentTexture.set(stage,texture);
if (!texture)
{
//if(IsTexture2DEnabled)
{
glDisable(GL_TEXTURE_2D);
IsTexture2DEnabled = false;
}
return true;
}
else
else if (texture->getDriverType() != EDT_OPENGL)
{
if (texture->getDriverType() != EDT_OPENGL)
{
//if(IsTexture2DEnabled)
{
glDisable(GL_TEXTURE_2D);
IsTexture2DEnabled = false;
}
CurrentTexture.set(stage, 0);
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
return false;
}
//if(!IsTexture2DEnabled)
{
glEnable(GL_TEXTURE_2D);
IsTexture2DEnabled = true;
}
glBindTexture(GL_TEXTURE_2D,
static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
}
return true;
}
......@@ -2543,12 +2511,8 @@ void COpenGLDriver::setMaterial(const SMaterial& material)
Material = material;
OverrideMaterial.apply(Material);
for (s32 i = MaxTextureUnits-1; i>= 0; --i)
{
for (u32 i = 0; i < MaxTextureUnits; ++i)
setActiveTexture(i, material.getTexture(i));
setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i),
Material.getTextureMatrix(i));
}
}
......@@ -2740,8 +2704,13 @@ GLint COpenGLDriver::getTextureWrapMode(const u8 clamp)
//! Can be called by an IMaterialRenderer to make its work easier.
void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderStates)
bool resetAllRenderStates, bool fixedPipeline)
{
// Fixed pipeline isn't important for shader based materials
if(fixedPipeline || resetAllRenderStates)
{
// material colors
if (resetAllRenderStates ||
lastmaterial.ColorMaterial != material.ColorMaterial)
{
......@@ -2839,25 +2808,115 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
}
// Texture filter
// Has to be checked always because it depends on the textures
// Filtering has to be set for each texture layer
for (u32 i=0; i<MaxTextureUnits; ++i)
// shademode
if (resetAllRenderStates || (lastmaterial.GouraudShading != material.GouraudShading))
{
if (material.GouraudShading)
glShadeModel(GL_SMOOTH);
else
glShadeModel(GL_FLAT);
}
// lighting
if (resetAllRenderStates || (lastmaterial.Lighting != material.Lighting))
{
if (material.Lighting)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
// fog
if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable)
{
if (material.FogEnable)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
}
// normalization
if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals)
{
if (material.NormalizeNormals)
glEnable(GL_NORMALIZE);
else
glDisable(GL_NORMALIZE);
}
}
// Set textures to TU/TIU and apply filters to them
for (s32 i = MaxTextureUnits-1; i>= 0; --i)
{
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(CurrentTexture[i]);
if(fixedPipeline)
{
if (i>0 && !MultiTextureExtension)
break;
if (!CurrentTexture[i])
{
if (MultiTextureExtension)
setGlActiveTexture(GL_TEXTURE0_ARB + i);
glDisable(GL_TEXTURE_2D);
continue;
}
else
{
if (MultiTextureExtension)
setGlActiveTexture(GL_TEXTURE0_ARB + i);
else if (i>0)
break;
const COpenGLTexture* tmpTexture = static_cast<const COpenGLTexture*>(CurrentTexture[i]);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName());
setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), material.getTextureMatrix(i));
}
}
else
{
if (CurrentTexture[i])
{
setGlActiveTexture(GL_TEXTURE0_ARB + i);
glBindTexture(GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName());
}
else
continue;
}
if(resetAllRenderStates)
tmpTexture->getStatesCache().IsCached = false;
#ifdef GL_EXT_texture_lod_bias
if (FeatureAvailable[IRR_EXT_texture_lod_bias] && (resetAllRenderStates || material.TextureLayer[i].LODBias != CacheLODBias[i]))
#ifdef GL_VERSION_2_1
if (Version>=210)
{
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].LODBias != tmpTexture->getStatesCache().LODBias)
{
if (material.TextureLayer[i].LODBias)
{
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, tmp);
}
else
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.f);
tmpTexture->getStatesCache().LODBias = material.TextureLayer[i].LODBias;
}
}
else if (FeatureAvailable[IRR_EXT_texture_lod_bias])
{
if (material.TextureLayer[i].LODBias)
{
const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp);
}
else
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
}
#elif defined(GL_EXT_texture_lod_bias)
if (FeatureAvailable[IRR_EXT_texture_lod_bias])
{
if (material.TextureLayer[i].LODBias)
{
......@@ -2866,10 +2925,9 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
}
else
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f);
CacheLODBias[i] = material.TextureLayer[i].LODBias;
}
#endif
if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
{
......@@ -2939,24 +2997,6 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud))
glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL);
// shademode
if (resetAllRenderStates || (lastmaterial.GouraudShading != material.GouraudShading))
{
if (material.GouraudShading)
glShadeModel(GL_SMOOTH);
else
glShadeModel(GL_FLAT);
}
// lighting
if (resetAllRenderStates || (lastmaterial.Lighting != material.Lighting))
{
if (material.Lighting)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
// zbuffer
if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer)
{
......@@ -3096,24 +3136,6 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
glDisable(GL_CULL_FACE);
}
// fog
if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable)
{
if (material.FogEnable)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
}
// normalization
if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals)
{
if (material.NormalizeNormals)
glEnable(GL_NORMALIZE);
else
glDisable(GL_NORMALIZE);
}
// Color Mask
if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask)
{
......@@ -3309,7 +3331,7 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater
}
// be sure to leave in texture stage 0
if (MultiTextureExtension)
if (fixedPipeline && MultiTextureExtension)
setGlActiveTexture(GL_TEXTURE0_ARB);
}
......@@ -4266,7 +4288,7 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
if ((RenderTargetTexture != texture) ||
(CurrentTarget==ERT_MULTI_RENDER_TEXTURES))
{
setActiveTexture(0, 0);
setGlActiveTexture(GL_TEXTURE0_ARB);
ResetRenderStates=true;
if (RenderTargetTexture!=0)
{
......
......@@ -275,7 +275,14 @@ namespace video
//! Can be called by an IMaterialRenderer to make its work easier.
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates);
bool resetAllRenderstates)
{
setBasicRenderStates(material, lastmaterial, resetAllRenderstates, true);
}
//! Can be called by an IMaterialRenderer to make its work easier.
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates, bool fixedPipeline);
//! Get a vertex shader constant index.
virtual s32 getVertexShaderConstantID(const c8* name);
......@@ -577,8 +584,6 @@ namespace video
GLenum CurrentMatrixMode;
GLenum CurrentActiveTexture;
s8 CacheLODBias[MATERIAL_MAX_TEXTURES];
//! All the lights that have been requested; a hardware limited
//! number of them will be used at once.
struct RequestedLight
......
......@@ -227,7 +227,7 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
if (CallBack)
CallBack->OnSetMaterial(material);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates, false);
}
......@@ -502,7 +502,7 @@ void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material,
bool resetAllRenderstates)
{
// forward
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates, false);
}
s32 COpenGLSLMaterialRenderer::getVertexShaderConstantID(const c8* name)
......
......@@ -317,6 +317,13 @@ void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
InternalFormat=oldInternalFormat;
Driver->setActiveTexture(0, this);
if (Driver->MultiTextureExtension)
Driver->setGlActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName);
if (Driver->testGLError())
os::Printer::log("Could not bind Texture", ELL_ERROR);
......@@ -652,6 +659,12 @@ void COpenGLTexture::unbindRTT()
{
Driver->setActiveTexture(0, this);
if (Driver->MultiTextureExtension)
Driver->setGlActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName);
// Copy Our ViewPort To The Texture
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height);
}
......@@ -701,6 +714,12 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
// generate color texture
glGenTextures(1, &TextureName);
Driver->setActiveTexture(0, this);
if (Driver->MultiTextureExtension)
Driver->setGlActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TextureName);
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_T, GL_CLAMP_TO_EDGE);
......
......@@ -56,7 +56,7 @@ public:
struct SStatesCache
{
SStatesCache() : WrapU(ETC_REPEAT), WrapV(ETC_REPEAT), BilinearFilter(true),
TrilinearFilter(false), AnisotropicFilter(0), MipMapStatus(true), IsCached(false)
TrilinearFilter(false), AnisotropicFilter(0), MipMapStatus(true), IsCached(false), LODBias(0)
{
}
......@@ -66,6 +66,7 @@ public:
bool TrilinearFilter;
u8 AnisotropicFilter;
bool MipMapStatus;
s8 LODBias;
bool IsCached;
};
......
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