mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-12-17 06:38:43 +00:00
1010 lines
26 KiB
C++
1010 lines
26 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include "stdopengl.h"
|
|
|
|
#include "driver_opengl.h"
|
|
|
|
// ***************************************************************************
|
|
// define it For Debug purpose only. Normal use is to hide this line
|
|
//#define NL3D_GLSTATE_DISABLE_CACHE
|
|
|
|
namespace NL3D
|
|
{
|
|
|
|
// ***************************************************************************
|
|
CDriverGLStates::CDriverGLStates()
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_CDriverGLStates)
|
|
_TextureCubeMapSupported= false;
|
|
_CurrARBVertexBuffer = 0;
|
|
_DepthRangeNear = 0.f;
|
|
_DepthRangeFar = 1.f;
|
|
_ZBias = 0.f;
|
|
_MaxDriverLight= 0;
|
|
_CullMode = CCW;
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::init(bool supportTextureCubeMap, bool supportTextureRectangle, uint maxLight)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_init)
|
|
_TextureCubeMapSupported= supportTextureCubeMap;
|
|
_TextureRectangleSupported= supportTextureRectangle;
|
|
_MaxDriverLight= maxLight;
|
|
_MaxDriverLight= std::min(_MaxDriverLight, uint(MaxLight));
|
|
|
|
// By default all arrays are disabled.
|
|
_VertexArrayEnabled= false;
|
|
_NormalArrayEnabled= false;
|
|
_WeightArrayEnabled= false;
|
|
_ColorArrayEnabled= false;
|
|
_SecondaryColorArrayEnabled= false;
|
|
uint i;
|
|
for(i=0; i<sizeof(_TexCoordArrayEnabled)/sizeof(_TexCoordArrayEnabled[0]); i++)
|
|
{
|
|
_TexCoordArrayEnabled[i]= false;
|
|
}
|
|
for(i=0; i<CVertexBuffer::NumValue; i++)
|
|
{
|
|
_VertexAttribArrayEnabled[i]= false;
|
|
}
|
|
_DepthRangeNear = 0.f;
|
|
_DepthRangeFar = 1.f;
|
|
_ZBias = 0.f;
|
|
// by default all lights are disabled (not reseted in forceDefaults)
|
|
for(i=0; i<MaxLight; i++)
|
|
{
|
|
_CurLight[i]= false;
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::forceDefaults(uint nbStages)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_forceDefaults)
|
|
// Enable / disable.
|
|
_CurFog= false;
|
|
_CurBlend= false;
|
|
_CurCullFace= true;
|
|
_CurAlphaTest= false;
|
|
_CurLighting= false;
|
|
_CurZWrite= true;
|
|
_CurStencilTest=false;
|
|
// setup GLStates.
|
|
glDisable(GL_FOG);
|
|
glDisable(GL_BLEND);
|
|
glEnable(GL_CULL_FACE);
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glDepthMask(GL_TRUE);
|
|
|
|
|
|
|
|
// Func.
|
|
_CurBlendSrc= GL_SRC_ALPHA;
|
|
_CurBlendDst= GL_ONE_MINUS_SRC_ALPHA;
|
|
_CurDepthFunc= GL_LEQUAL;
|
|
_CurStencilFunc = GL_ALWAYS;
|
|
_CurStencilRef = 0;
|
|
_CurStencilMask = std::numeric_limits<GLuint>::max();
|
|
_CurStencilOpFail = GL_KEEP;
|
|
_CurStencilOpZFail = GL_KEEP;
|
|
_CurStencilOpZPass = GL_KEEP;
|
|
_CurStencilWriteMask = std::numeric_limits<GLuint>::max();
|
|
_CurAlphaTestThreshold= 0.5f;
|
|
// setup GLStates.
|
|
glBlendFunc(_CurBlendSrc, _CurBlendDst);
|
|
glDepthFunc(_CurDepthFunc);
|
|
glStencilFunc(_CurStencilFunc, _CurStencilRef, _CurStencilMask);
|
|
glStencilOp(_CurStencilOpFail, _CurStencilOpZFail, _CurStencilOpZPass);
|
|
glStencilMask(_CurStencilWriteMask);
|
|
glAlphaFunc(GL_GREATER, _CurAlphaTestThreshold);
|
|
|
|
|
|
|
|
// Materials.
|
|
uint32 packedOne= (CRGBA(255,255,255,255)).getPacked();
|
|
uint32 packedZero= (CRGBA(0,0,0,255)).getPacked();
|
|
_CurEmissive= packedZero;
|
|
_CurAmbient= packedOne;
|
|
_CurDiffuse= packedOne;
|
|
_CurSpecular= packedZero;
|
|
_CurShininess= 1;
|
|
|
|
// Lighted vertex color
|
|
_VertexColorLighted=false;
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
|
|
// setup GLStates.
|
|
static const GLfloat one[4]= {1,1,1,1};
|
|
static const GLfloat zero[4]= {0,0,0,1};
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, zero);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, one);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, one);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
|
|
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, _CurShininess);
|
|
|
|
|
|
|
|
|
|
// TexModes
|
|
uint stage;
|
|
for(stage=0;stage<nbStages; stage++)
|
|
{
|
|
// disable texturing.
|
|
nglActiveTextureARB(GL_TEXTURE0_ARB+stage);
|
|
glDisable(GL_TEXTURE_2D);
|
|
if(_TextureCubeMapSupported)
|
|
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
if(_TextureRectangleSupported)
|
|
glDisable(GL_TEXTURE_RECTANGLE_NV);
|
|
_TextureMode[stage]= TextureDisabled;
|
|
|
|
// Tex gen init
|
|
_TexGenMode[stage] = 0;
|
|
glDisable( GL_TEXTURE_GEN_S );
|
|
glDisable( GL_TEXTURE_GEN_T );
|
|
glDisable( GL_TEXTURE_GEN_R );
|
|
glDisable( GL_TEXTURE_GEN_Q );
|
|
}
|
|
|
|
// ActiveTexture current texture to 0.
|
|
nglActiveTextureARB(GL_TEXTURE0_ARB);
|
|
_CurrentActiveTextureARB= 0;
|
|
nglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
_CurrentClientActiveTextureARB= 0;
|
|
|
|
// Depth range
|
|
_DepthRangeNear = 0.f;
|
|
_DepthRangeFar = 1.f;
|
|
_ZBias = 0.f;
|
|
glDepthRange (0, 1);
|
|
|
|
// Cull order
|
|
_CullMode = CCW;
|
|
glCullFace(GL_BACK);
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableBlend(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableBlend)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurBlend )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurBlend= enabled;
|
|
// Setup GLState.
|
|
if(_CurBlend)
|
|
glEnable(GL_BLEND);
|
|
else
|
|
glDisable(GL_BLEND);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableCullFace(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableCullFace)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurCullFace )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurCullFace= enabled;
|
|
// Setup GLState.
|
|
if(_CurCullFace)
|
|
glEnable(GL_CULL_FACE);
|
|
else
|
|
glDisable(GL_CULL_FACE);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableAlphaTest(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableAlphaTest)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurAlphaTest )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurAlphaTest= enabled;
|
|
|
|
// Setup GLState.
|
|
if(_CurAlphaTest)
|
|
{
|
|
glEnable(GL_ALPHA_TEST);
|
|
}
|
|
else
|
|
{
|
|
glDisable(GL_ALPHA_TEST);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableLighting(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableLighting)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurLighting )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurLighting= enabled;
|
|
// Setup GLState.
|
|
if(_CurLighting)
|
|
glEnable(GL_LIGHTING);
|
|
else
|
|
{
|
|
glDisable(GL_LIGHTING);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableLight(uint num, uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableLight)
|
|
if(num>=_MaxDriverLight)
|
|
return;
|
|
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurLight[num] )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurLight[num]= enabled;
|
|
// Setup GLState.
|
|
if(_CurLight[num])
|
|
glEnable ((GLenum)(GL_LIGHT0+num));
|
|
else
|
|
glDisable ((GLenum)(GL_LIGHT0+num));
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
bool CDriverGLStates::isLightEnabled(uint num) const
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_isLightEnabled)
|
|
if(num>=_MaxDriverLight)
|
|
return false;
|
|
else
|
|
return _CurLight[num];
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableZWrite(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableZWrite)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurZWrite )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurZWrite= enabled;
|
|
// Setup GLState.
|
|
if(_CurZWrite)
|
|
glDepthMask(GL_TRUE);
|
|
else
|
|
glDepthMask(GL_FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableStencilTest(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableStencilTest)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurStencilTest )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurStencilTest= enabled;
|
|
// Setup GLState.
|
|
if(_CurStencilTest)
|
|
glEnable(GL_STENCIL_TEST);
|
|
else
|
|
glDisable(GL_STENCIL_TEST);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::blendFunc(GLenum src, GLenum dst)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_blendFunc)
|
|
// If different from current setup, update.
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( src!= _CurBlendSrc || dst!=_CurBlendDst )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurBlendSrc= src;
|
|
_CurBlendDst= dst;
|
|
// Setup GLState.
|
|
glBlendFunc(_CurBlendSrc, _CurBlendDst);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::depthFunc(GLenum zcomp)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_depthFunc)
|
|
// If different from current setup, update.
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( zcomp != _CurDepthFunc )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurDepthFunc= zcomp;
|
|
// Setup GLState.
|
|
glDepthFunc(_CurDepthFunc);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::alphaFunc(float threshold)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_alphaFunc)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if(threshold != _CurAlphaTestThreshold)
|
|
#endif
|
|
{
|
|
// new state
|
|
_CurAlphaTestThreshold= threshold;
|
|
// setup function.
|
|
glAlphaFunc(GL_GREATER, _CurAlphaTestThreshold);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::stencilFunc(GLenum func, GLint ref, GLuint mask)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_stencilFunc)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if((func!=_CurStencilFunc) || (ref!=_CurStencilRef) || (mask!=_CurStencilMask))
|
|
#endif
|
|
{
|
|
// new state
|
|
_CurStencilFunc = func;
|
|
_CurStencilRef = ref;
|
|
_CurStencilMask = mask;
|
|
|
|
// setup function.
|
|
glStencilFunc(_CurStencilFunc, _CurStencilRef, _CurStencilMask);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_stencilOp)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if((fail!=_CurStencilOpFail) || (zfail!=_CurStencilOpZFail) || (zpass!=_CurStencilOpZPass))
|
|
#endif
|
|
{
|
|
// new state
|
|
_CurStencilOpFail = fail;
|
|
_CurStencilOpZFail = zfail;
|
|
_CurStencilOpZPass = zpass;
|
|
|
|
// setup function.
|
|
glStencilOp(_CurStencilOpFail, _CurStencilOpZFail, _CurStencilOpZPass);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::stencilMask(GLuint mask)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_stencilMask)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if(mask!=_CurStencilWriteMask)
|
|
#endif
|
|
{
|
|
// new state
|
|
_CurStencilWriteMask = mask;
|
|
|
|
// setup function.
|
|
glStencilMask(_CurStencilWriteMask);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setEmissive(uint32 packedColor, const GLfloat color[4])
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setEmissive)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( packedColor!=_CurEmissive )
|
|
#endif
|
|
{
|
|
_CurEmissive= packedColor;
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setAmbient(uint32 packedColor, const GLfloat color[4])
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setAmbient)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( packedColor!=_CurAmbient )
|
|
#endif
|
|
{
|
|
_CurAmbient= packedColor;
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setDiffuse(uint32 packedColor, const GLfloat color[4])
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setDiffuse)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( packedColor!=_CurDiffuse )
|
|
#endif
|
|
{
|
|
_CurDiffuse= packedColor;
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setSpecular(uint32 packedColor, const GLfloat color[4])
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setSpecular)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( packedColor!=_CurSpecular )
|
|
#endif
|
|
{
|
|
_CurSpecular= packedColor;
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setShininess(float shin)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setShininess)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( shin != _CurShininess )
|
|
#endif
|
|
{
|
|
_CurShininess= shin;
|
|
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin);
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
static void convColor(CRGBA col, GLfloat glcol[4])
|
|
{
|
|
H_AUTO_OGL(convColor)
|
|
static const float OO255= 1.0f/255;
|
|
glcol[0]= col.R*OO255;
|
|
glcol[1]= col.G*OO255;
|
|
glcol[2]= col.B*OO255;
|
|
glcol[3]= col.A*OO255;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setVertexColorLighted(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setVertexColorLighted)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enable != _VertexColorLighted)
|
|
#endif
|
|
{
|
|
_VertexColorLighted= enable;
|
|
|
|
if (_VertexColorLighted)
|
|
{
|
|
glEnable (GL_COLOR_MATERIAL);
|
|
glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE);
|
|
}
|
|
else
|
|
{
|
|
glDisable (GL_COLOR_MATERIAL);
|
|
// Since we leave glColorMaterial mode, GL diffuse is now scracth. reset him to current value.
|
|
CRGBA diffCol;
|
|
diffCol.R= (uint8)((_CurDiffuse >> 24) & 255);
|
|
diffCol.G= (uint8)((_CurDiffuse >> 16) & 255);
|
|
diffCol.B= (uint8)((_CurDiffuse >> 8) & 255);
|
|
diffCol.A= (uint8)((_CurDiffuse ) & 255);
|
|
GLfloat glColor[4];
|
|
convColor(diffCol, glColor);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, glColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::updateDepthRange()
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_updateDepthRange)
|
|
float delta = _ZBias * (_DepthRangeFar - _DepthRangeNear);
|
|
glDepthRange(delta + _DepthRangeNear, delta + _DepthRangeFar);
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setZBias(float zbias)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setZBias)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if (zbias != _ZBias)
|
|
#endif
|
|
{
|
|
_ZBias = zbias;
|
|
updateDepthRange();
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setDepthRange(float znear, float zfar)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setDepthRange)
|
|
nlassert(znear != zfar);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if (znear != _DepthRangeNear || zfar != _DepthRangeFar)
|
|
#endif
|
|
{
|
|
_DepthRangeNear = znear;
|
|
_DepthRangeFar = zfar;
|
|
updateDepthRange();
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setTexGenMode (uint stage, GLint mode)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setTexGenMode )
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if (mode != _TexGenMode[stage])
|
|
#endif
|
|
{
|
|
_TexGenMode[stage] = mode;
|
|
|
|
if(mode==0)
|
|
{
|
|
glDisable( GL_TEXTURE_GEN_S );
|
|
glDisable( GL_TEXTURE_GEN_T );
|
|
glDisable( GL_TEXTURE_GEN_R );
|
|
glDisable( GL_TEXTURE_GEN_Q );
|
|
}
|
|
else
|
|
{
|
|
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, mode);
|
|
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, mode);
|
|
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, mode);
|
|
/* Object or Eye Space ? => enable W generation. VERY IMPORTANT because
|
|
was a bug with VegetableRender and ShadowRender:
|
|
- Vegetable use the TexCoord1.w in his VertexProgram
|
|
- Shadow Render don't use any TexCoord in VB (since projected)
|
|
=> TexCoord1.w dirty!!
|
|
*/
|
|
if(mode==GL_OBJECT_LINEAR || mode==GL_EYE_LINEAR)
|
|
{
|
|
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, mode);
|
|
glEnable( GL_TEXTURE_GEN_Q );
|
|
}
|
|
else
|
|
{
|
|
glDisable( GL_TEXTURE_GEN_Q );
|
|
}
|
|
// Enable All.
|
|
glEnable( GL_TEXTURE_GEN_S );
|
|
glEnable( GL_TEXTURE_GEN_T );
|
|
glEnable( GL_TEXTURE_GEN_R );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::resetTextureMode()
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_resetTextureMode)
|
|
glDisable(GL_TEXTURE_2D);
|
|
if (_TextureCubeMapSupported)
|
|
{
|
|
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
}
|
|
if (_TextureRectangleSupported)
|
|
{
|
|
glDisable(GL_TEXTURE_RECTANGLE_NV);
|
|
}
|
|
_TextureMode[_CurrentActiveTextureARB]= TextureDisabled;
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setTextureMode(TTextureMode texMode)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setTextureMode)
|
|
TTextureMode oldTexMode = _TextureMode[_CurrentActiveTextureARB];
|
|
if(oldTexMode != texMode)
|
|
{
|
|
// Disable first old mode.
|
|
if(oldTexMode == Texture2D)
|
|
glDisable(GL_TEXTURE_2D);
|
|
else if(oldTexMode == TextureRect)
|
|
{
|
|
if(_TextureRectangleSupported)
|
|
glDisable(GL_TEXTURE_RECTANGLE_NV);
|
|
else
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
else if(oldTexMode == TextureCubeMap)
|
|
{
|
|
if(_TextureCubeMapSupported)
|
|
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
else
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
// Enable new mode.
|
|
if(texMode == Texture2D)
|
|
glEnable(GL_TEXTURE_2D);
|
|
else if(texMode == TextureRect)
|
|
{
|
|
if(_TextureRectangleSupported)
|
|
glEnable(GL_TEXTURE_RECTANGLE_NV);
|
|
else
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
else if(texMode == TextureCubeMap)
|
|
{
|
|
if(_TextureCubeMapSupported)
|
|
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
else
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
// new mode.
|
|
_TextureMode[_CurrentActiveTextureARB]= texMode;
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::activeTextureARB(uint stage)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_activeTextureARB)
|
|
if( _CurrentActiveTextureARB != stage )
|
|
{
|
|
nglActiveTextureARB(GL_TEXTURE0_ARB+stage);
|
|
|
|
|
|
_CurrentActiveTextureARB= stage;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::forceActiveTextureARB(uint stage)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_forceActiveTextureARB)
|
|
nglActiveTextureARB(GL_TEXTURE0_ARB+stage);
|
|
|
|
_CurrentActiveTextureARB= stage;
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableVertexArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableVertexArray)
|
|
if(_VertexArrayEnabled != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
else
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
_VertexArrayEnabled= enable;
|
|
}
|
|
}
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableNormalArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableNormalArray)
|
|
if(_NormalArrayEnabled != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
else
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
_NormalArrayEnabled= enable;
|
|
|
|
|
|
}
|
|
}
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableWeightArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableWeightArray)
|
|
if(_WeightArrayEnabled != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_VERTEX_WEIGHTING_EXT);
|
|
else
|
|
glDisableClientState(GL_VERTEX_WEIGHTING_EXT);
|
|
_WeightArrayEnabled= enable;
|
|
|
|
|
|
}
|
|
}
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableColorArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableColorArray)
|
|
if(_ColorArrayEnabled != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
else
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
_ColorArrayEnabled= enable;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableSecondaryColorArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableSecondaryColorArray)
|
|
if(_SecondaryColorArrayEnabled != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
|
else
|
|
glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
|
|
|
|
|
|
_SecondaryColorArrayEnabled= enable;
|
|
// If disable
|
|
if(!enable)
|
|
{
|
|
// GeForceFx Bug: Must reset Secondary color to 0 (if comes from a VP), else bugs
|
|
nglSecondaryColor3ubEXT(0,0,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::clientActiveTextureARB(uint stage)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_clientActiveTextureARB)
|
|
if( _CurrentClientActiveTextureARB != stage )
|
|
{
|
|
nglClientActiveTextureARB(GL_TEXTURE0_ARB+stage);
|
|
_CurrentClientActiveTextureARB= stage;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableTexCoordArray(bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableTexCoordArray)
|
|
if(_TexCoordArrayEnabled[_CurrentClientActiveTextureARB] != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
else
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
_TexCoordArrayEnabled[_CurrentClientActiveTextureARB]= enable;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableVertexAttribArray(uint glIndex, bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableVertexAttribArray)
|
|
if(_VertexAttribArrayEnabled[glIndex] != enable)
|
|
{
|
|
if(enable)
|
|
glEnableClientState(glIndex+GL_VERTEX_ATTRIB_ARRAY0_NV);
|
|
else
|
|
glDisableClientState(glIndex+GL_VERTEX_ATTRIB_ARRAY0_NV);
|
|
|
|
|
|
_VertexAttribArrayEnabled[glIndex]= enable;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableVertexAttribArrayARB(uint glIndex,bool enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableVertexAttribArrayARB)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if(_VertexAttribArrayEnabled[glIndex] != enable)
|
|
#endif
|
|
{
|
|
if(enable)
|
|
nglEnableVertexAttribArrayARB(glIndex);
|
|
else
|
|
nglDisableVertexAttribArrayARB(glIndex);
|
|
|
|
_VertexAttribArrayEnabled[glIndex]= enable;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableVertexAttribArrayForEXTVertexShader(uint glIndex, bool enable, uint *variants)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableVertexAttribArrayForEXTVertexShader)
|
|
if(_VertexAttribArrayEnabled[glIndex] != enable)
|
|
{
|
|
switch(glIndex)
|
|
{
|
|
case 0: // position
|
|
enableVertexArray(enable);
|
|
break;
|
|
case 1: // skin weight
|
|
if(enable)
|
|
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSSkinWeightVariant]);
|
|
else
|
|
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSSkinWeightVariant]);
|
|
break;
|
|
case 2: // normal
|
|
enableNormalArray(enable);
|
|
break;
|
|
case 3: // color
|
|
enableColorArray(enable);
|
|
break;
|
|
case 4: // secondary color
|
|
if(enable)
|
|
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSSecondaryColorVariant]);
|
|
else
|
|
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSSecondaryColorVariant]);
|
|
break;
|
|
case 5: // fog coordinate
|
|
if(enable)
|
|
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSFogCoordsVariant]);
|
|
else
|
|
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSFogCoordsVariant]);
|
|
break;
|
|
case 6: // palette skin
|
|
if(enable)
|
|
nglEnableVariantClientStateEXT(variants[CDriverGL::EVSPaletteSkinVariant]);
|
|
else
|
|
nglDisableVariantClientStateEXT(variants[CDriverGL::EVSPaletteSkinVariant]);
|
|
break;
|
|
case 7: // empty
|
|
nlstop;
|
|
break;
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
clientActiveTextureARB(glIndex - 8);
|
|
enableTexCoordArray(enable);
|
|
break;
|
|
default:
|
|
nlstop; // invalid value
|
|
break;
|
|
}
|
|
_VertexAttribArrayEnabled[glIndex]= enable;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::enableFog(uint enable)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_enableFog)
|
|
// If different from current setup, update.
|
|
bool enabled= (enable!=0);
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if( enabled != _CurFog )
|
|
#endif
|
|
{
|
|
// new state.
|
|
_CurFog= enabled;
|
|
// Setup GLState.
|
|
if(_CurFog)
|
|
glEnable(GL_FOG);
|
|
else
|
|
glDisable(GL_FOG);
|
|
|
|
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::forceBindARBVertexBuffer(uint objectID)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_forceBindARBVertexBuffer)
|
|
nglBindBufferARB(GL_ARRAY_BUFFER_ARB, objectID);
|
|
_CurrARBVertexBuffer = objectID;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::bindARBVertexBuffer(uint objectID)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_bindARBVertexBuffer)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if (objectID != _CurrARBVertexBuffer)
|
|
#endif
|
|
{
|
|
forceBindARBVertexBuffer(objectID);
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CDriverGLStates::setCullMode(TCullMode cullMode)
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_setCullMode)
|
|
#ifndef NL3D_GLSTATE_DISABLE_CACHE
|
|
if (cullMode != _CullMode)
|
|
#endif
|
|
{
|
|
glCullFace(cullMode == CCW ? GL_BACK : GL_FRONT);
|
|
_CullMode = cullMode;
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
CDriverGLStates::TCullMode CDriverGLStates::getCullMode() const
|
|
{
|
|
H_AUTO_OGL(CDriverGLStates_CDriverGLStates)
|
|
return _CullMode;
|
|
}
|
|
|
|
|
|
|
|
} // NL3D
|