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