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

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:26 2004