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

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:12 2004