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