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