Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGLRenderSystem.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://ogre.sourceforge.net/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.s
00023 -----------------------------------------------------------------------------
00024 */
00025 
00026 
00027 #include "OgreGLRenderSystem.h"
00028 #include "OgreRenderSystem.h"
00029 #include "OgreLogManager.h"
00030 #include "OgreLight.h"
00031 #include "OgreCamera.h"
00032 #include "OgreGLTextureManager.h"
00033 #include "OgreGLHardwareVertexBuffer.h"
00034 #include "OgreGLHardwareIndexBuffer.h"
00035 #include "OgreGLDefaultHardwareBufferManager.h"
00036 #include "OgreGLUtil.h"
00037 #include "OgreGLGpuProgram.h"
00038 #include "OgreGLGpuNvparseProgram.h"
00039 #include "ATI_FS_GLGpuProgram.h"
00040 #include "OgreGLGpuProgramManager.h"
00041 #include "OgreException.h"
00042 #include "OgreGLATIFSInit.h"
00043 #include "OgreGLHardwareOcclusionQuery.h"
00044 
00045 
00046 #ifdef HAVE_CONFIG_H
00047 #   include "config.h"
00048 #endif
00049 
00050 // Convenience macro from ARB_vertex_buffer_object spec
00051 #define VBO_BUFFER_OFFSET(i) ((char *)NULL + (i))
00052 
00053 // Pointers to extension functions
00054 GL_ActiveTextureARB_Func glActiveTextureARB_ptr;
00055 GL_ClientActiveTextureARB_Func glClientActiveTextureARB_ptr;
00056 GL_SecondaryColorPointerEXT_Func glSecondaryColorPointerEXT_ptr;
00057 GL_GenBuffersARB_Func glGenBuffersARB_ptr;
00058 GL_BindBufferARB_Func glBindBufferARB_ptr;
00059 GL_DeleteBuffersARB_Func glDeleteBuffersARB_ptr;
00060 GL_MapBufferARB_Func glMapBufferARB_ptr;
00061 GL_UnmapBufferARB_Func glUnmapBufferARB_ptr;
00062 GL_BufferDataARB_Func glBufferDataARB_ptr;
00063 GL_BufferSubDataARB_Func glBufferSubDataARB_ptr;
00064 GL_GetBufferSubDataARB_Func glGetBufferSubDataARB_ptr;
00065 GL_GenProgramsARB_Func glGenProgramsARB_ptr;
00066 GL_DeleteProgramsARB_Func glDeleteProgramsARB_ptr;
00067 GL_BindProgramARB_Func glBindProgramARB_ptr;
00068 GL_ProgramStringARB_Func glProgramStringARB_ptr;
00069 GL_ProgramLocalParameter4fvARB_Func glProgramLocalParameter4fvARB_ptr;
00070 GL_ProgramParameter4fvNV_Func glProgramParameter4fvNV_ptr;
00071 GL_VertexAttribPointerARB_Func glVertexAttribPointerARB_ptr;
00072 GL_EnableVertexAttribArrayARB_Func glEnableVertexAttribArrayARB_ptr;
00073 GL_DisableVertexAttribArrayARB_Func glDisableVertexAttribArrayARB_ptr;
00074 GL_CombinerStageParameterfvNV_Func glCombinerStageParameterfvNV_ptr;
00075 GL_CombinerParameterfvNV_Func glCombinerParameterfvNV_ptr;
00076 GL_CombinerParameteriNV_Func glCombinerParameteriNV_ptr;
00077 GL_GetProgramivARB_Func glGetProgramivARB_ptr;
00078 GL_LoadProgramNV_Func glLoadProgramNV_ptr;
00079 GL_CombinerInputNV_Func glCombinerInputNV_ptr;
00080 GL_CombinerOutputNV_Func glCombinerOutputNV_ptr;
00081 GL_FinalCombinerInputNV_Func glFinalCombinerInputNV_ptr;
00082 GL_TrackMatrixNV_Func glTrackMatrixNV_ptr;
00083 PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB_ptr;
00084 GL_ActiveStencilFaceEXT_Func glActiveStencilFaceEXT_ptr;
00085 GL_GenOcclusionQueriesNV_Func glGenOcclusionQueriesNV_ptr;  
00086 GL_DeleteOcclusionQueriesNV_Func glDeleteOcclusionQueriesNV_ptr;
00087 GL_BeginOcclusionQueryNV_Func glBeginOcclusionQueryNV_ptr;
00088 GL_EndOcclusionQueryNV_Func glEndOcclusionQueryNV_ptr;
00089 GL_GetOcclusionQueryuivNV_Func glGetOcclusionQueryuivNV_ptr;
00090 
00091 namespace Ogre {
00092 
00093     // Callback function used when registering GLGpuPrograms
00094     GpuProgram* createGLArbGpuProgram(const String& name, GpuProgramType gptype, const String& syntaxCode)
00095     {
00096         return new GLArbGpuProgram(name, gptype, syntaxCode);
00097     }
00098 
00099     GpuProgram* createGLGpuNvparseProgram(const String& name, GpuProgramType gptype, const String& syntaxCode)
00100     {
00101         return new GLGpuNvparseProgram(name, gptype, syntaxCode);
00102     }
00103 
00104     GpuProgram* createGL_ATI_FS_GpuProgram(const String& name, GpuProgramType gptype, const String& syntaxCode)
00105     {
00106 
00107         return new ATI_FS_GLGpuProgram(name, gptype, syntaxCode);
00108     }
00109 
00110     GLRenderSystem::GLRenderSystem()
00111       : mDepthWrite(true), mHardwareBufferManager(0), mGpuProgramManager(0)
00112     {
00113         size_t i;
00114 
00115         OgreGuard( "GLRenderSystem::GLRenderSystem" );
00116 
00117         LogManager::getSingleton().logMessage(getName() + " created.");
00118 
00119         // Get our GLSupport
00120         mGLSupport = getGLSupport();
00121 
00122         for( i=0; i<MAX_LIGHTS; i++ )
00123             mLights[i] = NULL;
00124 
00125         mWorldMatrix = Matrix4::IDENTITY;
00126         mViewMatrix = Matrix4::IDENTITY;
00127         
00128         initConfigOptions();
00129 
00130         mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
00131 
00132         for (i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; i++)
00133         {
00134             mTextureCoordIndex[i] = 0;
00135         }
00136 
00137         for (i = 0; i < OGRE_MAX_TEXTURE_LAYERS; i++)
00138         {
00139             mTextureTypes[i] = 0;
00140         }
00141 
00142         mActiveRenderTarget = NULL;
00143 
00144         mGLInitialized = false;
00145 
00146         glActiveTextureARB_ptr = 0;
00147         glClientActiveTextureARB_ptr = 0;
00148         glSecondaryColorPointerEXT_ptr = 0;
00149         glGenBuffersARB_ptr = 0;
00150         glBindBufferARB_ptr = 0;
00151         glDeleteBuffersARB_ptr = 0;
00152         glMapBufferARB_ptr = 0;
00153         glUnmapBufferARB_ptr = 0;
00154         glBufferDataARB_ptr = 0;
00155         glBufferSubDataARB_ptr = 0;
00156         glGetBufferSubDataARB_ptr = 0;
00157         glGenProgramsARB_ptr = 0;
00158         glDeleteProgramsARB_ptr = 0;
00159         glBindProgramARB_ptr = 0;
00160         glProgramStringARB_ptr = 0;
00161         glProgramLocalParameter4fvARB_ptr = 0;
00162         glProgramParameter4fvNV_ptr = 0;
00163         glCombinerStageParameterfvNV_ptr = 0;
00164         glCombinerParameterfvNV_ptr = 0;
00165         glCombinerParameteriNV_ptr = 0;
00166         glGetProgramivARB_ptr = 0;
00167         glLoadProgramNV_ptr = 0;
00168         glCombinerInputNV_ptr = 0;
00169         glCombinerOutputNV_ptr = 0;
00170         glFinalCombinerInputNV_ptr = 0;
00171         glTrackMatrixNV_ptr = 0;
00172         glActiveStencilFaceEXT_ptr = 0;
00173         glGenOcclusionQueriesNV_ptr = 0;
00174         glDeleteOcclusionQueriesNV_ptr = 0;
00175         glBeginOcclusionQueryNV_ptr = 0;
00176         glEndOcclusionQueryNV_ptr = 0;
00177         glGetOcclusionQueryuivNV_ptr = 0;
00178 
00179         mCurrentLights = 0;
00180         mMinFilter = FO_LINEAR;
00181         mMipFilter = FO_POINT;
00182         mCurrentVertexProgram = 0;
00183         mCurrentFragmentProgram = 0;
00184 
00185         mClipPlanes.reserve(6);
00186 
00187         OgreUnguard();
00188     }
00189 
00190     GLRenderSystem::~GLRenderSystem()
00191     {
00192         // Destroy render windows
00193         RenderTargetMap::iterator i;
00194         for (i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
00195         {
00196             delete i->second;
00197         }
00198         mRenderTargets.clear();
00199 
00200         if (mTextureManager)
00201             delete mTextureManager;
00202 
00203         if (mHardwareBufferManager)
00204             delete mHardwareBufferManager;
00205         if (mGpuProgramManager)
00206             delete mGpuProgramManager;
00207         delete mCapabilities;
00208         delete mGLSupport;
00209     }
00210 
00211     const String& GLRenderSystem::getName(void) const
00212     {
00213         static String strName("OpenGL Rendering Subsystem");
00214         return strName;
00215     }
00216 
00217     void GLRenderSystem::initConfigOptions(void)
00218     {
00219         OgreGuard("GLRenderSystem::initConfigOptions");
00220         mGLSupport->addConfig();
00221         OgreUnguard();
00222     }
00223     
00224     ConfigOptionMap& GLRenderSystem::getConfigOptions(void)
00225     {
00226         return mGLSupport->getConfigOptions();
00227     }
00228 
00229     void GLRenderSystem::setConfigOption(const String &name, const String &value)
00230     {
00231         mGLSupport->setConfigOption(name, value);
00232     }
00233 
00234     String GLRenderSystem::validateConfigOptions(void)
00235     {
00236         // XXX Return an error string if something is invalid
00237         return mGLSupport->validateConfig();
00238     }
00239 
00240     RenderWindow* GLRenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
00241     {
00242 
00243         mGLSupport->start();
00244         RenderWindow* autoWindow = mGLSupport->createWindow(autoCreateWindow, this, windowTitle);
00245 
00246         _setCullingMode( mCullingMode );
00247         
00248         return autoWindow;
00249     }
00250 
00251     void GLRenderSystem::initGL(void)
00252     {
00253         mGLSupport->initialiseExtensions();
00254 
00255         LogManager::getSingleton().logMessage(
00256             "***************************\n"
00257             "*** GL Renderer Started ***\n"
00258             "***************************");
00259 
00260 
00261         // Check for hardware mipmapping support.
00262         // Note: This is disabled for ATI cards until they fix their drivers
00263         if(mGLSupport->getGLVendor() != "ATI" && 
00264             (mGLSupport->checkMinGLVersion("1.4.0") || 
00265              mGLSupport->checkExtension("GL_SGIS_generate_mipmap")))
00266         {
00267             mCapabilities->setCapability(RSC_AUTOMIPMAP);
00268         }
00269 
00270         // Check for blending support
00271         if(mGLSupport->checkMinGLVersion("1.3.0") || 
00272             mGLSupport->checkExtension("GL_ARB_texture_env_combine") || 
00273             mGLSupport->checkExtension("GL_EXT_texture_env_combine"))
00274         {
00275             mCapabilities->setCapability(RSC_BLENDING);
00276         }
00277 
00278         // Check for Multitexturing support and set number of texture units
00279         if(mGLSupport->checkMinGLVersion("1.3.0") || 
00280             mGLSupport->checkExtension("GL_ARB_multitexture"))
00281         {
00282             GLint units;
00283             glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
00284 
00285             mCapabilities->setNumTextureUnits(units);
00286         }
00287         else
00288         {
00289             // If no multitexture support then set one texture unit
00290             mCapabilities->setNumTextureUnits(1);
00291         }
00292             
00293         // Check for Anisotropy support
00294         if(mGLSupport->checkExtension("GL_EXT_texture_filter_anisotropic"))
00295         {
00296             mCapabilities->setCapability(RSC_ANISOTROPY);
00297         }
00298 
00299         // Check for DOT3 support
00300         if(mGLSupport->checkMinGLVersion("1.3.0") ||
00301             mGLSupport->checkExtension("GL_ARB_texture_env_dot3") ||
00302             mGLSupport->checkExtension("GL_EXT_texture_env_dot3"))
00303         {
00304             mCapabilities->setCapability(RSC_DOT3);
00305         }
00306 
00307         // Check for cube mapping
00308         if(mGLSupport->checkMinGLVersion("1.3.0") || 
00309             mGLSupport->checkExtension("GL_ARB_texture_cube_map") || 
00310             mGLSupport->checkExtension("GL_EXT_texture_cube_map"))
00311         {
00312             mCapabilities->setCapability(RSC_CUBEMAPPING);
00313         }
00314         
00315         // Check for hardware stencil support and set bit depth
00316         GLint stencil;
00317         glGetIntegerv(GL_STENCIL_BITS,&stencil);
00318 
00319         if(stencil)
00320         {
00321             mCapabilities->setCapability(RSC_HWSTENCIL);
00322             mCapabilities->setStencilBufferBitDepth(stencil);
00323         }
00324 
00325         // Check for VBO support
00326         if(mGLSupport->checkExtension("GL_ARB_vertex_buffer_object"))
00327         {
00328             mCapabilities->setCapability(RSC_VBO);
00329 
00330             mHardwareBufferManager = new GLHardwareBufferManager;
00331         }
00332         else
00333         {
00334             mHardwareBufferManager = new GLDefaultHardwareBufferManager;
00335         }
00336 
00337         // XXX Need to check for nv2 support and make a program manager for it
00338         // XXX Probably nv1 as well for older cards
00339         // GPU Program Manager setup
00340         mGpuProgramManager = new GLGpuProgramManager();
00341         if(mGLSupport->checkExtension("GL_ARB_vertex_program"))
00342         {
00343             mCapabilities->setCapability(RSC_VERTEX_PROGRAM);
00344 
00345             // Vertex Program Properties
00346             mCapabilities->setMaxVertexProgramVersion("arbvp1");
00347             mCapabilities->setVertexProgramConstantBoolCount(0);
00348             mCapabilities->setVertexProgramConstantIntCount(0);
00349             mCapabilities->setVertexProgramConstantFloatCount(
00350                 GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
00351 
00352             mGpuProgramManager->_pushSyntaxCode("arbvp1");
00353             mGpuProgramManager->registerProgramFactory("arbvp1", createGLArbGpuProgram);
00354         }
00355 
00356         if (mGLSupport->checkExtension("GL_NV_register_combiners2") &&
00357             mGLSupport->checkExtension("GL_NV_texture_shader"))
00358         {
00359             mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
00360             mCapabilities->setMaxFragmentProgramVersion("fp20");
00361 
00362             mGpuProgramManager->_pushSyntaxCode("fp20");
00363             mGpuProgramManager->registerProgramFactory("fp20", createGLGpuNvparseProgram);
00364         }
00365 
00366 
00367         // NFZ - check for ATI fragment shader support
00368         if (mGLSupport->checkExtension("GL_ATI_fragment_shader"))
00369         {
00370             mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
00371             mCapabilities->setMaxFragmentProgramVersion("ps_1_4");
00372             // no boolean params allowed
00373             mCapabilities->setFragmentProgramConstantBoolCount(0);
00374             // no integer params allowed
00375             mCapabilities->setFragmentProgramConstantIntCount(0);
00376 
00377             // only 8 Vector4 constant floats supported
00378             mCapabilities->setFragmentProgramConstantFloatCount(8);
00379 
00380             mGpuProgramManager->_pushSyntaxCode("ps_1_4");
00381             mGpuProgramManager->_pushSyntaxCode("ps_1_3");
00382             mGpuProgramManager->_pushSyntaxCode("ps_1_2");
00383             mGpuProgramManager->_pushSyntaxCode("ps_1_1");
00384 
00385             mGpuProgramManager->registerProgramFactory("ps_1_4", createGL_ATI_FS_GpuProgram);
00386             mGpuProgramManager->registerProgramFactory("ps_1_3", createGL_ATI_FS_GpuProgram);
00387             mGpuProgramManager->registerProgramFactory("ps_1_2", createGL_ATI_FS_GpuProgram);
00388             mGpuProgramManager->registerProgramFactory("ps_1_1", createGL_ATI_FS_GpuProgram);
00389         }
00390 
00391 
00392         if (mGLSupport->checkExtension("GL_ARB_fragment_program"))
00393         {
00394             mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
00395             // Fragment Program Properties
00396             mCapabilities->setMaxFragmentProgramVersion("arbfp1");
00397             mCapabilities->setFragmentProgramConstantBoolCount(0);
00398             mCapabilities->setFragmentProgramConstantIntCount(0);
00399             mCapabilities->setFragmentProgramConstantFloatCount(
00400                 GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
00401 
00402             mGpuProgramManager->_pushSyntaxCode("arbfp1");
00403             mGpuProgramManager->registerProgramFactory("arbfp1", createGLArbGpuProgram);
00404         }
00405 
00406         // Check for texture compression
00407         if(mGLSupport->checkMinGLVersion("1.3.0") ||
00408             mGLSupport->checkExtension("GL_ARB_texture_compression"))
00409         {   
00410             mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION);
00411          
00412             // Check for dxt compression
00413             if(mGLSupport->checkExtension("GL_EXT_texture_compression_s3tc"))
00414             {
00415                 mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
00416             }
00417             // Check for vtc compression
00418             if(mGLSupport->checkExtension("GL_NV_texture_compression_vtc"))
00419             {
00420                 mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION_VTC);
00421             }
00422         }
00423 
00424         // Scissor test is standard in GL 1.2 (is it emulated on some cards though?)
00425         mCapabilities->setCapability(RSC_SCISSOR_TEST);
00426         // As are user clipping planes
00427         mCapabilities->setCapability(RSC_USER_CLIP_PLANES);
00428 
00429         // 2-sided stencil?
00430         if (mGLSupport->checkExtension("GL_EXT_stencil_two_side"))
00431         {
00432             mCapabilities->setCapability(RSC_TWO_SIDED_STENCIL);
00433         }
00434         // stencil wrapping?
00435         if (mGLSupport->checkExtension("GL_EXT_stencil_wrap"))
00436         {
00437             mCapabilities->setCapability(RSC_STENCIL_WRAP);
00438         }
00439 
00440         // Check for hardware occlusion support
00441         if(mGLSupport->checkExtension("GL_NV_occlusion_query"))
00442         {
00443             mCapabilities->setCapability(RSC_HWOCCLUSION);      
00444         }
00445         // UBYTE4 always supported
00446         mCapabilities->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
00447 
00448         // Inifinite far plane always supported
00449         mCapabilities->setCapability(RSC_INFINITE_FAR_PLANE);
00450 
00451         // Get extension function pointers
00452         glActiveTextureARB_ptr = 
00453             (GL_ActiveTextureARB_Func)mGLSupport->getProcAddress("glActiveTextureARB");
00454         glClientActiveTextureARB_ptr = 
00455             (GL_ClientActiveTextureARB_Func)mGLSupport->getProcAddress("glClientActiveTextureARB");
00456         glSecondaryColorPointerEXT_ptr = 
00457             (GL_SecondaryColorPointerEXT_Func)mGLSupport->getProcAddress("glSecondaryColorPointerEXT");
00458         glGenBuffersARB_ptr = 
00459             (GL_GenBuffersARB_Func)mGLSupport->getProcAddress("glGenBuffersARB");
00460         glBindBufferARB_ptr = 
00461             (GL_BindBufferARB_Func)mGLSupport->getProcAddress("glBindBufferARB");
00462         glDeleteBuffersARB_ptr = 
00463             (GL_DeleteBuffersARB_Func)mGLSupport->getProcAddress("glDeleteBuffersARB");
00464         glMapBufferARB_ptr = 
00465             (GL_MapBufferARB_Func)mGLSupport->getProcAddress("glMapBufferARB");
00466         glUnmapBufferARB_ptr = 
00467             (GL_UnmapBufferARB_Func)mGLSupport->getProcAddress("glUnmapBufferARB");
00468         glBufferDataARB_ptr = 
00469             (GL_BufferDataARB_Func)mGLSupport->getProcAddress("glBufferDataARB");
00470         glBufferSubDataARB_ptr = 
00471             (GL_BufferSubDataARB_Func)mGLSupport->getProcAddress("glBufferSubDataARB");
00472         glGetBufferSubDataARB_ptr = 
00473             (GL_GetBufferSubDataARB_Func)mGLSupport->getProcAddress("glGetBufferSubDataARB");
00474         glGenProgramsARB_ptr =
00475             (GL_GenProgramsARB_Func)mGLSupport->getProcAddress("glGenProgramsARB");
00476         glDeleteProgramsARB_ptr =
00477             (GL_DeleteProgramsARB_Func)mGLSupport->getProcAddress("glDeleteProgramsARB");
00478         glBindProgramARB_ptr =
00479             (GL_BindProgramARB_Func)mGLSupport->getProcAddress("glBindProgramARB");
00480         glProgramStringARB_ptr =
00481             (GL_ProgramStringARB_Func)mGLSupport->getProcAddress("glProgramStringARB");
00482         glProgramLocalParameter4fvARB_ptr =
00483             (GL_ProgramLocalParameter4fvARB_Func)mGLSupport->getProcAddress("glProgramLocalParameter4fvARB");
00484          glProgramParameter4fvNV_ptr =
00485             (GL_ProgramParameter4fvNV_Func)mGLSupport->getProcAddress("glProgramParameter4fvNV");
00486          glVertexAttribPointerARB_ptr =
00487              (GL_VertexAttribPointerARB_Func)mGLSupport->getProcAddress("glVertexAttribPointerARB");
00488          glEnableVertexAttribArrayARB_ptr =
00489              (GL_EnableVertexAttribArrayARB_Func)mGLSupport->getProcAddress("glEnableVertexAttribArrayARB");
00490          glDisableVertexAttribArrayARB_ptr =
00491              (GL_DisableVertexAttribArrayARB_Func)mGLSupport->getProcAddress("glDisableVertexAttribArrayARB");
00492          glCombinerStageParameterfvNV_ptr =
00493             (GL_CombinerStageParameterfvNV_Func)mGLSupport->getProcAddress("glCombinerStageParameterfvNV");
00494         glCombinerParameterfvNV_ptr = 
00495             (GL_CombinerParameterfvNV_Func)mGLSupport->getProcAddress("glCombinerParameterfvNV");
00496          glCombinerParameteriNV_ptr = (GL_CombinerParameteriNV_Func)mGLSupport->getProcAddress("glCombinerParameteriNV");
00497         glGetProgramivARB_ptr = 
00498             (GL_GetProgramivARB_Func)mGLSupport->getProcAddress("glGetProgramivARB");
00499         glLoadProgramNV_ptr = 
00500             (GL_LoadProgramNV_Func)mGLSupport->getProcAddress("glLoadProgramNV");
00501         glCombinerInputNV_ptr =
00502             (GL_CombinerInputNV_Func)mGLSupport->getProcAddress("glCombinerInputNV");
00503         glCombinerOutputNV_ptr =
00504             (GL_CombinerOutputNV_Func)mGLSupport->getProcAddress("glCombinerOutputNV");
00505         glFinalCombinerInputNV_ptr = 
00506             (GL_FinalCombinerInputNV_Func)mGLSupport->getProcAddress("glFinalCombinerInputNV");
00507         glTrackMatrixNV_ptr = 
00508             (GL_TrackMatrixNV_Func)mGLSupport->getProcAddress("glTrackMatrixNV");
00509         glCompressedTexImage2DARB_ptr =
00510             (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)mGLSupport->getProcAddress("glCompressedTexImage2DARB");
00511         InitATIFragmentShaderExtensions(*mGLSupport);
00512         glActiveStencilFaceEXT_ptr = 
00513             (GL_ActiveStencilFaceEXT_Func)mGLSupport->getProcAddress("glActiveStencilFaceEXT");
00514         glGenOcclusionQueriesNV_ptr =
00515             (GL_GenOcclusionQueriesNV_Func)mGLSupport->getProcAddress("glGenOcclusionQueriesNV");
00516         glDeleteOcclusionQueriesNV_ptr =
00517             (GL_DeleteOcclusionQueriesNV_Func)mGLSupport->getProcAddress("glDeleteOcclusionQueriesNV");
00518         glBeginOcclusionQueryNV_ptr =
00519             (GL_BeginOcclusionQueryNV_Func)mGLSupport->getProcAddress("glBeginOcclusionQueryNV");
00520         glEndOcclusionQueryNV_ptr =
00521             (GL_EndOcclusionQueryNV_Func)mGLSupport->getProcAddress("glEndOcclusionQueryNV");
00522         glGetOcclusionQueryuivNV_ptr =
00523             (GL_GetOcclusionQueryuivNV_Func)mGLSupport->getProcAddress("glGetOcclusionQueryuivNV");
00524 
00525         mCapabilities->log(LogManager::getSingleton().getDefaultLog());
00526         mGLInitialized = true;
00527     }
00528 
00529     void GLRenderSystem::reinitialise(void)
00530     {
00531         this->shutdown();
00532         this->initialise(true);
00533     }
00534 
00535     void GLRenderSystem::shutdown(void)
00536     {
00537         RenderSystem::shutdown();
00538 
00539         mGLSupport->stop();
00540         mStopRendering = true;
00541     }
00542 
00543     void GLRenderSystem::setAmbientLight(float r, float g, float b)
00544     {
00545         GLfloat lmodel_ambient[] = {r, g, b, 1.0};
00546         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
00547     }
00548 
00549     void GLRenderSystem::setShadingType(ShadeOptions so)
00550     {
00551         switch(so)
00552         {
00553         case SO_FLAT:
00554             glShadeModel(GL_FLAT);
00555             break;
00556         default:
00557             glShadeModel(GL_SMOOTH);
00558             break;
00559         }
00560     }
00561 
00562 
00563     RenderWindow* GLRenderSystem::createRenderWindow(
00564             const String & name, unsigned int width, unsigned int height, unsigned int colourDepth,
00565             bool fullScreen, int left, int top, bool depthBuffer, 
00566             RenderWindow* parentWindowHandle)
00567     {
00568         if (mRenderTargets.find(name) != mRenderTargets.end())
00569         {
00570             Except(
00571                 Exception::ERR_INVALIDPARAMS, 
00572                 "Window with name '" + name + "' already exists",
00573                 "GLRenderSystem::createRenderWindow" );
00574         }
00575 
00576         // Create the window
00577         RenderWindow* win = mGLSupport->newWindow(name, width, height, 
00578             colourDepth, fullScreen, left, top, depthBuffer, parentWindowHandle,
00579             mVSync);
00580 
00581         attachRenderTarget( *win );
00582 
00583         if (!mGLInitialized) 
00584         {
00585             initGL();
00586             mTextureManager = new GLTextureManager(*mGLSupport);
00587         }
00588 
00589         // XXX Do more?
00590 
00591         return win;
00592     }
00593 
00594     RenderTexture * GLRenderSystem::createRenderTexture( const String & name, unsigned int width, unsigned int height )
00595     {
00596         RenderTexture* rt = new GLRenderTexture(name, width, height);
00597         attachRenderTarget(*rt);
00598         return rt;
00599     }
00600 
00601     //-----------------------------------------------------------------------
00602     void GLRenderSystem::destroyRenderWindow(RenderWindow* pWin)
00603     {
00604         // Find it to remove from list
00605         RenderTargetMap::iterator i = mRenderTargets.begin();
00606 
00607         while (i != mRenderTargets.end())
00608         {
00609             if (i->second == pWin)
00610             {
00611                 mRenderTargets.erase(i);
00612                 delete pWin;
00613                 break;
00614             }
00615         }
00616     }
00617 
00618     //---------------------------------------------------------------------
00619     void GLRenderSystem::_useLights(const LightList& lights, unsigned short limit)
00620     {
00621 
00622         // Save previous modelview
00623         glMatrixMode(GL_MODELVIEW);
00624         glPushMatrix();
00625         // just load view matrix (identity world)
00626         GLfloat mat[16];
00627         makeGLMatrix(mat, mViewMatrix);
00628         glLoadMatrixf(mat);
00629 
00630         LightList::const_iterator i, iend;
00631         iend = lights.end();
00632         unsigned short num = 0;
00633         for (i = lights.begin(); i != iend && num < limit; ++i, ++num)
00634         {
00635             setGLLight(num, *i);
00636             mLights[num] = *i;
00637         }
00638         // Disable extra lights
00639         for (; num < mCurrentLights; ++num)
00640         {
00641             setGLLight(num, NULL);
00642             mLights[num] = NULL;
00643         }
00644         mCurrentLights = std::min(limit, static_cast<unsigned short>(lights.size()));
00645 
00646         setLights();
00647 
00648         // restore previous
00649         glPopMatrix();
00650 
00651     }
00652 
00653     void GLRenderSystem::setGLLight(size_t index, Light* lt)
00654     {
00655         GLenum gl_index = GL_LIGHT0 + index;
00656 
00657         if (!lt)
00658         {
00659             // Disable in the scene
00660             glDisable(gl_index);
00661         }
00662         else
00663         {
00664             switch (lt->getType())
00665             {
00666             case Light::LT_SPOTLIGHT:
00667                 glLightf( gl_index, GL_SPOT_CUTOFF, lt->getSpotlightOuterAngle() * 0.5 );
00668                 break;
00669             default:
00670                 glLightf( gl_index, GL_SPOT_CUTOFF, 180.0 );
00671                 break;
00672             }
00673 
00674             // Color
00675             ColourValue col;
00676             col = lt->getDiffuseColour();
00677 
00678 
00679             GLfloat f4vals[4] = {col.r, col.g, col.b, col.a};
00680             glLightfv(gl_index, GL_DIFFUSE, f4vals);
00681             
00682             col = lt->getSpecularColour();
00683             f4vals[0] = col.r;
00684             f4vals[1] = col.g;
00685             f4vals[2] = col.b;
00686             f4vals[3] = col.a;
00687             glLightfv(gl_index, GL_SPECULAR, f4vals);
00688 
00689             // Disable ambient light for movables
00690             glLighti(gl_index, GL_AMBIENT, 0);
00691 
00692             setGLLightPositionDirection(lt, gl_index);
00693 
00694 
00695             // Attenuation
00696             glLightf(gl_index, GL_CONSTANT_ATTENUATION, lt->getAttenuationConstant());
00697             glLightf(gl_index, GL_LINEAR_ATTENUATION, lt->getAttenuationLinear());
00698             glLightf(gl_index, GL_QUADRATIC_ATTENUATION, lt->getAttenuationQuadric());
00699             // Enable in the scene
00700             glEnable(gl_index);
00701 
00702         }
00703 
00704     }
00705 
00706     //-----------------------------------------------------------------------------
00707     void GLRenderSystem::makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m)
00708     {
00709         size_t x = 0;
00710         for (size_t i = 0; i < 4; i++)
00711         {
00712             for (size_t j = 0; j < 4; j++)
00713             {
00714                 gl_matrix[x] = m[j][i];
00715                 x++;
00716             }
00717         }
00718     }
00719     //-----------------------------------------------------------------------------
00720     void GLRenderSystem::_setWorldMatrix( const Matrix4 &m )
00721     {
00722         GLfloat mat[16];
00723         mWorldMatrix = m;
00724         makeGLMatrix( mat, mViewMatrix * mWorldMatrix );
00725         glMatrixMode(GL_MODELVIEW);
00726         glLoadMatrixf(mat);
00727     }
00728 
00729     //-----------------------------------------------------------------------------
00730     void GLRenderSystem::_setViewMatrix( const Matrix4 &m )
00731     {
00732         mViewMatrix = m;
00733 
00734         GLfloat mat[16];
00735         makeGLMatrix(mat, mViewMatrix);
00736         glMatrixMode(GL_MODELVIEW);
00737         glLoadMatrixf(mat);
00738 
00739         makeGLMatrix(mat, mWorldMatrix);
00740         glMultMatrixf(mat);
00741 
00742         setGLClipPlanes();
00743     }
00744     //-----------------------------------------------------------------------------
00745     void GLRenderSystem::_setProjectionMatrix(const Matrix4 &m)
00746     {
00747         GLfloat mat[16];
00748         makeGLMatrix(mat, m);
00749         if (mActiveRenderTarget->requiresTextureFlipping())
00750         {
00751             // Invert y
00752             mat[5] = -mat[5];
00753         }
00754         glMatrixMode(GL_PROJECTION);
00755         glLoadMatrixf(mat);
00756         glMatrixMode(GL_MODELVIEW);
00757     }
00758     //-----------------------------------------------------------------------------
00759     void GLRenderSystem::_setSurfaceParams(const ColourValue &ambient,
00760         const ColourValue &diffuse, const ColourValue &specular,
00761         const ColourValue &emissive, Real shininess)
00762     {
00763         // XXX Cache previous values?
00764         // XXX Front or Front and Back?
00765 
00766         GLfloat f4val[4] = {diffuse.r, diffuse.g, diffuse.b, diffuse.a};
00767         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, f4val);
00768         f4val[0] = ambient.r;
00769         f4val[1] = ambient.g;
00770         f4val[2] = ambient.b;
00771         f4val[3] = ambient.a;
00772         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, f4val);
00773         f4val[0] = specular.r;
00774         f4val[1] = specular.g;
00775         f4val[2] = specular.b;
00776         f4val[3] = specular.a;
00777         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, f4val);
00778         f4val[0] = emissive.r;
00779         f4val[1] = emissive.g;
00780         f4val[2] = emissive.b;
00781         f4val[3] = emissive.a;
00782         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, f4val);
00783         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00784     }
00785 
00786     //-----------------------------------------------------------------------------
00787     void GLRenderSystem::_setTexture(size_t stage, bool enabled, const String &texname)
00788     {
00789         GLTexture* tex = static_cast<GLTexture*>(TextureManager::getSingleton().getByName(texname));
00790 
00791         GLenum lastTextureType = mTextureTypes[stage];
00792 
00793         glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
00794         if (enabled)
00795         {
00796             if (tex)
00797                 mTextureTypes[stage] = tex->getGLTextureType();
00798             else
00799                 // assume 2D
00800                 mTextureTypes[stage] = GL_TEXTURE_2D;
00801 
00802             if(lastTextureType != mTextureTypes[stage] && lastTextureType != 0)
00803             {
00804                 glDisable( lastTextureType );
00805             }
00806 
00807             glEnable( mTextureTypes[stage] );
00808             if(tex)
00809                 glBindTexture( mTextureTypes[stage], tex->getGLID() );
00810         }
00811         else
00812         {
00813             glDisable( mTextureTypes[stage] );
00814             glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00815         }
00816 
00817         glActiveTextureARB_ptr( GL_TEXTURE0 );
00818     }
00819 
00820     //-----------------------------------------------------------------------------
00821     void GLRenderSystem::_setTextureCoordSet(size_t stage, size_t index)
00822     {
00823         mTextureCoordIndex[stage] = index;
00824     }
00825     //-----------------------------------------------------------------------------
00826     void GLRenderSystem::_setTextureCoordCalculation(size_t stage, TexCoordCalcMethod m, 
00827         const Frustum* frustum)
00828     {
00829         GLfloat M[16];
00830         Matrix4 projectionBias;
00831 
00832         // Default to no extra auto texture matrix
00833         mUseAutoTextureMatrix = false;
00834 
00835         GLfloat eyePlaneS[] = {1.0, 0.0, 0.0, 0.0};
00836         GLfloat eyePlaneT[] = {0.0, 1.0, 0.0, 0.0};
00837         GLfloat eyePlaneR[] = {0.0, 0.0, 1.0, 0.0};
00838         GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, 1.0};
00839 
00840         glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
00841 
00842         switch( m )
00843         {
00844         case TEXCALC_NONE:
00845             glDisable( GL_TEXTURE_GEN_S );
00846             glDisable( GL_TEXTURE_GEN_T );
00847             glDisable( GL_TEXTURE_GEN_R );
00848             glDisable( GL_TEXTURE_GEN_Q );
00849             break;
00850 
00851         case TEXCALC_ENVIRONMENT_MAP:
00852             glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00853             glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00854 
00855             glEnable( GL_TEXTURE_GEN_S );
00856             glEnable( GL_TEXTURE_GEN_T );
00857             glDisable( GL_TEXTURE_GEN_R );
00858             glDisable( GL_TEXTURE_GEN_Q );
00859 
00860             // Need to use a texture matrix to flip the spheremap
00861             mUseAutoTextureMatrix = true;
00862             memset(mAutoTextureMatrix, 0, sizeof(GLfloat)*16);
00863             mAutoTextureMatrix[0] = mAutoTextureMatrix[10] = mAutoTextureMatrix[15] = 1.0f;
00864             mAutoTextureMatrix[5] = -1.0f;
00865 
00866             break;
00867 
00868         case TEXCALC_ENVIRONMENT_MAP_PLANAR:            
00869             // XXX This doesn't seem right?!
00870 #ifdef GL_VERSION_1_3
00871             glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00872             glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00873             glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00874 
00875             glEnable( GL_TEXTURE_GEN_S );
00876             glEnable( GL_TEXTURE_GEN_T );
00877             glEnable( GL_TEXTURE_GEN_R );
00878             glDisable( GL_TEXTURE_GEN_Q );
00879 #else
00880             glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00881             glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
00882 
00883             glEnable( GL_TEXTURE_GEN_S );
00884             glEnable( GL_TEXTURE_GEN_T );
00885             glDisable( GL_TEXTURE_GEN_R );
00886             glDisable( GL_TEXTURE_GEN_Q );
00887 #endif
00888             break;
00889         case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
00890             
00891             glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00892             glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00893             glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
00894 
00895             glEnable( GL_TEXTURE_GEN_S );
00896             glEnable( GL_TEXTURE_GEN_T );
00897             glEnable( GL_TEXTURE_GEN_R );
00898             glDisable( GL_TEXTURE_GEN_Q );
00899 
00900             // We need an extra texture matrix here
00901             // This sets the texture matrix to be the inverse of the modelview matrix
00902             mUseAutoTextureMatrix = true;
00903             glGetFloatv( GL_MODELVIEW_MATRIX, M );
00904 
00905             // Transpose 3x3 in order to invert matrix (rotation)
00906             // Note that we need to invert the Z _before_ the rotation
00907             // No idea why we have to invert the Z at all, but reflection is wrong without it
00908             mAutoTextureMatrix[0] = M[0]; mAutoTextureMatrix[1] = M[4]; mAutoTextureMatrix[2] = -M[8];
00909             mAutoTextureMatrix[4] = M[1]; mAutoTextureMatrix[5] = M[5]; mAutoTextureMatrix[6] = -M[9];
00910             mAutoTextureMatrix[8] = M[2]; mAutoTextureMatrix[9] = M[6]; mAutoTextureMatrix[10] = -M[10];
00911             mAutoTextureMatrix[3] = mAutoTextureMatrix[7] = mAutoTextureMatrix[11] = 0.0f;
00912             mAutoTextureMatrix[12] = mAutoTextureMatrix[13] = mAutoTextureMatrix[14] = 0.0f;
00913             mAutoTextureMatrix[15] = 1.0f;
00914 
00915             break;
00916         case TEXCALC_ENVIRONMENT_MAP_NORMAL:
00917             glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
00918             glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
00919             glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
00920 
00921             glEnable( GL_TEXTURE_GEN_S );
00922             glEnable( GL_TEXTURE_GEN_T );
00923             glEnable( GL_TEXTURE_GEN_R );
00924             glDisable( GL_TEXTURE_GEN_Q );
00925             break;
00926         case TEXCALC_PROJECTIVE_TEXTURE:
00927             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00928             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00929             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00930             glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00931             glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
00932             glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
00933             glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
00934             glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
00935             glEnable(GL_TEXTURE_GEN_S);
00936             glEnable(GL_TEXTURE_GEN_T);
00937             glEnable(GL_TEXTURE_GEN_R);
00938             glEnable(GL_TEXTURE_GEN_Q);
00939 
00940             mUseAutoTextureMatrix = true;
00941 
00942             // Set scale and translation matrix for projective textures
00943             projectionBias = Matrix4::ZERO;
00944             projectionBias[0][0] = 0.5; projectionBias[1][1] = -0.5; 
00945             projectionBias[2][2] = 1.0; projectionBias[0][3] = 0.5; 
00946             projectionBias[1][3] = 0.5; projectionBias[3][3] = 1.0;
00947 
00948             projectionBias = projectionBias * frustum->getProjectionMatrix();
00949             projectionBias = projectionBias * frustum->getViewMatrix();
00950 
00951             makeGLMatrix(mAutoTextureMatrix, projectionBias);
00952             break;
00953         default:
00954             break;
00955         }
00956         glActiveTextureARB_ptr( GL_TEXTURE0 );
00957     }
00958     //-----------------------------------------------------------------------------
00959     void GLRenderSystem::_setTextureAddressingMode(size_t stage, TextureUnitState::TextureAddressingMode tam)
00960     {
00961         GLint type;
00962         switch(tam)
00963         {
00964         case TextureUnitState::TAM_WRAP:
00965             type = GL_REPEAT;
00966             break;
00967         case TextureUnitState::TAM_MIRROR:
00968             type = GL_MIRRORED_REPEAT;
00969             break;
00970         case TextureUnitState::TAM_CLAMP:
00971             type = GL_CLAMP_TO_EDGE;
00972             break;
00973         }
00974 
00975         glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
00976         glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S, type );
00977         glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T, type );
00978         glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R, type );
00979         glActiveTextureARB_ptr( GL_TEXTURE0 );
00980     }
00981     //-----------------------------------------------------------------------------
00982     void GLRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xform)
00983     {
00984         GLfloat mat[16];
00985         makeGLMatrix(mat, xform);
00986 
00987         mat[12] = mat[8];
00988         mat[13] = mat[9];
00989 //        mat[14] = mat[10];
00990 //        mat[15] = mat[11];
00991 
00992 //        for (int j=0; j< 4; j++)
00993 //        {
00994 //            int x = 0;
00995 //            for (x = 0; x < 4; x++)
00996 //            {
00997 //                printf("[%2d]=%0.2f\t", (x*4) + j, mat[(x*4) + j]);
00998 //            }
00999 //            printf("\n");
01000 //        }
01001 
01002         glActiveTextureARB_ptr(GL_TEXTURE0 + stage);
01003         glMatrixMode(GL_TEXTURE);
01004 
01005         if (mUseAutoTextureMatrix)
01006         {
01007             // Load auto matrix in
01008             glLoadMatrixf(mAutoTextureMatrix);
01009             // Concat new matrix
01010             glMultMatrixf(mat);
01011 
01012         }
01013         else
01014         {
01015             // Just load this matrix
01016             glLoadMatrixf(mat);
01017         }
01018 
01019         glMatrixMode(GL_MODELVIEW);
01020         glActiveTextureARB_ptr(GL_TEXTURE0);
01021     }
01022     //-----------------------------------------------------------------------------
01023     GLint GLRenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const
01024     {
01025         switch(ogreBlend)
01026         {
01027         case SBF_ONE:
01028             return GL_ONE;
01029         case SBF_ZERO:
01030             return GL_ZERO;
01031         case SBF_DEST_COLOUR:
01032             return GL_DST_COLOR;
01033         case SBF_SOURCE_COLOUR:
01034             return GL_SRC_COLOR;
01035         case SBF_ONE_MINUS_DEST_COLOUR:
01036             return GL_ONE_MINUS_DST_COLOR;
01037         case SBF_ONE_MINUS_SOURCE_COLOUR:
01038             return GL_ONE_MINUS_SRC_COLOR;
01039         case SBF_DEST_ALPHA:
01040             return GL_DST_ALPHA;
01041         case SBF_SOURCE_ALPHA:
01042             return GL_SRC_ALPHA;
01043         case SBF_ONE_MINUS_DEST_ALPHA:
01044             return GL_ONE_MINUS_DST_ALPHA;
01045         case SBF_ONE_MINUS_SOURCE_ALPHA:
01046             return GL_ONE_MINUS_SRC_ALPHA;
01047         };
01048         // to keep compiler happy
01049         return GL_ONE;
01050     }
01051 
01052     void GLRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
01053     {
01054         GLint sourceBlend = getBlendMode(sourceFactor);
01055         GLint destBlend = getBlendMode(destFactor);
01056         
01057         glEnable(GL_BLEND);
01058         glBlendFunc(sourceBlend, destBlend);
01059     }
01060     //-----------------------------------------------------------------------------
01061     void GLRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value)
01062     {
01063         glEnable(GL_ALPHA_TEST);
01064         glAlphaFunc(convertCompareFunction(func), value / 255.0f);
01065     }
01066     //-----------------------------------------------------------------------------
01067     void GLRenderSystem::_setViewport(Viewport *vp)
01068     {
01069         // Check if viewport is different
01070         if (vp != mActiveViewport || vp->_isUpdated())
01071         {
01072               mActiveViewport = vp;
01073               mActiveRenderTarget = vp->getTarget();
01074               // XXX Rendering target stuff?
01075               GLsizei x, y, w, h;
01076   
01077               RenderTarget* target;
01078               target = vp->getTarget();
01079   
01080               // Calculate the "lower-left" corner of the viewport
01081               w = vp->getActualWidth();
01082               h = vp->getActualHeight();
01083               x = vp->getActualLeft();
01084               y = target->getHeight() - vp->getActualTop() - h;
01085   
01086               glViewport(x, y, w, h);
01087   
01088               // Configure the viewport clipping
01089               glScissor(x, y, w, h);
01090   
01091               vp->_clearUpdatedFlag();
01092         }
01093     }
01094 
01095     void GLRenderSystem::setLights()
01096     {
01097         for (size_t i = 0; i < MAX_LIGHTS; ++i)
01098         {
01099             if (mLights[i] != NULL)
01100             {
01101                 Light* lt = mLights[i];
01102                 setGLLightPositionDirection(lt, i);
01103             }
01104         }
01105     }
01106 
01107     //-----------------------------------------------------------------------------
01108     void GLRenderSystem::_beginFrame(void)
01109     {
01110         OgreGuard( "GLRenderSystem::_beginFrame" );
01111         
01112         if (!mActiveViewport)
01113             Except(999, "Cannot begin frame - no viewport selected.",
01114                 "GLRenderSystem::_beginFrame");
01115 
01116         // Clear the viewport if required
01117         if (mActiveViewport->getClearEveryFrame())
01118         {
01119             // Activate the viewport clipping
01120             glEnable(GL_SCISSOR_TEST);
01121 
01122             clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, 
01123                 mActiveViewport->getBackgroundColour());
01124         }        
01125 
01126         OgreUnguard();
01127     }
01128    
01129     //-----------------------------------------------------------------------------
01130     void GLRenderSystem::_endFrame(void)
01131     {
01132         // XXX Do something?
01133     }
01134 
01135     //-----------------------------------------------------------------------------
01136     void GLRenderSystem::_setCullingMode(CullingMode mode)
01137     {
01138         GLint cullMode;
01139 
01140         switch( mode )
01141         {
01142         case CULL_NONE:
01143             glDisable( GL_CULL_FACE );
01144             return;
01145         case CULL_CLOCKWISE:
01146             if (mActiveRenderTarget && 
01147                 ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
01148                 (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
01149             {
01150                 cullMode = GL_CW;
01151             }
01152             else
01153             {
01154                 cullMode = GL_CCW;
01155             }
01156             break;
01157         case CULL_ANTICLOCKWISE:
01158             if (mActiveRenderTarget && 
01159                 ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
01160                 (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
01161             {
01162                 cullMode = GL_CCW;
01163             }
01164             else
01165             {
01166                 cullMode = GL_CW;
01167             }
01168             break;
01169         }
01170 
01171         glEnable( GL_CULL_FACE );
01172         glFrontFace( cullMode );
01173     }
01174     //-----------------------------------------------------------------------------
01175     void GLRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
01176     {
01177         _setDepthBufferCheckEnabled(depthTest);
01178         _setDepthBufferWriteEnabled(depthWrite);
01179         _setDepthBufferFunction(depthFunction);
01180     }
01181     //-----------------------------------------------------------------------------
01182     void GLRenderSystem::_setDepthBufferCheckEnabled(bool enabled)
01183     {
01184         if (enabled)
01185         {
01186             glClearDepth(1.0f);
01187             glEnable(GL_DEPTH_TEST);
01188         }
01189         else
01190         {
01191             glDisable(GL_DEPTH_TEST);
01192         }
01193     }
01194     //-----------------------------------------------------------------------------
01195     void GLRenderSystem::_setDepthBufferWriteEnabled(bool enabled)
01196     {
01197         GLboolean flag = enabled ? GL_TRUE : GL_FALSE;
01198         glDepthMask( flag );  
01199         // Store for reference in _beginFrame
01200         mDepthWrite = enabled;
01201     }
01202     //-----------------------------------------------------------------------------
01203     void GLRenderSystem::_setDepthBufferFunction(CompareFunction func)
01204     {
01205         glDepthFunc(convertCompareFunction(func));
01206     }
01207     //-----------------------------------------------------------------------------
01208     void GLRenderSystem::_setDepthBias(ushort bias)
01209     {
01210         if (bias > 0)
01211         {
01212             glEnable(GL_POLYGON_OFFSET_FILL);
01213             glEnable(GL_POLYGON_OFFSET_POINT);
01214             glEnable(GL_POLYGON_OFFSET_LINE);
01215             // Bias is in {0, 16}, scale the unit addition appropriately
01216             glPolygonOffset(1.0f, bias);
01217         }
01218         else
01219         {
01220             glDisable(GL_POLYGON_OFFSET_FILL);
01221             glDisable(GL_POLYGON_OFFSET_POINT);
01222             glDisable(GL_POLYGON_OFFSET_LINE);
01223         }
01224     }
01225     //-----------------------------------------------------------------------------
01226     void GLRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
01227     {
01228         glColorMask(red, green, blue, alpha);
01229         // record this
01230         mColourWrite[0] = red;
01231         mColourWrite[1] = blue;
01232         mColourWrite[2] = green;
01233         mColourWrite[3] = alpha;
01234     }
01235     //-----------------------------------------------------------------------------
01236     String GLRenderSystem::getErrorDescription(long errCode) const
01237     {
01238         // XXX FIXME
01239         return String("Uknown Error");
01240     }
01241     //-----------------------------------------------------------------------------
01242     void GLRenderSystem::setLightingEnabled(bool enabled)
01243     {
01244         if (enabled)
01245             glEnable(GL_LIGHTING);
01246         else
01247             glDisable(GL_LIGHTING);
01248     }
01249     //-----------------------------------------------------------------------------
01250     void GLRenderSystem::_setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
01251     {
01252 
01253         GLint fogMode;
01254         switch (mode)
01255         {
01256         case FOG_EXP:
01257             fogMode = GL_EXP;
01258             break;
01259         case FOG_EXP2:
01260             fogMode = GL_EXP2;
01261             break;
01262         case FOG_LINEAR:
01263             fogMode = GL_LINEAR;
01264             break;
01265         default:
01266             // Give up on it
01267             glDisable(GL_FOG);
01268             return;
01269         }
01270 
01271         glEnable(GL_FOG);
01272         glFogi(GL_FOG_MODE, fogMode);
01273         GLfloat fogColor[4] = {colour.r, colour.g, colour.b, colour.a};
01274         glFogfv(GL_FOG_COLOR, fogColor);
01275         glFogf(GL_FOG_DENSITY, density);
01276         glFogf(GL_FOG_START, start);
01277         glFogf(GL_FOG_END, end);
01278         // XXX Hint here?
01279     }
01280 
01281     void GLRenderSystem::convertColourValue(const ColourValue& colour, unsigned long* pDest)
01282     {
01283     #if OGRE_ENDIAN == ENDIAN_BIG
01284         *pDest = colour.getAsLongRGBA();
01285     #else
01286       // GL accesses by byte, so use ABGR so little-endian format will make it RGBA in byte mode
01287         *pDest = colour.getAsLongABGR();
01288     #endif
01289     }
01290     
01291     void GLRenderSystem::_makeProjectionMatrix(Real fovy, Real aspect, Real nearPlane, 
01292         Real farPlane, Matrix4& dest, bool forGpuProgram)
01293     {
01294         Real thetaY = Math::AngleUnitsToRadians(fovy / 2.0f);
01295         Real tanThetaY = Math::Tan(thetaY);
01296         //Real thetaX = thetaY * aspect;
01297         //Real tanThetaX = Math::Tan(thetaX);
01298 
01299         // Calc matrix elements
01300         Real w = (1.0f / tanThetaY) / aspect;
01301         Real h = 1.0f / tanThetaY;
01302         Real q, qn;
01303         if (farPlane == 0)
01304         {
01305             // Infinite far plane
01306             q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
01307             qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
01308         }
01309         else
01310         {
01311             q = -(farPlane + nearPlane) / (farPlane - nearPlane);
01312             qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
01313         }
01314 
01315         // NB This creates Z in range [-1,1]
01316         //
01317         // [ w   0   0   0  ]
01318         // [ 0   h   0   0  ]
01319         // [ 0   0   q   qn ]
01320         // [ 0   0   -1  0  ]
01321 
01322         dest = Matrix4::ZERO;
01323         dest[0][0] = w;
01324         dest[1][1] = h;
01325         dest[2][2] = q;
01326         dest[2][3] = qn;
01327         dest[3][2] = -1;
01328 
01329     }
01330     
01331     void GLRenderSystem::_makeOrthoMatrix(Real fovy, Real aspect, Real nearPlane, 
01332         Real farPlane, Matrix4& dest, bool forGpuProgram)
01333     {
01334             Real thetaY = Math::AngleUnitsToRadians(fovy / 2.0f);
01335             Real sinThetaY = Math::Sin(thetaY);
01336             Real thetaX = thetaY * aspect;
01337             Real sinThetaX = Math::Sin(thetaX);
01338             Real w = 1.0 / (sinThetaX * nearPlane);
01339             Real h = 1.0 / (sinThetaY * nearPlane);
01340             Real q;
01341             if (farPlane == 0)
01342             {
01343                 q = 0;
01344             }
01345             else
01346             {
01347                 q = 1.0 / (farPlane - nearPlane);
01348             }
01349         
01350             dest = Matrix4::ZERO;
01351             dest[0][0] = w;
01352             dest[1][1] = h;
01353             dest[2][2] = -q;
01354             dest[3][3] = 1;
01355     }
01356 
01357     void GLRenderSystem::_setRasterisationMode(SceneDetailLevel level)
01358     {
01359         GLenum glmode;
01360         switch(level)
01361         {
01362         case SDL_POINTS:
01363             glmode = GL_POINT;
01364             break;
01365         case SDL_WIREFRAME:
01366             glmode = GL_LINE;
01367             break;
01368         case SDL_SOLID:
01369             glmode = GL_FILL;
01370             break;
01371 
01372             // Deactivate the viewport clipping.
01373             glDisable(GL_SCISSOR_TEST);
01374         }
01375 
01376         glPolygonMode(GL_FRONT_AND_BACK, glmode);
01377     }
01378     //---------------------------------------------------------------------
01379     void GLRenderSystem::setStencilCheckEnabled(bool enabled)
01380     {
01381         if (enabled)
01382         {
01383             glEnable(GL_STENCIL_TEST);
01384         }
01385         else
01386         {
01387             glDisable(GL_STENCIL_TEST);
01388         }
01389     }
01390     //---------------------------------------------------------------------
01391     void GLRenderSystem::setStencilBufferParams(CompareFunction func, ulong refValue, 
01392         ulong mask, StencilOperation stencilFailOp, 
01393         StencilOperation depthFailOp, StencilOperation passOp, 
01394         bool twoSidedOperation)
01395     {
01396         if (twoSidedOperation)
01397         {
01398             if (!mCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL))
01399                 Except(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported",
01400                     "GLRenderSystem::setStencilBufferParams");
01401             glActiveStencilFaceEXT_ptr(GL_FRONT);
01402         }
01403         
01404         glStencilMask(mask);
01405         glStencilFunc(convertCompareFunction(func), refValue, mask);
01406         glStencilOp(convertStencilOp(stencilFailOp), convertStencilOp(depthFailOp), 
01407             convertStencilOp(passOp));
01408 
01409         if (twoSidedOperation)
01410         {
01411             // set everything again, inverted
01412             glActiveStencilFaceEXT_ptr(GL_BACK);
01413             glStencilMask(mask);
01414             glStencilFunc(convertCompareFunction(func), refValue, mask);
01415             glStencilOp(
01416                 convertStencilOp(stencilFailOp, true), 
01417                 convertStencilOp(depthFailOp, true), 
01418                 convertStencilOp(passOp, true));
01419             // reset
01420             glActiveStencilFaceEXT_ptr(GL_FRONT);
01421             glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
01422         }
01423         else
01424         {
01425             glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
01426         }
01427     }
01428     //---------------------------------------------------------------------
01429     GLint GLRenderSystem::convertCompareFunction(CompareFunction func) const
01430     {
01431         switch(func)
01432         {
01433         case CMPF_ALWAYS_FAIL:
01434             return GL_NEVER;
01435         case CMPF_ALWAYS_PASS:
01436             return GL_ALWAYS;
01437         case CMPF_LESS:
01438             return GL_LESS;
01439         case CMPF_LESS_EQUAL:
01440             return GL_LEQUAL;
01441         case CMPF_EQUAL:
01442             return GL_EQUAL;
01443         case CMPF_NOT_EQUAL:
01444             return GL_NOTEQUAL;
01445         case CMPF_GREATER_EQUAL:
01446             return GL_GEQUAL;
01447         case CMPF_GREATER:
01448             return GL_GREATER;
01449         };
01450         // to keep compiler happy
01451         return GL_ALWAYS;
01452     }
01453     //---------------------------------------------------------------------
01454     GLint GLRenderSystem::convertStencilOp(StencilOperation op, bool invert) const
01455     {
01456         switch(op)
01457         {
01458         case SOP_KEEP:
01459             return GL_KEEP;
01460         case SOP_ZERO:
01461             return GL_ZERO;
01462         case SOP_REPLACE:
01463             return GL_REPLACE;
01464         case SOP_INCREMENT:
01465             return invert ? GL_DECR : GL_INCR;
01466         case SOP_DECREMENT:
01467             return invert ? GL_INCR : GL_DECR;
01468         case SOP_INCREMENT_WRAP:
01469             return invert ? GL_DECR_WRAP_EXT : GL_INCR_WRAP_EXT;
01470         case SOP_DECREMENT_WRAP:
01471             return invert ? GL_INCR_WRAP_EXT : GL_DECR_WRAP_EXT;
01472         case SOP_INVERT:
01473             return GL_INVERT;
01474         };
01475         // to keep compiler happy
01476         return SOP_KEEP;
01477     }
01478     //---------------------------------------------------------------------
01479     GLuint GLRenderSystem::getCombinedMinMipFilter(void) const
01480     {
01481         switch(mMinFilter)
01482         {
01483         case FO_ANISOTROPIC:
01484         case FO_LINEAR:
01485             switch(mMipFilter)
01486             {
01487             case FO_ANISOTROPIC:
01488             case FO_LINEAR:
01489                 // linear min, linear mip
01490                 return GL_LINEAR_MIPMAP_LINEAR;
01491                 break;
01492             case FO_POINT:
01493                 // linear min, point mip
01494                 return GL_LINEAR_MIPMAP_NEAREST;
01495                 break;
01496             case FO_NONE:
01497                 // linear min, no mip
01498                 return GL_LINEAR;
01499                 break;
01500             }
01501             break;
01502         case FO_POINT:
01503         case FO_NONE:
01504             switch(mMipFilter)
01505             {
01506             case FO_ANISOTROPIC:
01507             case FO_LINEAR:
01508                 // nearest min, linear mip
01509                 return GL_NEAREST_MIPMAP_LINEAR;
01510                 break;
01511             case FO_POINT:
01512                 // nearest min, point mip
01513                 return GL_NEAREST_MIPMAP_NEAREST;
01514                 break;
01515             case FO_NONE:
01516                 // nearest min, no mip
01517                 return GL_NEAREST;
01518                 break;
01519             }
01520             break;
01521         }
01522 
01523         // should never get here
01524         return 0;
01525 
01526     }
01527     //---------------------------------------------------------------------
01528     void GLRenderSystem::_setTextureUnitFiltering(size_t unit, 
01529         FilterType ftype, FilterOptions fo)
01530     {
01531         OgreGuard( "GLRenderSystem::_setTextureUnitFiltering" );        
01532 
01533         glActiveTextureARB_ptr( GL_TEXTURE0 + unit );
01534         switch(ftype)
01535         {
01536         case FT_MIN:
01537             mMinFilter = fo;
01538             // Combine with existing mip filter
01539             glTexParameteri(
01540                 mTextureTypes[unit],
01541                 GL_TEXTURE_MIN_FILTER, 
01542                 getCombinedMinMipFilter());
01543             break;
01544         case FT_MAG:
01545             switch (fo)
01546             {
01547             case FO_ANISOTROPIC: // GL treats linear and aniso the same
01548             case FO_LINEAR:
01549                 glTexParameteri(
01550                     mTextureTypes[unit],
01551                     GL_TEXTURE_MAG_FILTER, 
01552                     GL_LINEAR);
01553                 break;
01554             case FO_POINT:
01555             case FO_NONE:
01556                 glTexParameteri(
01557                     mTextureTypes[unit],
01558                     GL_TEXTURE_MAG_FILTER, 
01559                     GL_NEAREST);
01560                 break;
01561             }
01562             break;
01563         case FT_MIP:
01564             mMipFilter = fo;
01565             // Combine with existing min filter
01566             glTexParameteri(
01567                 mTextureTypes[unit],
01568                 GL_TEXTURE_MIN_FILTER, 
01569                 getCombinedMinMipFilter());
01570             break;
01571         }
01572 
01573         glActiveTextureARB_ptr( GL_TEXTURE0 );
01574 
01575         OgreUnguard();
01576     }
01577     //---------------------------------------------------------------------
01578     GLfloat GLRenderSystem::_getCurrentAnisotropy(size_t unit)
01579     {
01580         GLfloat curAniso = 0;
01581         glGetTexParameterfv(mTextureTypes[unit], 
01582             GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso);
01583         return curAniso ? curAniso : 1;
01584     }
01585     //---------------------------------------------------------------------
01586     void GLRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
01587     {
01588        if (!mCapabilities->hasCapability(RSC_ANISOTROPY))
01589             return;
01590 
01591         GLfloat largest_supported_anisotropy = 0;
01592         glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
01593         if (maxAnisotropy > largest_supported_anisotropy)
01594             maxAnisotropy = largest_supported_anisotropy ? largest_supported_anisotropy : 1;
01595         if (_getCurrentAnisotropy(unit) != maxAnisotropy)
01596             glTexParameterf(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
01597     }
01598     //-----------------------------------------------------------------------------
01599     void GLRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm)
01600     {       
01601         // Check to see if blending is supported
01602         if(!mCapabilities->hasCapability(RSC_BLENDING))
01603             return;
01604 
01605         GLenum src1op, src2op, cmd;
01606         GLfloat cv1[4], cv2[4];
01607 
01608         if (bm.blendType == LBT_COLOUR)
01609         {
01610             cv1[0] = bm.colourArg1.r;
01611             cv1[1] = bm.colourArg1.g;
01612             cv1[2] = bm.colourArg1.b;
01613             cv1[3] = bm.colourArg1.a;
01614 
01615             cv2[0] = bm.colourArg2.r;
01616             cv2[1] = bm.colourArg2.g;
01617             cv2[2] = bm.colourArg2.b;
01618             cv2[3] = bm.colourArg2.a;
01619         }
01620 
01621         if (bm.blendType == LBT_ALPHA)
01622         {
01623             cv1[0] = 0;
01624             cv1[1] = 0;
01625             cv1[2] = 0;
01626             cv1[3] = bm.alphaArg1;
01627 
01628             cv2[0] = 0;
01629             cv2[1] = 0;
01630             cv2[2] = 0;
01631             cv2[3] = bm.alphaArg2;
01632         }
01633 
01634         switch (bm.source1)
01635         {
01636         case LBS_CURRENT:
01637             src1op = GL_PREVIOUS;
01638             break;
01639         case LBS_TEXTURE:
01640             src1op = GL_TEXTURE;
01641             break;
01642         case LBS_MANUAL:
01643             src1op = GL_CONSTANT;
01644             break;
01645         case LBS_DIFFUSE:
01646             src1op = GL_PRIMARY_COLOR;
01647             break;
01648         // XXX
01649         case LBS_SPECULAR:
01650         default:
01651             src1op = 0;
01652         }
01653 
01654         switch (bm.source2)
01655         {
01656         case LBS_CURRENT:
01657             src2op = GL_PREVIOUS;
01658             break;
01659         case LBS_TEXTURE:
01660             src2op = GL_TEXTURE;
01661             break;
01662         case LBS_MANUAL:
01663             src2op = GL_CONSTANT;
01664             break;
01665         case LBS_DIFFUSE:
01666             src2op = GL_PRIMARY_COLOR;
01667             break;
01668         // XXX
01669         case LBS_SPECULAR:
01670         default:
01671             src2op = 0;
01672         }
01673 
01674         switch (bm.operation)
01675         {
01676         case LBX_SOURCE1:
01677             cmd = GL_REPLACE;
01678             break;
01679         case LBX_SOURCE2:
01680             cmd = GL_REPLACE;
01681             break;
01682         case LBX_MODULATE:
01683             cmd = GL_MODULATE;
01684             break;
01685         case LBX_MODULATE_X2:
01686             cmd = GL_MODULATE;
01687             break;
01688         case LBX_MODULATE_X4:
01689             cmd = GL_MODULATE;
01690             break;
01691         case LBX_ADD:
01692             cmd = GL_ADD;
01693             break;
01694         case LBX_ADD_SIGNED:
01695             cmd = GL_ADD_SIGNED;
01696             break;
01697         case LBX_SUBTRACT:
01698             cmd = GL_SUBTRACT;
01699             break;
01700         case LBX_BLEND_DIFFUSE_ALPHA:
01701             cmd = GL_INTERPOLATE;
01702             break;
01703         case LBX_BLEND_TEXTURE_ALPHA:
01704             cmd = GL_INTERPOLATE;
01705             break;
01706         case LBX_BLEND_CURRENT_ALPHA:
01707             cmd = GL_INTERPOLATE;
01708             break;
01709         case LBX_DOTPRODUCT:
01710             cmd = mCapabilities->hasCapability(RSC_DOT3) 
01711                 ? GL_DOT3_RGB : GL_MODULATE;
01712             break;
01713         default:
01714             cmd = 0;
01715         }
01716 
01717         glActiveTextureARB_ptr(GL_TEXTURE0 + stage);
01718         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
01719 
01720         if (bm.blendType == LBT_COLOUR)
01721         {
01722             glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, cmd);
01723             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, src1op);
01724             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, src2op);
01725             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
01726         }
01727         else
01728         {
01729             glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, cmd);
01730             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, src1op);
01731             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, src2op);
01732             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
01733         }
01734 
01735         switch (bm.operation)
01736         {
01737           case LBX_BLEND_DIFFUSE_ALPHA:
01738             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
01739             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
01740             break;
01741           case LBX_BLEND_TEXTURE_ALPHA:
01742             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
01743             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE);
01744             break;
01745           case LBX_BLEND_CURRENT_ALPHA:
01746             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);
01747             glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS);
01748             break;
01749           default:
01750             break;
01751         };
01752 
01753         switch (bm.operation)
01754         {
01755           case LBX_MODULATE_X2:
01756             glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? 
01757                 GL_RGB_SCALE : GL_ALPHA_SCALE, 2);
01758             break;
01759           case LBX_MODULATE_X4:
01760             glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? 
01761                 GL_RGB_SCALE : GL_ALPHA_SCALE, 4);
01762             break;
01763           default:
01764             glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? 
01765                 GL_RGB_SCALE : GL_ALPHA_SCALE, 1);
01766             break;
01767         }
01768 
01769         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
01770         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
01771         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
01772         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
01773         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
01774         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
01775         if(bm.source1 == LBS_MANUAL)
01776             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv1);
01777         if (bm.source2 == LBS_MANUAL)
01778             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv2);
01779 
01780         glActiveTextureARB_ptr(GL_TEXTURE0);
01781     }
01782     //---------------------------------------------------------------------
01783     void GLRenderSystem::setGLLightPositionDirection(Light* lt, size_t lightindex)
01784     {
01785         // Set position / direction
01786         Vector4 vec;
01787         // Use general 4D vector which is the same as GL's approach
01788         vec = lt->getAs4DVector();
01789 
01790         glLightfv(GL_LIGHT0 + lightindex, GL_POSITION, vec.val);
01791         // Set spotlight direction
01792         if (lt->getType() == Light::LT_SPOTLIGHT)
01793         {
01794             vec = lt->getDerivedDirection();
01795             vec.w = 0.0; 
01796             glLightfv(GL_LIGHT0 + lightindex, GL_SPOT_DIRECTION, vec.val);
01797         }
01798     }
01799     //---------------------------------------------------------------------
01800     void GLRenderSystem::setVertexDeclaration(VertexDeclaration* decl)
01801     {
01802     }
01803     //---------------------------------------------------------------------
01804     void GLRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
01805     {
01806     }
01807     //---------------------------------------------------------------------
01808     void GLRenderSystem::_render(const RenderOperation& op)
01809     {
01810         // Guard
01811         OgreGuard ("GLRenderSystem::_render");
01812         // Call super class
01813         RenderSystem::_render(op);
01814 
01815         void* pBufferData = 0;
01816         
01817         const VertexDeclaration::VertexElementList& decl = 
01818             op.vertexData->vertexDeclaration->getElements();
01819         VertexDeclaration::VertexElementList::const_iterator elem, elemEnd;
01820         elemEnd = decl.end();
01821 
01822         for (elem = decl.begin(); elem != elemEnd; ++elem)
01823         {
01824             HardwareVertexBufferSharedPtr vertexBuffer = 
01825                 op.vertexData->vertexBufferBinding->getBuffer(elem->getSource());
01826             if(mCapabilities->hasCapability(RSC_VBO))
01827             {
01828                 glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, 
01829                     static_cast<const GLHardwareVertexBuffer*>(vertexBuffer.get())->getGLBufferId());
01830                 pBufferData = VBO_BUFFER_OFFSET(elem->getOffset());
01831             }
01832             else
01833             {
01834                 pBufferData = static_cast<const GLDefaultHardwareVertexBuffer*>(vertexBuffer.get())->getDataPtr(elem->getOffset());
01835             }
01836 
01837             unsigned int i = 0;
01838 
01839             switch(elem->getSemantic())
01840             {
01841             case VES_POSITION:
01842                 glVertexPointer(VertexElement::getTypeCount(
01843                     elem->getType()), 
01844                     GLHardwareBufferManager::getGLType(elem->getType()), 
01845                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01846                     pBufferData);
01847                 glEnableClientState( GL_VERTEX_ARRAY );
01848                 break;
01849             case VES_NORMAL:
01850                 glNormalPointer(
01851                     GLHardwareBufferManager::getGLType(elem->getType()), 
01852                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01853                     pBufferData);
01854                 glEnableClientState( GL_NORMAL_ARRAY );
01855                 break;
01856             case VES_DIFFUSE:
01857                 glColorPointer(4, 
01858                     GLHardwareBufferManager::getGLType(elem->getType()), 
01859                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01860                     pBufferData);
01861                 glEnableClientState( GL_COLOR_ARRAY );
01862                 break;
01863             case VES_SPECULAR:
01864                 glSecondaryColorPointerEXT_ptr(4, 
01865                     GLHardwareBufferManager::getGLType(elem->getType()), 
01866                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01867                     pBufferData);
01868                 glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
01869                 break;
01870             case VES_TEXTURE_COORDINATES:
01871 
01872                 for (i = 0; i < mCapabilities->getNumTextureUnits(); i++)
01873                 {
01874                     // Only set this texture unit's texcoord pointer if it
01875                     // is supposed to be using this element's index
01876                     if (mTextureCoordIndex[i] == elem->getIndex())
01877                     {
01878                         glClientActiveTextureARB_ptr(GL_TEXTURE0 + i);
01879                         glTexCoordPointer(
01880                             VertexElement::getTypeCount(elem->getType()), 
01881                             GLHardwareBufferManager::getGLType(elem->getType()),
01882                             static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01883                                 pBufferData);
01884                         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
01885                     }
01886                 }
01887                 break;
01888             case VES_BLEND_INDICES:
01889                 assert(mCapabilities->hasCapability(RSC_VERTEX_PROGRAM));
01890                 glVertexAttribPointerARB_ptr(
01891                     7, // matrix indices are vertex attribute 7 (no def?)
01892                     VertexElement::getTypeCount(elem->getType()), 
01893                     GLHardwareBufferManager::getGLType(elem->getType()), 
01894                     GL_FALSE, // normalisation disabled
01895                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01896                     pBufferData);
01897                 glEnableVertexAttribArrayARB_ptr(7);
01898                 break;
01899             case VES_BLEND_WEIGHTS:
01900                 assert(mCapabilities->hasCapability(RSC_VERTEX_PROGRAM));
01901                 glVertexAttribPointerARB_ptr(
01902                     1, // weights are vertex attribute 1 (no def?)
01903                     VertexElement::getTypeCount(elem->getType()), 
01904                     GLHardwareBufferManager::getGLType(elem->getType()), 
01905                     GL_FALSE, // normalisation disabled
01906                     static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
01907                     pBufferData);
01908                 glEnableVertexAttribArrayARB_ptr(1);
01909                 break;
01910             default:
01911                 break;
01912             };
01913 
01914         }
01915 
01916         glClientActiveTextureARB_ptr(GL_TEXTURE0);
01917 
01918         // Find the correct type to render
01919         GLint primType;
01920         switch (op.operationType)
01921         {
01922         case RenderOperation::OT_POINT_LIST:
01923             primType = GL_POINTS;
01924             break;
01925         case RenderOperation::OT_LINE_LIST:
01926             primType = GL_LINES;
01927             break;
01928         case RenderOperation::OT_LINE_STRIP:
01929             primType = GL_LINE_STRIP;
01930             break;
01931         case RenderOperation::OT_TRIANGLE_LIST:
01932             primType = GL_TRIANGLES;
01933             break;
01934         case RenderOperation::OT_TRIANGLE_STRIP:
01935             primType = GL_TRIANGLE_STRIP;
01936             break;
01937         case RenderOperation::OT_TRIANGLE_FAN:
01938             primType = GL_TRIANGLE_FAN;
01939             break;
01940         }
01941 
01942         if (op.useIndexes)
01943         {
01944             if(mCapabilities->hasCapability(RSC_VBO))
01945             {
01946                 glBindBufferARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, 
01947                     static_cast<GLHardwareIndexBuffer*>(
01948                         op.indexData->indexBuffer.get())->getGLBufferId());
01949 
01950                 pBufferData = VBO_BUFFER_OFFSET(
01951                     op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
01952             }
01953             else
01954             {
01955                 pBufferData = static_cast<GLDefaultHardwareIndexBuffer*>(
01956                     op.indexData->indexBuffer.get())->getDataPtr(
01957                         op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
01958             }
01959 
01960             GLenum indexType = (op.indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
01961 
01962             glDrawRangeElements(primType, op.indexData->indexStart, 
01963                 op.indexData->indexStart + op.indexData->indexCount - 1,
01964                 op.indexData->indexCount, indexType, pBufferData);
01965 
01966         }
01967         else
01968         {
01969             glDrawArrays(primType, op.vertexData->vertexStart,
01970                 op.vertexData->vertexCount);
01971         }
01972 
01973         glDisableClientState( GL_VERTEX_ARRAY );
01974         glDisableClientState( GL_TEXTURE_COORD_ARRAY );
01975         glDisableClientState( GL_NORMAL_ARRAY );
01976         glDisableClientState( GL_COLOR_ARRAY );
01977         glDisableClientState( GL_SECONDARY_COLOR_ARRAY );
01978         if (mCapabilities->hasCapability(RSC_VERTEX_PROGRAM))
01979         {
01980             glDisableVertexAttribArrayARB_ptr(7); // disable indices
01981             glDisableVertexAttribArrayARB_ptr(1); // disable weights
01982         }
01983         glColor4f(1,1,1,1);
01984 
01985         // UnGuard
01986         OgreUnguard();
01987     }
01988     //---------------------------------------------------------------------
01989     void GLRenderSystem::setNormaliseNormals(bool normalise)
01990     {
01991         if (normalise)
01992             glEnable(GL_NORMALIZE);
01993         else
01994             glDisable(GL_NORMALIZE);
01995 
01996     }
01997     //---------------------------------------------------------------------
01998     void GLRenderSystem::bindGpuProgram(GpuProgram* prg)
01999     {
02000         GLGpuProgram* glprg = static_cast<GLGpuProgram*>(prg);
02001         glprg->bindProgram();
02002         if (glprg->getType() == GPT_VERTEX_PROGRAM)
02003         {
02004             mCurrentVertexProgram = glprg;
02005         }
02006         else
02007         {
02008             mCurrentFragmentProgram = glprg;
02009         }
02010     }
02011     //---------------------------------------------------------------------
02012     void GLRenderSystem::unbindGpuProgram(GpuProgramType gptype)
02013     {
02014 
02015         if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram)
02016         {
02017             mCurrentVertexProgram->unbindProgram();
02018             mCurrentVertexProgram = 0;
02019         }
02020         else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram)
02021         {
02022             mCurrentFragmentProgram->unbindProgram();
02023             mCurrentFragmentProgram = 0;
02024         }
02025 
02026 
02027     }
02028     //---------------------------------------------------------------------
02029     void GLRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params)
02030     {
02031         if (gptype == GPT_VERTEX_PROGRAM)
02032         {
02033             mCurrentVertexProgram->bindProgramParameters(params);
02034         }
02035         else
02036         {
02037             mCurrentFragmentProgram->bindProgramParameters(params);
02038         }
02039     }
02040     //---------------------------------------------------------------------
02041     void GLRenderSystem::setClipPlanes(const PlaneList& clipPlanes)
02042     {
02043         size_t i;
02044         size_t numClipPlanes;
02045         GLdouble clipPlane[4];
02046 
02047         numClipPlanes = clipPlanes.size();
02048         for (i = 0; i < numClipPlanes; ++i)
02049         {
02050             GLenum clipPlaneId = static_cast<GLenum>(GL_CLIP_PLANE0 + i);
02051             const Plane& plane = clipPlanes[i];
02052 
02053             if (i >= GL_MAX_CLIP_PLANES)
02054             {
02055                 Except(0, "Unable to set clip plane", 
02056                     "GLRenderSystem::setClipPlanes");
02057             }
02058 
02059             clipPlane[0] = plane.normal.x;
02060             clipPlane[1] = plane.normal.y;
02061             clipPlane[2] = plane.normal.z;
02062             clipPlane[3] = -plane.d;
02063 
02064             glClipPlane(clipPlaneId, clipPlane);
02065             glEnable(clipPlaneId);
02066         }
02067 
02068             // disable remaining clip planes
02069         for ( ; i < 6/*GL_MAX_CLIP_PLANES*/; ++i)
02070         {
02071             glDisable(static_cast<GLenum>(GL_CLIP_PLANE0 + i));
02072         }
02073     }
02074     //---------------------------------------------------------------------
02075     void GLRenderSystem::setScissorTest(bool enabled, size_t left, 
02076         size_t top, size_t right, size_t bottom)
02077     {
02078         //  GL measures from the bottom, not the top
02079         size_t targetHeight = mActiveRenderTarget->getHeight();
02080         // Calculate the "lower-left" corner of the viewport
02081         GLsizei w, h, x, y;
02082 
02083         if (enabled)
02084         {
02085             glEnable(GL_SCISSOR_TEST);
02086             // NB GL uses width / height rather than right / bottom
02087             x = left;
02088             y = targetHeight - bottom;
02089             w = right - left;
02090             h = bottom - top;
02091             glScissor(x, y, w, h);
02092         }
02093         else
02094         {
02095             glDisable(GL_SCISSOR_TEST);
02096             // GL requires you to reset the scissor when disabling
02097             w = mActiveViewport->getActualWidth();
02098             h = mActiveViewport->getActualHeight();
02099             x = mActiveViewport->getActualLeft();
02100             y = targetHeight - mActiveViewport->getActualTop() - h;
02101             glScissor(x, y, w, h);
02102         }
02103     }
02104     //---------------------------------------------------------------------
02105     void GLRenderSystem::clearFrameBuffer(unsigned int buffers, 
02106         const ColourValue& colour, Real depth, unsigned short stencil)
02107     {
02108 
02109         GLbitfield flags = 0;
02110         if (buffers & FBT_COLOUR)
02111         {
02112             flags |= GL_COLOR_BUFFER_BIT;
02113         }
02114         if (buffers & FBT_DEPTH)
02115         {
02116             flags |= GL_DEPTH_BUFFER_BIT;
02117         }
02118         if (buffers & FBT_STENCIL)
02119         {
02120             flags |= GL_STENCIL_BUFFER_BIT;
02121         }
02122 
02123 
02124         // Enable depth & colour buffer for writing if it isn't
02125 
02126         if (!mDepthWrite)
02127         {
02128             glDepthMask( GL_TRUE );
02129         }
02130         bool colourMask = !mColourWrite[0] || !mColourWrite[1] 
02131         || !mColourWrite[2] || mColourWrite[3]; 
02132         if (colourMask)
02133         {
02134             glColorMask(true, true, true, true);
02135         }
02136         // Set values
02137         glClearColor(colour.r, colour.g, colour.b, colour.a);
02138         glClearDepth(depth);
02139         glClearStencil(stencil);
02140         // Clear buffers
02141         glClear(flags);
02142         // Reset depth write state if appropriate
02143         // Enable depth buffer for writing if it isn't
02144         if (!mDepthWrite)
02145         {
02146             glDepthMask( GL_FALSE );
02147         }
02148         if (colourMask)
02149         {
02150             glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
02151         }
02152 
02153     }
02154     // ------------------------------------------------------------------
02155     void GLRenderSystem::_makeProjectionMatrix(Real left, Real right, 
02156         Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, 
02157         bool forGpuProgram)
02158     {
02159         Real width = right - left;
02160         Real height = top - bottom;
02161         Real q, qn;
02162         if (farPlane == 0)
02163         {
02164             // Infinite far plane
02165             q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
02166             qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
02167         }
02168         else
02169         {
02170             q = -(farPlane + nearPlane) / (farPlane - nearPlane);
02171             qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
02172         }
02173         dest = Matrix4::ZERO;
02174         dest[0][0] = 2 * nearPlane / width;
02175         dest[0][2] = (right+left) / width;
02176         dest[1][1] = 2 * nearPlane / height;
02177         dest[1][2] = (top+bottom) / height;
02178         dest[2][2] = q;
02179         dest[2][3] = qn;
02180         dest[3][2] = -1;
02181     }
02182 
02183     // ------------------------------------------------------------------
02184     void GLRenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D)
02185     {
02186         if (mClipPlanes.size() < index+1)
02187             mClipPlanes.resize(index+1);
02188         mClipPlanes[index] = Vector4 (A, B, C, D);
02189         GLdouble plane[4] = { A, B, C, D };
02190         glClipPlane (GL_CLIP_PLANE0 + index, plane);
02191     }
02192 
02193     // ------------------------------------------------------------------
02194     void GLRenderSystem::setGLClipPlanes() const
02195     {
02196         size_t size = mClipPlanes.size();
02197         for (size_t i=0; i<size; i++)
02198         {
02199             const Vector4 &p = mClipPlanes[i];
02200             GLdouble plane[4] = { p.x, p.y, p.z, p.w };
02201             glClipPlane (GL_CLIP_PLANE0 + i, plane);
02202         }
02203     }
02204 
02205     // ------------------------------------------------------------------
02206     void GLRenderSystem::enableClipPlane (ushort index, bool enable)
02207     {
02208         glEnable (GL_CLIP_PLANE0 + index);
02209     }
02210     //---------------------------------------------------------------------
02211     HardwareOcclusionQuery* GLRenderSystem::createHardwareOcclusionQuery(void)
02212     {
02213         return new GLHardwareOcclusionQuery(); 
02214     }
02215 
02216 
02217 
02218 }

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:13 2004