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