// NeL - MMORPG Framework // 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 . #ifndef NL_DRIVER_OPENGL_STATES_H #define NL_DRIVER_OPENGL_STATES_H #include "nel/misc/types_nl.h" #include "nel/3d/vertex_buffer.h" #ifdef NL_MAC_NATIVE # define GL_GLEXT_LEGACY # include #else # include #endif namespace NL3D { // *************************************************************************** /** * Class for optimizing calls to openGL states, by caching old ones. * All following call with OpenGL must be done with only one instance of this class: - glEnable() glDisable() with: - GL_BLEND - GL_CULL_FACE - GL_ALPHA_TEST - GL_LIGHTING - GL_LIGHT0 + i ..... - GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP_ARB. - GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_R - GL_COLOR_MATERIAL - GL_FOG - glActiveTextureARB() - glClientActiveTextureARB() - glEnableClientState() glDisableClientState() with: - GL_VERTEX_ARRAY - GL_NORMAL_ARRAY - GL_VERTEX_WEIGHTING_EXT - GL_COLOR_ARRAY - GL_SECONDARY_COLOR_ARRAY_EXT - GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ATTRIB_ARRAY0_NV + i. - glDepthMask() - glAlphaFunc() - glBlendFunc() - glDepthFunc() - glMaterialf() and glMaterialfv() for: - GL_EMISSION - GL_AMBIENT - GL_DIFFUSE - GL_SPECULAR - GL_SHININESS - glDepthRange() - glColorMaterial() - glTexGeni() * \author Lionel Berenguier * \author Nevrax France * \date 2001 */ class CDriverGLStates { public: /// Constructor. no-op. CDriverGLStates(); // init. Do it just after setDisplay() void init(bool supportTextureCubeMap, bool supportTextureRectangle, uint maxLight); /// Reset all OpenGL states of interest to default, and update caching. This don't apply to light. void forceDefaults(uint nbTextureStages); /// \name enable if !0 // @{ void enableBlend(uint enable); void enableFog(uint enable); void enableCullFace(uint enable); /// enable and set good AlphaFunc. void enableAlphaTest(uint enable); void enableZWrite(uint enable); // overall lighting enabled void enableLighting(uint enable); bool isLightingEnabled() const { return _CurLighting; } /// enable/disable specific light. num must be < "maxLight" param set in init() void enableLight(uint num, uint enable); bool isLightEnabled(uint num) const; /// enable/disable stencil test void enableStencilTest(bool enable); bool isStencilTestEnabled() const { return _CurStencilTest; } // @} /// glBlendFunc. void blendFunc(GLenum src, GLenum dst); /// glDepthFunc. void depthFunc(GLenum zcomp); /// glAlphaFunc void alphaFunc(float threshold); /// glStencilFunc void stencilFunc(GLenum stencilFunc, GLint ref, GLuint mask); /// glStencilOp void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); /// glStencilMask void stencilMask(uint mask); /// \name Material setting. /// Each f() get an uint32 for fast comparison, and OpenGL colors. // @{ void setEmissive(uint32 packedColor, const GLfloat color[4]); void setAmbient(uint32 packedColor, const GLfloat color[4]); void setDiffuse(uint32 packedColor, const GLfloat color[4]); void setSpecular(uint32 packedColor, const GLfloat color[4]); void setShininess(float shin); void setVertexColorLighted(bool enable); void setDepthRange (float znear, float zfar); void getDepthRange(float &znear, float &zfar) const { znear = _DepthRangeNear; zfar = _DepthRangeFar; } /** Set z-bias * NB : this is done in window coordinate, not in world coordinate as with CMaterial */ void setZBias(float zbias); // NB: set 0 to reset TexGen. void setTexGenMode (uint stage, GLint mode); // @} /// \name Texture Mode setting. // @{ enum TTextureMode {TextureDisabled, Texture2D, TextureRect, TextureCubeMap, TextureModeCount}; /// same as glActiveTextureARB(). useful for setTextureMode. void activeTextureARB(uint stage); /// same as active texture arb, but with no cache check void forceActiveTextureARB(uint stage); /// get active texture uint getActiveTextureARB() const { return _CurrentActiveTextureARB; } /** change if needed the texture mode of the current active Texture ARB. * NB: if CubeMap extension not supported, TextureCubeMap <=> TextureDisabled. */ void setTextureMode(TTextureMode texMode); TTextureMode getTextureMode() const { return _TextureMode[_CurrentActiveTextureARB]; } // reset texture mode to the default (disabled) for the current stage. It forces the state (useful after texture shaders) void resetTextureMode(); // @} /// \name Vertex Array enabling. /// equivalent to glEnableClientState() / glDisableClientState(). NB: Not modified by forceDefaults() // @{ void enableVertexArray(bool enable); void enableNormalArray(bool enable); void enableWeightArray(bool enable); void enableColorArray(bool enable); void enableSecondaryColorArray(bool enable); /// same as glClientActiveTextureARB(). useful for enableTexCoordArray. void clientActiveTextureARB(uint stage); /// NB: caller must call correct clientActiveTextureARB() before. void enableTexCoordArray(bool enable); /** For vertexProgram. do not check if supported or not. */ void enableVertexAttribArray(uint glIndex, bool enable); /** Same as enableVertexAttribArray, but for EXTVertexShader (need variant ID) * \param firstVariantSymbol the first variant symbol */ void enableVertexAttribArrayForEXTVertexShader(uint glIndex, bool enable, uint *variants); // special version for ARB_vertex_program used with ARB_vertex_buffer or ATI_vertex_attrib_array_object void enableVertexAttribArrayARB(uint glIndex, bool enable); // @} // ARB_vertex_buffer_object buffer binding void bindARBVertexBuffer(uint objectID); void forceBindARBVertexBuffer(uint objectID); uint getCurrBoundARBVertexBuffer() const { return _CurrARBVertexBuffer; } enum TCullMode { CCW = 0, CW }; void setCullMode(TCullMode cullMode); TCullMode getCullMode() const; private: bool _CurBlend; bool _CurFog; bool _CurCullFace; bool _CurAlphaTest; bool _CurLighting; bool _CurZWrite; bool _CurStencilTest; GLenum _CurBlendSrc; GLenum _CurBlendDst; GLenum _CurDepthFunc; GLenum _CurStencilFunc; GLint _CurStencilRef; GLuint _CurStencilMask; GLenum _CurStencilOpFail; GLenum _CurStencilOpZFail; GLenum _CurStencilOpZPass; GLuint _CurStencilWriteMask; float _CurAlphaTestThreshold; uint32 _CurEmissive; uint32 _CurAmbient; uint32 _CurDiffuse; uint32 _CurSpecular; float _CurShininess; bool _VertexColorLighted; bool _TextureCubeMapSupported; bool _TextureRectangleSupported; uint _CurrentActiveTextureARB; TTextureMode _TextureMode[8]; bool _VertexArrayEnabled; bool _NormalArrayEnabled; bool _WeightArrayEnabled; bool _ColorArrayEnabled; bool _SecondaryColorArrayEnabled; uint _CurrentClientActiveTextureARB; bool _TexCoordArrayEnabled[8]; bool _VertexAttribArrayEnabled[CVertexBuffer::NumValue]; GLint _TexGenMode[8]; uint _CurrARBVertexBuffer; float _DepthRangeNear; float _DepthRangeFar; float _ZBias; // NB : zbias is in window coordinates TCullMode _CullMode; private: void updateDepthRange(); // Mirror of glEnable() and GL_LIGHT0+i enum {MaxLight=8}; uint _MaxDriverLight; bool _CurLight[MaxLight]; }; } // NL3D #endif // NL_DRIVER_OPENGL_STATES_H /* End of driver_opengl_states.h */