source: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLRenderSystem.cpp @ 115

Revision 115, 93.0 KB checked in by mattausch, 19 years ago (diff)

added depth pass algorithm + delayed transparent object rendering (so depth ordering is right)

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://ogre.sourceforge.net/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.s
23-----------------------------------------------------------------------------
24*/
25
26
27#include "OgreGLRenderSystem.h"
28#include "OgreRenderSystem.h"
29#include "OgreLogManager.h"
30#include "OgreStringConverter.h"
31#include "OgreLight.h"
32#include "OgreCamera.h"
33#include "OgreGLTextureManager.h"
34#include "OgreGLHardwareVertexBuffer.h"
35#include "OgreGLHardwareIndexBuffer.h"
36#include "OgreGLDefaultHardwareBufferManager.h"
37#include "OgreGLUtil.h"
38#include "OgreGLGpuProgram.h"
39#include "OgreGLGpuNvparseProgram.h"
40#include "ATI_FS_GLGpuProgram.h"
41#include "OgreGLGpuProgramManager.h"
42#include "OgreException.h"
43#include "OgreGLATIFSInit.h"
44#include "OgreGLSLExtSupport.h"
45#include "OgreGLHardwareOcclusionQuery.h"
46#include "OgreGLContext.h"
47
48
49#ifdef HAVE_CONFIG_H
50#   include "config.h"
51#endif
52
53// Convenience macro from ARB_vertex_buffer_object spec
54#define VBO_BUFFER_OFFSET(i) ((char *)NULL + (i))
55
56// Pointers to extension functions
57GL_ActiveTextureARB_Func glActiveTextureARB_ptr;
58GL_ClientActiveTextureARB_Func glClientActiveTextureARB_ptr;
59GL_SecondaryColorPointerEXT_Func glSecondaryColorPointerEXT_ptr;
60GL_SecondaryColor3fEXT_Func glSecondaryColor3fEXT_ptr;
61GL_GenBuffersARB_Func glGenBuffersARB_ptr;
62GL_BindBufferARB_Func glBindBufferARB_ptr;
63GL_DeleteBuffersARB_Func glDeleteBuffersARB_ptr;
64GL_MapBufferARB_Func glMapBufferARB_ptr;
65GL_UnmapBufferARB_Func glUnmapBufferARB_ptr;
66GL_BufferDataARB_Func glBufferDataARB_ptr;
67GL_BufferSubDataARB_Func glBufferSubDataARB_ptr;
68GL_GetBufferSubDataARB_Func glGetBufferSubDataARB_ptr;
69GL_GenProgramsARB_Func glGenProgramsARB_ptr;
70GL_DeleteProgramsARB_Func glDeleteProgramsARB_ptr;
71GL_BindProgramARB_Func glBindProgramARB_ptr;
72GL_ProgramStringARB_Func glProgramStringARB_ptr;
73GL_ProgramLocalParameter4fvARB_Func glProgramLocalParameter4fvARB_ptr;
74GL_ProgramParameter4fvNV_Func glProgramParameter4fvNV_ptr;
75GL_VertexAttribPointerARB_Func glVertexAttribPointerARB_ptr;
76GL_EnableVertexAttribArrayARB_Func glEnableVertexAttribArrayARB_ptr;
77GL_DisableVertexAttribArrayARB_Func glDisableVertexAttribArrayARB_ptr;
78GL_CombinerStageParameterfvNV_Func glCombinerStageParameterfvNV_ptr;
79GL_CombinerParameterfvNV_Func glCombinerParameterfvNV_ptr;
80GL_CombinerParameteriNV_Func glCombinerParameteriNV_ptr;
81GL_GetProgramivARB_Func glGetProgramivARB_ptr;
82GL_LoadProgramNV_Func glLoadProgramNV_ptr;
83GL_CombinerInputNV_Func glCombinerInputNV_ptr;
84GL_CombinerOutputNV_Func glCombinerOutputNV_ptr;
85GL_FinalCombinerInputNV_Func glFinalCombinerInputNV_ptr;
86GL_TrackMatrixNV_Func glTrackMatrixNV_ptr;
87PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glCompressedTexImage1DARB_ptr;
88PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB_ptr;
89PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glCompressedTexImage3DARB_ptr;
90PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glCompressedTexSubImage1DARB_ptr;
91PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glCompressedTexSubImage2DARB_ptr;
92PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glCompressedTexSubImage3DARB_ptr;
93PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB_ptr;
94GL_ActiveStencilFaceEXT_Func glActiveStencilFaceEXT_ptr;
95GL_GenOcclusionQueriesNV_Func glGenOcclusionQueriesNV_ptr;     
96GL_DeleteOcclusionQueriesNV_Func glDeleteOcclusionQueriesNV_ptr;
97GL_BeginOcclusionQueryNV_Func glBeginOcclusionQueryNV_ptr;
98GL_EndOcclusionQueryNV_Func glEndOcclusionQueryNV_ptr;
99GL_GetOcclusionQueryuivNV_Func glGetOcclusionQueryuivNV_ptr;
100GL_GenQueriesARB_Func glGenQueriesARB_ptr;
101GL_DeleteQueriesARB_Func glDeleteQueriesARB_ptr;
102GL_BeginQueryARB_Func glBeginQueryARB_ptr;
103GL_EndQueryARB_Func glEndQueryARB_ptr;
104#ifdef GTP_VISIBILITY_MODIFIED_OGRE
105GL_GetQueryivARB_Func glGetQueryivARB_ptr;
106GL_GetQueryObjectivARB_Func glGetQueryObjectivARB_ptr;
107#endif // GTP_VISIBILITY_MODIFIED_OGRE
108GL_GetQueryObjectuivARB_Func glGetQueryObjectuivARB_ptr;
109
110namespace Ogre {
111
112    // Callback function used when registering GLGpuPrograms
113    GpuProgram* createGLArbGpuProgram(ResourceManager* creator,
114        const String& name, ResourceHandle handle,
115        const String& group, bool isManual, ManualResourceLoader* loader,
116        GpuProgramType gptype, const String& syntaxCode)
117    {
118        GLArbGpuProgram* ret = new GLArbGpuProgram(
119            creator, name, handle, group, isManual, loader);
120        ret->setType(gptype);
121        ret->setSyntaxCode(syntaxCode);
122        return ret;
123    }
124
125    GpuProgram* createGLGpuNvparseProgram(ResourceManager* creator,
126        const String& name, ResourceHandle handle,
127        const String& group, bool isManual, ManualResourceLoader* loader,
128        GpuProgramType gptype, const String& syntaxCode)
129    {
130        GLGpuNvparseProgram* ret = new GLGpuNvparseProgram(
131            creator, name, handle, group, isManual, loader);
132        ret->setType(gptype);
133        ret->setSyntaxCode(syntaxCode);
134        return ret;
135    }
136
137    GpuProgram* createGL_ATI_FS_GpuProgram(ResourceManager* creator,
138        const String& name, ResourceHandle handle,
139        const String& group, bool isManual, ManualResourceLoader* loader,
140        GpuProgramType gptype, const String& syntaxCode)
141        {
142
143        ATI_FS_GLGpuProgram* ret = new ATI_FS_GLGpuProgram(
144            creator, name, handle, group, isManual, loader);
145        ret->setType(gptype);
146        ret->setSyntaxCode(syntaxCode);
147        return ret;
148        }
149
150    GLRenderSystem::GLRenderSystem()
151      : mExternalWindowHandle(0), mDepthWrite(true), mHardwareBufferManager(0),
152        mGpuProgramManager(0)
153    {
154        size_t i;
155
156        OgreGuard( "GLRenderSystem::GLRenderSystem" );
157
158        LogManager::getSingleton().logMessage(getName() + " created.");
159
160        // Get our GLSupport
161        mGLSupport = getGLSupport();
162
163        for( i=0; i<MAX_LIGHTS; i++ )
164            mLights[i] = NULL;
165
166        mWorldMatrix = Matrix4::IDENTITY;
167        mViewMatrix = Matrix4::IDENTITY;
168       
169        initConfigOptions();
170
171        mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
172
173        for (i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; i++)
174        {
175            mTextureCoordIndex[i] = 0;
176        }
177
178        for (i = 0; i < OGRE_MAX_TEXTURE_LAYERS; i++)
179        {
180            mTextureTypes[i] = 0;
181        }
182
183        mActiveRenderTarget = 0;
184        mCurrentContext = 0;
185        mMainContext = 0;
186
187        mGLInitialized = false;
188
189        glActiveTextureARB_ptr = 0;
190        glClientActiveTextureARB_ptr = 0;
191        glSecondaryColorPointerEXT_ptr = 0;
192        glSecondaryColor3fEXT_ptr = 0;
193        glGenBuffersARB_ptr = 0;
194        glBindBufferARB_ptr = 0;
195        glDeleteBuffersARB_ptr = 0;
196        glMapBufferARB_ptr = 0;
197        glUnmapBufferARB_ptr = 0;
198        glBufferDataARB_ptr = 0;
199        glBufferSubDataARB_ptr = 0;
200        glGetBufferSubDataARB_ptr = 0;
201        glGenProgramsARB_ptr = 0;
202        glDeleteProgramsARB_ptr = 0;
203        glBindProgramARB_ptr = 0;
204        glProgramStringARB_ptr = 0;
205        glProgramLocalParameter4fvARB_ptr = 0;
206        glProgramParameter4fvNV_ptr = 0;
207        glCombinerStageParameterfvNV_ptr = 0;
208        glCombinerParameterfvNV_ptr = 0;
209        glCombinerParameteriNV_ptr = 0;
210        glGetProgramivARB_ptr = 0;
211        glLoadProgramNV_ptr = 0;
212        glCombinerInputNV_ptr = 0;
213        glCombinerOutputNV_ptr = 0;
214        glFinalCombinerInputNV_ptr = 0;
215        glTrackMatrixNV_ptr = 0;
216        glActiveStencilFaceEXT_ptr = 0;
217        glGenOcclusionQueriesNV_ptr = 0;
218        glDeleteOcclusionQueriesNV_ptr = 0;
219        glBeginOcclusionQueryNV_ptr = 0;
220        glEndOcclusionQueryNV_ptr = 0;
221        glGetOcclusionQueryuivNV_ptr = 0;
222                glGenQueriesARB_ptr = 0;
223                glDeleteQueriesARB_ptr = 0;
224                glBeginQueryARB_ptr = 0;
225                glEndQueryARB_ptr = 0;
226#ifdef GTP_VISIBILITY_MODIFIED_OGRE
227                glGetQueryivARB_ptr = 0;
228                glGetQueryObjectivARB_ptr = 0;
229#endif // GTP_VISIBILITY_MODIFIED_OGRE
230                glGetQueryObjectuivARB_ptr = 0;
231
232        mCurrentLights = 0;
233        mMinFilter = FO_LINEAR;
234        mMipFilter = FO_POINT;
235        mCurrentVertexProgram = 0;
236        mCurrentFragmentProgram = 0;
237
238        mClipPlanes.reserve(6);
239
240        OgreUnguard();
241    }
242
243    GLRenderSystem::~GLRenderSystem()
244    {
245        shutdown();
246
247        // Destroy render windows
248        RenderTargetMap::iterator i;
249        for (i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
250        {
251            delete i->second;
252        }
253        mRenderTargets.clear();
254
255        if (mTextureManager)
256            delete mTextureManager;
257
258        delete mCapabilities;
259        delete mGLSupport;
260    }
261
262    const String& GLRenderSystem::getName(void) const
263    {
264        static String strName("OpenGL Rendering Subsystem");
265        return strName;
266    }
267
268    void GLRenderSystem::initConfigOptions(void)
269    {
270        OgreGuard("GLRenderSystem::initConfigOptions");
271        mGLSupport->addConfig();
272        OgreUnguard();
273    }
274   
275    ConfigOptionMap& GLRenderSystem::getConfigOptions(void)
276    {
277        return mGLSupport->getConfigOptions();
278    }
279
280    void GLRenderSystem::setConfigOption(const String &name, const String &value)
281    {
282        mGLSupport->setConfigOption(name, value);
283    }
284
285    String GLRenderSystem::validateConfigOptions(void)
286    {
287        // XXX Return an error string if something is invalid
288        return mGLSupport->validateConfig();
289    }
290
291    RenderWindow* GLRenderSystem::initialise(bool autoCreateWindow, const String& windowTitle)
292    {
293        mGLSupport->start();
294       
295                RenderWindow* autoWindow = mGLSupport->createWindow(autoCreateWindow, this, windowTitle);
296
297
298        _setCullingMode( mCullingMode );
299       
300        return autoWindow;
301    }
302
303    void GLRenderSystem::initGL(void)
304    {
305        mGLSupport->initialiseExtensions();
306
307        LogManager::getSingleton().logMessage(
308            "***************************\n"
309            "*** GL Renderer Started ***\n"
310            "***************************");
311
312
313        // Check for hardware mipmapping support.
314        // Note: This is disabled for ATI cards until they fix their drivers
315        if(mGLSupport->getGLVendor() != "ATI" &&
316            (mGLSupport->checkMinGLVersion("1.4.0") ||
317             mGLSupport->checkExtension("GL_SGIS_generate_mipmap")))
318        {
319            mCapabilities->setCapability(RSC_AUTOMIPMAP);
320        }
321
322        // Check for blending support
323        if(mGLSupport->checkMinGLVersion("1.3.0") ||
324            mGLSupport->checkExtension("GL_ARB_texture_env_combine") ||
325            mGLSupport->checkExtension("GL_EXT_texture_env_combine"))
326        {
327            mCapabilities->setCapability(RSC_BLENDING);
328        }
329
330        // Check for Multitexturing support and set number of texture units
331        if(mGLSupport->checkMinGLVersion("1.3.0") ||
332            mGLSupport->checkExtension("GL_ARB_multitexture"))
333        {
334            GLint units;
335            glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
336
337            mCapabilities->setNumTextureUnits(units);
338        }
339        else
340        {
341            // If no multitexture support then set one texture unit
342            mCapabilities->setNumTextureUnits(1);
343        }
344           
345        // Check for Anisotropy support
346        if(mGLSupport->checkExtension("GL_EXT_texture_filter_anisotropic"))
347        {
348            mCapabilities->setCapability(RSC_ANISOTROPY);
349        }
350
351        // Check for DOT3 support
352        if(mGLSupport->checkMinGLVersion("1.3.0") ||
353            mGLSupport->checkExtension("GL_ARB_texture_env_dot3") ||
354            mGLSupport->checkExtension("GL_EXT_texture_env_dot3"))
355        {
356            mCapabilities->setCapability(RSC_DOT3);
357        }
358
359        // Check for cube mapping
360        if(mGLSupport->checkMinGLVersion("1.3.0") ||
361            mGLSupport->checkExtension("GL_ARB_texture_cube_map") ||
362            mGLSupport->checkExtension("GL_EXT_texture_cube_map"))
363        {
364            mCapabilities->setCapability(RSC_CUBEMAPPING);
365        }
366       
367        // Check for hardware stencil support and set bit depth
368        GLint stencil;
369        glGetIntegerv(GL_STENCIL_BITS,&stencil);
370
371        if(stencil)
372        {
373            mCapabilities->setCapability(RSC_HWSTENCIL);
374            mCapabilities->setStencilBufferBitDepth(stencil);
375        }
376
377        // Check for VBO support
378        if(mGLSupport->checkExtension("GL_ARB_vertex_buffer_object"))
379        {
380            mCapabilities->setCapability(RSC_VBO);
381
382            mHardwareBufferManager = new GLHardwareBufferManager;
383        }
384        else
385        {
386            mHardwareBufferManager = new GLDefaultHardwareBufferManager;
387        }
388
389        // XXX Need to check for nv2 support and make a program manager for it
390        // XXX Probably nv1 as well for older cards
391        // GPU Program Manager setup
392        mGpuProgramManager = new GLGpuProgramManager();
393
394                if(mGLSupport->checkExtension("GL_ARB_vertex_program"))
395        {
396            mCapabilities->setCapability(RSC_VERTEX_PROGRAM);
397
398            // Vertex Program Properties
399            mCapabilities->setMaxVertexProgramVersion("arbvp1");
400            mCapabilities->setVertexProgramConstantBoolCount(0);
401            mCapabilities->setVertexProgramConstantIntCount(0);
402            mCapabilities->setVertexProgramConstantFloatCount(
403                GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
404
405            mGpuProgramManager->_pushSyntaxCode("arbvp1");
406            mGpuProgramManager->registerProgramFactory("arbvp1", createGLArbGpuProgram);
407        }
408
409        if (mGLSupport->checkExtension("GL_NV_register_combiners2") &&
410            mGLSupport->checkExtension("GL_NV_texture_shader"))
411        {
412            mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
413            mCapabilities->setMaxFragmentProgramVersion("fp20");
414
415            mGpuProgramManager->_pushSyntaxCode("fp20");
416            mGpuProgramManager->registerProgramFactory("fp20", createGLGpuNvparseProgram);
417        }
418
419
420                // NFZ - check for ATI fragment shader support
421                if (mGLSupport->checkExtension("GL_ATI_fragment_shader"))
422                {
423            mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
424            mCapabilities->setMaxFragmentProgramVersion("ps_1_4");
425            // no boolean params allowed
426            mCapabilities->setFragmentProgramConstantBoolCount(0);
427            // no integer params allowed
428            mCapabilities->setFragmentProgramConstantIntCount(0);
429
430                        // only 8 Vector4 constant floats supported
431            mCapabilities->setFragmentProgramConstantFloatCount(8);
432
433            mGpuProgramManager->_pushSyntaxCode("ps_1_4");
434            mGpuProgramManager->_pushSyntaxCode("ps_1_3");
435            mGpuProgramManager->_pushSyntaxCode("ps_1_2");
436            mGpuProgramManager->_pushSyntaxCode("ps_1_1");
437
438            mGpuProgramManager->registerProgramFactory("ps_1_4", createGL_ATI_FS_GpuProgram);
439            mGpuProgramManager->registerProgramFactory("ps_1_3", createGL_ATI_FS_GpuProgram);
440            mGpuProgramManager->registerProgramFactory("ps_1_2", createGL_ATI_FS_GpuProgram);
441            mGpuProgramManager->registerProgramFactory("ps_1_1", createGL_ATI_FS_GpuProgram);
442                }
443
444
445        if (mGLSupport->checkExtension("GL_ARB_fragment_program"))
446        {
447            mCapabilities->setCapability(RSC_FRAGMENT_PROGRAM);
448            // Fragment Program Properties
449            mCapabilities->setMaxFragmentProgramVersion("arbfp1");
450            mCapabilities->setFragmentProgramConstantBoolCount(0);
451            mCapabilities->setFragmentProgramConstantIntCount(0);
452            mCapabilities->setFragmentProgramConstantFloatCount(
453                GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
454
455            mGpuProgramManager->_pushSyntaxCode("arbfp1");
456            mGpuProgramManager->registerProgramFactory("arbfp1", createGLArbGpuProgram);
457        }
458
459                // NFZ - check if GLSL is supported
460                if ( mGLSupport->checkExtension("GL_ARB_shading_language_100") &&
461                         mGLSupport->checkExtension("GL_ARB_shader_objects") &&
462                         mGLSupport->checkExtension("GL_ARB_fragment_shader") &&
463                         mGLSupport->checkExtension("GL_ARB_vertex_shader") )
464                {
465                        // NFZ - check for GLSL vertex and fragment shader support successful
466            mGpuProgramManager->_pushSyntaxCode("glsl");
467                        LogManager::getSingleton().logMessage("GLSL support detected");
468                }
469
470                // Check for texture compression
471        if(mGLSupport->checkMinGLVersion("1.3.0") ||
472            mGLSupport->checkExtension("GL_ARB_texture_compression"))
473        {   
474            mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION);
475         
476            // Check for dxt compression
477            if(mGLSupport->checkExtension("GL_EXT_texture_compression_s3tc"))
478            {
479                mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
480            }
481            // Check for vtc compression
482            if(mGLSupport->checkExtension("GL_NV_texture_compression_vtc"))
483            {
484                mCapabilities->setCapability(RSC_TEXTURE_COMPRESSION_VTC);
485            }
486        }
487
488        // Scissor test is standard in GL 1.2 (is it emulated on some cards though?)
489        mCapabilities->setCapability(RSC_SCISSOR_TEST);
490                // As are user clipping planes
491                mCapabilities->setCapability(RSC_USER_CLIP_PLANES);
492
493        // 2-sided stencil?
494        if (mGLSupport->checkExtension("GL_EXT_stencil_two_side"))
495        {
496            mCapabilities->setCapability(RSC_TWO_SIDED_STENCIL);
497        }
498        // stencil wrapping?
499        if (mGLSupport->checkExtension("GL_EXT_stencil_wrap"))
500        {
501            mCapabilities->setCapability(RSC_STENCIL_WRAP);
502        }
503
504        // Check for hardware occlusion support
505        if(mGLSupport->checkExtension("GL_NV_occlusion_query"))
506        {
507            mCapabilities->setCapability(RSC_HWOCCLUSION);             
508        }
509
510                // UBYTE4 always supported
511                mCapabilities->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
512
513        // Inifinite far plane always supported
514        mCapabilities->setCapability(RSC_INFINITE_FAR_PLANE);
515
516        // Check for non-power-of-2 texture support
517                if(mGLSupport->checkExtension("GL_ARB_texture_non_power_of_two"))
518        {
519            mCapabilities->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
520        }
521
522        // Check for Float textures
523        if(mGLSupport->checkExtension("GL_ATI_texture_float") ||
524//           mGLSupport->checkExtension("GL_NV_float_buffer") ||
525           mGLSupport->checkExtension("GL_ARB_texture_float"))
526        {
527            mCapabilities->setCapability(RSC_TEXTURE_FLOAT);
528        }
529               
530                // 3D textures should be supported by GL 1.2, which is our minimum version
531        mCapabilities->setCapability(RSC_TEXTURE_3D);
532
533                // Check for GLSupport specific extensions
534                mGLSupport->initialiseCapabilities(*mCapabilities);
535
536        // Get extension function pointers
537        glActiveTextureARB_ptr =
538            (GL_ActiveTextureARB_Func)mGLSupport->getProcAddress("glActiveTextureARB");
539        glClientActiveTextureARB_ptr =
540            (GL_ClientActiveTextureARB_Func)mGLSupport->getProcAddress("glClientActiveTextureARB");
541        glSecondaryColorPointerEXT_ptr =
542            (GL_SecondaryColorPointerEXT_Func)mGLSupport->getProcAddress("glSecondaryColorPointerEXT");
543        glSecondaryColor3fEXT_ptr =
544            (GL_SecondaryColor3fEXT_Func)mGLSupport->getProcAddress("glSecondaryColor3fEXT");
545        glGenBuffersARB_ptr =
546            (GL_GenBuffersARB_Func)mGLSupport->getProcAddress("glGenBuffersARB");
547        glBindBufferARB_ptr =
548            (GL_BindBufferARB_Func)mGLSupport->getProcAddress("glBindBufferARB");
549        glDeleteBuffersARB_ptr =
550            (GL_DeleteBuffersARB_Func)mGLSupport->getProcAddress("glDeleteBuffersARB");
551        glMapBufferARB_ptr =
552            (GL_MapBufferARB_Func)mGLSupport->getProcAddress("glMapBufferARB");
553        glUnmapBufferARB_ptr =
554            (GL_UnmapBufferARB_Func)mGLSupport->getProcAddress("glUnmapBufferARB");
555        glBufferDataARB_ptr =
556            (GL_BufferDataARB_Func)mGLSupport->getProcAddress("glBufferDataARB");
557        glBufferSubDataARB_ptr =
558            (GL_BufferSubDataARB_Func)mGLSupport->getProcAddress("glBufferSubDataARB");
559        glGetBufferSubDataARB_ptr =
560            (GL_GetBufferSubDataARB_Func)mGLSupport->getProcAddress("glGetBufferSubDataARB");
561        glGenProgramsARB_ptr =
562            (GL_GenProgramsARB_Func)mGLSupport->getProcAddress("glGenProgramsARB");
563        glDeleteProgramsARB_ptr =
564            (GL_DeleteProgramsARB_Func)mGLSupport->getProcAddress("glDeleteProgramsARB");
565        glBindProgramARB_ptr =
566            (GL_BindProgramARB_Func)mGLSupport->getProcAddress("glBindProgramARB");
567        glProgramStringARB_ptr =
568            (GL_ProgramStringARB_Func)mGLSupport->getProcAddress("glProgramStringARB");
569        glProgramLocalParameter4fvARB_ptr =
570            (GL_ProgramLocalParameter4fvARB_Func)mGLSupport->getProcAddress("glProgramLocalParameter4fvARB");
571         glProgramParameter4fvNV_ptr =
572            (GL_ProgramParameter4fvNV_Func)mGLSupport->getProcAddress("glProgramParameter4fvNV");
573         glVertexAttribPointerARB_ptr =
574             (GL_VertexAttribPointerARB_Func)mGLSupport->getProcAddress("glVertexAttribPointerARB");
575         glEnableVertexAttribArrayARB_ptr =
576             (GL_EnableVertexAttribArrayARB_Func)mGLSupport->getProcAddress("glEnableVertexAttribArrayARB");
577         glDisableVertexAttribArrayARB_ptr =
578             (GL_DisableVertexAttribArrayARB_Func)mGLSupport->getProcAddress("glDisableVertexAttribArrayARB");
579         glCombinerStageParameterfvNV_ptr =
580            (GL_CombinerStageParameterfvNV_Func)mGLSupport->getProcAddress("glCombinerStageParameterfvNV");
581        glCombinerParameterfvNV_ptr =
582            (GL_CombinerParameterfvNV_Func)mGLSupport->getProcAddress("glCombinerParameterfvNV");
583         glCombinerParameteriNV_ptr = (GL_CombinerParameteriNV_Func)mGLSupport->getProcAddress("glCombinerParameteriNV");
584        glGetProgramivARB_ptr =
585            (GL_GetProgramivARB_Func)mGLSupport->getProcAddress("glGetProgramivARB");
586        glLoadProgramNV_ptr =
587            (GL_LoadProgramNV_Func)mGLSupport->getProcAddress("glLoadProgramNV");
588        glCombinerInputNV_ptr =
589            (GL_CombinerInputNV_Func)mGLSupport->getProcAddress("glCombinerInputNV");
590        glCombinerOutputNV_ptr =
591            (GL_CombinerOutputNV_Func)mGLSupport->getProcAddress("glCombinerOutputNV");
592        glFinalCombinerInputNV_ptr =
593            (GL_FinalCombinerInputNV_Func)mGLSupport->getProcAddress("glFinalCombinerInputNV");
594        glTrackMatrixNV_ptr =
595            (GL_TrackMatrixNV_Func)mGLSupport->getProcAddress("glTrackMatrixNV");
596                glCompressedTexImage1DARB_ptr =
597            (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)mGLSupport->getProcAddress("glCompressedTexImage1DARB");
598        glCompressedTexImage2DARB_ptr =
599            (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)mGLSupport->getProcAddress("glCompressedTexImage2DARB");
600                glCompressedTexImage3DARB_ptr =
601            (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)mGLSupport->getProcAddress("glCompressedTexImage3DARB");
602        glCompressedTexSubImage1DARB_ptr =
603            (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)mGLSupport->getProcAddress("glCompressedTexSubImage1DARB");
604        glCompressedTexSubImage2DARB_ptr =
605            (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)mGLSupport->getProcAddress("glCompressedTexSubImage2DARB");
606        glCompressedTexSubImage3DARB_ptr =
607            (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)mGLSupport->getProcAddress("glCompressedTexSubImage3DARB");
608                glGetCompressedTexImageARB_ptr =
609                        (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)mGLSupport->getProcAddress("glGetCompressedTexImageARB");
610        InitATIFragmentShaderExtensions(*mGLSupport);
611                InitGLShaderLanguageExtensions(*mGLSupport);
612        glActiveStencilFaceEXT_ptr =
613            (GL_ActiveStencilFaceEXT_Func)mGLSupport->getProcAddress("glActiveStencilFaceEXT");
614        glGenOcclusionQueriesNV_ptr =
615            (GL_GenOcclusionQueriesNV_Func)mGLSupport->getProcAddress("glGenOcclusionQueriesNV");
616        glDeleteOcclusionQueriesNV_ptr =
617            (GL_DeleteOcclusionQueriesNV_Func)mGLSupport->getProcAddress("glDeleteOcclusionQueriesNV");
618        glBeginOcclusionQueryNV_ptr =
619            (GL_BeginOcclusionQueryNV_Func)mGLSupport->getProcAddress("glBeginOcclusionQueryNV");
620        glEndOcclusionQueryNV_ptr =
621            (GL_EndOcclusionQueryNV_Func)mGLSupport->getProcAddress("glEndOcclusionQueryNV");
622        glGetOcclusionQueryuivNV_ptr =
623            (GL_GetOcclusionQueryuivNV_Func)mGLSupport->getProcAddress("glGetOcclusionQueryuivNV");
624
625                glGenQueriesARB_ptr =
626                         (GL_GenQueriesARB_Func)mGLSupport->getProcAddress("glGenQueriesARB");
627                glDeleteQueriesARB_ptr =
628                        (GL_DeleteQueriesARB_Func)mGLSupport->getProcAddress("glDeleteQueriesARB");
629                glBeginQueryARB_ptr =
630                         (GL_BeginQueryARB_Func)mGLSupport->getProcAddress("glBeginQueryARB");
631                glEndQueryARB_ptr =
632                         (GL_EndQueryARB_Func)mGLSupport->getProcAddress("glEndQueryARB");
633        #ifdef GTP_VISIBILITY_MODIFIED_OGRE
634                glGetQueryivARB_ptr =
635                        (GL_GetQueryivARB_Func)mGLSupport->getProcAddress("glGetQueryivARB");
636                glGetQueryObjectivARB_ptr =
637                         (GL_GetQueryObjectivARB_Func)mGLSupport->getProcAddress("glGetQueryObjectivARB");
638        #endif // GTP_VISIBILITY_MODIFIED_OGRE
639                glGetQueryObjectuivARB_ptr =
640                         (GL_GetQueryObjectuivARB_Func)mGLSupport->getProcAddress("glGetQueryObjectuivARB");
641
642        mCapabilities->log(LogManager::getSingleton().getDefaultLog());
643        mGLInitialized = true;
644    }
645
646    void GLRenderSystem::reinitialise(void)
647    {
648        this->shutdown();
649        this->initialise(true);
650    }
651
652    void GLRenderSystem::shutdown(void)
653    {
654        RenderSystem::shutdown();
655
656        // Deleting the GPU program manager and hardware buffer manager.  Has to be done before the mGLSupport->stop().
657                if (mGpuProgramManager)
658        {
659                delete mGpuProgramManager;
660                mGpuProgramManager = 0;
661        }
662
663        if (mHardwareBufferManager)
664        {
665            delete mHardwareBufferManager;
666            mHardwareBufferManager = 0;
667        }
668
669
670        mGLSupport->stop();
671        mStopRendering = true;
672    }
673
674    void GLRenderSystem::setAmbientLight(float r, float g, float b)
675    {
676        GLfloat lmodel_ambient[] = {r, g, b, 1.0};
677        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
678    }
679
680    void GLRenderSystem::setShadingType(ShadeOptions so)
681    {
682        switch(so)
683        {
684        case SO_FLAT:
685            glShadeModel(GL_FLAT);
686            break;
687        default:
688            glShadeModel(GL_SMOOTH);
689            break;
690        }
691    }
692
693        RenderWindow* GLRenderSystem::createRenderWindow(const String &name,
694                unsigned int width, unsigned int height, bool fullScreen,
695                const NameValuePairList *miscParams)
696    {
697        if (mRenderTargets.find(name) != mRenderTargets.end())
698        {
699            OGRE_EXCEPT(
700                Exception::ERR_INVALIDPARAMS,
701                "Window with name '" + name + "' already exists",
702                "GLRenderSystem::createRenderWindow" );
703        }
704                // Log a message
705                std::stringstream ss;
706                ss << "GLRenderSystem::createRenderWindow \"" << name << "\", " <<
707                        width << "x" << height << " ";
708                if(fullScreen)
709                        ss << "fullscreen ";
710                else
711                        ss << "windowed ";
712                if(miscParams)
713                {
714                        ss << " miscParams: ";
715                        NameValuePairList::const_iterator it;
716                        for(it=miscParams->begin(); it!=miscParams->end(); ++it)
717                        {
718                                ss << it->first << "=" << it->second << " ";
719                        }
720                        LogManager::getSingleton().logMessage(ss.str());
721                }
722
723        // Create the window
724        RenderWindow* win = mGLSupport->newWindow(name, width, height,
725            fullScreen, miscParams);
726
727        attachRenderTarget( *win );
728
729        if (!mGLInitialized)
730        {
731            // Initialise GL after the first window has been created
732            initGL();
733            mTextureManager = new GLTextureManager(*mGLSupport);
734            // Set main and current context
735            ContextMap::iterator i = mContextMap.find(win);
736            if(i != mContextMap.end()) {
737                mCurrentContext = i->second;
738                mMainContext =  i->second;
739                mCurrentContext->setCurrent();
740            }
741            // Initialise the main context
742            _oneTimeContextInitialization();
743        }
744
745
746        // XXX Do more?
747
748        return win;
749    }
750
751        RenderTexture * GLRenderSystem::createRenderTexture( const String & name, unsigned int width, unsigned int height,
752                TextureType texType, PixelFormat internalFormat, const NameValuePairList *miscParams )
753    {
754                // Log a message
755                std::stringstream ss;
756                ss << "GLRenderSystem::createRenderTexture \"" << name << "\", " <<
757                        width << "x" << height << " texType=" << texType <<
758                        " internalFormat=" << PixelUtil::getFormatName(internalFormat) << " ";
759                if(miscParams)
760                {
761                        ss << "miscParams: ";
762                        NameValuePairList::const_iterator it;
763                        for(it=miscParams->begin(); it!=miscParams->end(); ++it)
764                        {
765                                ss << it->first << "=" << it->second << " ";
766                        }
767                        LogManager::getSingleton().logMessage(ss.str());
768                }
769                // Pass on the create call
770        RenderTexture *rt = mGLSupport->createRenderTexture(name, width, height, texType, internalFormat, miscParams);
771        attachRenderTarget( *rt );
772        return rt;
773    }
774
775    //-----------------------------------------------------------------------
776    void GLRenderSystem::destroyRenderWindow(RenderWindow* pWin)
777    {
778        // Find it to remove from list
779        RenderTargetMap::iterator i = mRenderTargets.begin();
780
781        while (i != mRenderTargets.end())
782        {
783            if (i->second == pWin)
784            {
785                mRenderTargets.erase(i);
786                delete pWin;
787                break;
788            }
789        }
790    }
791
792        //---------------------------------------------------------------------
793    void GLRenderSystem::_useLights(const LightList& lights, unsigned short limit)
794    {
795        // Save previous modelview
796        glMatrixMode(GL_MODELVIEW);
797        glPushMatrix();
798        // just load view matrix (identity world)
799        GLfloat mat[16];
800        makeGLMatrix(mat, mViewMatrix);
801        glLoadMatrixf(mat);
802
803        LightList::const_iterator i, iend;
804        iend = lights.end();
805        unsigned short num = 0;
806        for (i = lights.begin(); i != iend && num < limit; ++i, ++num)
807        {
808            setGLLight(num, *i);
809            mLights[num] = *i;
810        }
811        // Disable extra lights
812        for (; num < mCurrentLights; ++num)
813        {
814            setGLLight(num, NULL);
815            mLights[num] = NULL;
816        }
817        mCurrentLights = std::min(limit, static_cast<unsigned short>(lights.size()));
818
819        setLights();
820
821        // restore previous
822        glPopMatrix();
823
824    }
825
826    void GLRenderSystem::setGLLight(size_t index, Light* lt)
827    {
828        GLenum gl_index = GL_LIGHT0 + index;
829
830        if (!lt)
831        {
832            // Disable in the scene
833            glDisable(gl_index);
834        }
835        else
836        {
837            switch (lt->getType())
838            {
839            case Light::LT_SPOTLIGHT:
840                glLightf( gl_index, GL_SPOT_CUTOFF, 0.5f * lt->getSpotlightOuterAngle().valueDegrees() );
841                break;
842            default:
843                glLightf( gl_index, GL_SPOT_CUTOFF, 180.0 );
844                break;
845            }
846
847            // Color
848            ColourValue col;
849            col = lt->getDiffuseColour();
850
851
852            GLfloat f4vals[4] = {col.r, col.g, col.b, col.a};
853            glLightfv(gl_index, GL_DIFFUSE, f4vals);
854           
855            col = lt->getSpecularColour();
856            f4vals[0] = col.r;
857            f4vals[1] = col.g;
858            f4vals[2] = col.b;
859            f4vals[3] = col.a;
860            glLightfv(gl_index, GL_SPECULAR, f4vals);
861
862
863            // Disable ambient light for movables;
864            f4vals[0] = 0;
865            f4vals[1] = 0;
866            f4vals[2] = 0;
867            f4vals[3] = 1;
868            glLightfv(gl_index, GL_AMBIENT, f4vals);
869
870            setGLLightPositionDirection(lt, gl_index);
871
872
873            // Attenuation
874            glLightf(gl_index, GL_CONSTANT_ATTENUATION, lt->getAttenuationConstant());
875            glLightf(gl_index, GL_LINEAR_ATTENUATION, lt->getAttenuationLinear());
876            glLightf(gl_index, GL_QUADRATIC_ATTENUATION, lt->getAttenuationQuadric());
877            // Enable in the scene
878            glEnable(gl_index);
879
880        }
881
882    }
883
884    //-----------------------------------------------------------------------------
885    void GLRenderSystem::makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m)
886    {
887        size_t x = 0;
888        for (size_t i = 0; i < 4; i++)
889        {
890            for (size_t j = 0; j < 4; j++)
891            {
892                gl_matrix[x] = m[j][i];
893                x++;
894            }
895        }
896    }
897    //-----------------------------------------------------------------------------
898    void GLRenderSystem::_setWorldMatrix( const Matrix4 &m )
899    {
900        GLfloat mat[16];
901        mWorldMatrix = m;
902        makeGLMatrix( mat, mViewMatrix * mWorldMatrix );
903        glMatrixMode(GL_MODELVIEW);
904        glLoadMatrixf(mat);
905    }
906
907    //-----------------------------------------------------------------------------
908    void GLRenderSystem::_setViewMatrix( const Matrix4 &m )
909    {
910        mViewMatrix = m;
911
912        GLfloat mat[16];
913        makeGLMatrix(mat, mViewMatrix);
914        glMatrixMode(GL_MODELVIEW);
915        glLoadMatrixf(mat);
916
917        makeGLMatrix(mat, mWorldMatrix);
918        glMultMatrixf(mat);
919
920        setGLClipPlanes();
921    }
922    //-----------------------------------------------------------------------------
923    void GLRenderSystem::_setProjectionMatrix(const Matrix4 &m)
924    {
925        GLfloat mat[16];
926        makeGLMatrix(mat, m);
927        if (mActiveRenderTarget->requiresTextureFlipping())
928        {
929            // Invert y
930            mat[5] = -mat[5];
931        }
932        glMatrixMode(GL_PROJECTION);
933        glLoadMatrixf(mat);
934        glMatrixMode(GL_MODELVIEW);
935    }
936    //-----------------------------------------------------------------------------
937    void GLRenderSystem::_setSurfaceParams(const ColourValue &ambient,
938        const ColourValue &diffuse, const ColourValue &specular,
939        const ColourValue &emissive, Real shininess,
940        TrackVertexColourType tracking)
941    {
942        // XXX Cache previous values?
943        // XXX Front or Front and Back?
944
945        GLfloat f4val[4] = {diffuse.r, diffuse.g, diffuse.b, diffuse.a};
946        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, f4val);
947        f4val[0] = ambient.r;
948        f4val[1] = ambient.g;
949        f4val[2] = ambient.b;
950        f4val[3] = ambient.a;
951        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, f4val);
952        f4val[0] = specular.r;
953        f4val[1] = specular.g;
954        f4val[2] = specular.b;
955        f4val[3] = specular.a;
956        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, f4val);
957        f4val[0] = emissive.r;
958        f4val[1] = emissive.g;
959        f4val[2] = emissive.b;
960        f4val[3] = emissive.a;
961        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, f4val);
962        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
963       
964        // Track vertex colour
965        if(tracking != TVC_NONE)
966        {
967            GLenum gt = GL_DIFFUSE;
968            // There are actually 15 different combinations for tracking, of which
969            // GL only supports the most used 5. This means that we have to do some
970            // magic to find the best match. NOTE:
971            //  GL_AMBIENT_AND_DIFFUSE != GL_AMBIENT | GL__DIFFUSE
972            if(tracking & TVC_AMBIENT)
973            {
974                if(tracking & TVC_DIFFUSE)
975                {
976                    gt = GL_AMBIENT_AND_DIFFUSE;
977                }
978                else
979                {
980                    gt = GL_AMBIENT;
981                }
982            }
983            else if(tracking & TVC_DIFFUSE)
984            {
985                gt = GL_DIFFUSE;
986            }
987            else if(tracking & TVC_SPECULAR)
988            {
989                gt = GL_SPECULAR;             
990            }
991            else if(tracking & TVC_EMISSIVE)
992            {
993                gt = GL_EMISSION;
994            }
995            glColorMaterial(GL_FRONT_AND_BACK, gt);
996           
997            glEnable(GL_COLOR_MATERIAL);
998        }
999        else
1000        {
1001            glDisable(GL_COLOR_MATERIAL);         
1002        }
1003    }
1004
1005    //-----------------------------------------------------------------------------
1006    void GLRenderSystem::_setTexture(size_t stage, bool enabled, const String &texname)
1007    {
1008        GLTexturePtr tex = TextureManager::getSingleton().getByName(texname);
1009
1010        GLenum lastTextureType = mTextureTypes[stage];
1011
1012                glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
1013                if (enabled)
1014        {
1015            if (!tex.isNull())
1016            {
1017                // note used
1018                tex->touch();
1019                mTextureTypes[stage] = tex->getGLTextureTarget();
1020            }
1021            else
1022                // assume 2D
1023                mTextureTypes[stage] = GL_TEXTURE_2D;
1024
1025            if(lastTextureType != mTextureTypes[stage] && lastTextureType != 0)
1026            {
1027                glDisable( lastTextureType );
1028            }
1029
1030                        glEnable( mTextureTypes[stage] );
1031                        if(!tex.isNull())
1032                                glBindTexture( mTextureTypes[stage], tex->getGLID() );
1033        }
1034        else
1035        {
1036            if (lastTextureType != 0)
1037            {
1038                glDisable( mTextureTypes[stage] );
1039            }
1040                        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1041        }
1042
1043        glActiveTextureARB_ptr( GL_TEXTURE0 );
1044    }
1045
1046    //-----------------------------------------------------------------------------
1047    void GLRenderSystem::_setTextureCoordSet(size_t stage, size_t index)
1048    {
1049        mTextureCoordIndex[stage] = index;
1050    }
1051    //-----------------------------------------------------------------------------
1052    void GLRenderSystem::_setTextureCoordCalculation(size_t stage, TexCoordCalcMethod m,
1053        const Frustum* frustum)
1054    {
1055        GLfloat M[16];
1056        Matrix4 projectionBias;
1057
1058        // Default to no extra auto texture matrix
1059        mUseAutoTextureMatrix = false;
1060
1061        GLfloat eyePlaneS[] = {1.0, 0.0, 0.0, 0.0};
1062        GLfloat eyePlaneT[] = {0.0, 1.0, 0.0, 0.0};
1063        GLfloat eyePlaneR[] = {0.0, 0.0, 1.0, 0.0};
1064        GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, 1.0};
1065
1066        glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
1067
1068        switch( m )
1069        {
1070        case TEXCALC_NONE:
1071            glDisable( GL_TEXTURE_GEN_S );
1072            glDisable( GL_TEXTURE_GEN_T );
1073            glDisable( GL_TEXTURE_GEN_R );
1074            glDisable( GL_TEXTURE_GEN_Q );
1075            break;
1076
1077        case TEXCALC_ENVIRONMENT_MAP:
1078            glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
1079            glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
1080
1081            glEnable( GL_TEXTURE_GEN_S );
1082            glEnable( GL_TEXTURE_GEN_T );
1083            glDisable( GL_TEXTURE_GEN_R );
1084            glDisable( GL_TEXTURE_GEN_Q );
1085
1086            // Need to use a texture matrix to flip the spheremap
1087            mUseAutoTextureMatrix = true;
1088            memset(mAutoTextureMatrix, 0, sizeof(GLfloat)*16);
1089            mAutoTextureMatrix[0] = mAutoTextureMatrix[10] = mAutoTextureMatrix[15] = 1.0f;
1090            mAutoTextureMatrix[5] = -1.0f;
1091
1092            break;
1093
1094        case TEXCALC_ENVIRONMENT_MAP_PLANAR:           
1095            // XXX This doesn't seem right?!
1096#ifdef GL_VERSION_1_3
1097            glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1098            glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1099            glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1100
1101            glEnable( GL_TEXTURE_GEN_S );
1102            glEnable( GL_TEXTURE_GEN_T );
1103            glEnable( GL_TEXTURE_GEN_R );
1104            glDisable( GL_TEXTURE_GEN_Q );
1105#else
1106            glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
1107            glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
1108
1109            glEnable( GL_TEXTURE_GEN_S );
1110            glEnable( GL_TEXTURE_GEN_T );
1111            glDisable( GL_TEXTURE_GEN_R );
1112            glDisable( GL_TEXTURE_GEN_Q );
1113#endif
1114            break;
1115        case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
1116           
1117            glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1118            glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1119            glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
1120
1121            glEnable( GL_TEXTURE_GEN_S );
1122            glEnable( GL_TEXTURE_GEN_T );
1123            glEnable( GL_TEXTURE_GEN_R );
1124            glDisable( GL_TEXTURE_GEN_Q );
1125
1126            // We need an extra texture matrix here
1127            // This sets the texture matrix to be the inverse of the modelview matrix
1128            mUseAutoTextureMatrix = true;
1129            glGetFloatv( GL_MODELVIEW_MATRIX, M );
1130
1131            // Transpose 3x3 in order to invert matrix (rotation)
1132            // Note that we need to invert the Z _before_ the rotation
1133            // No idea why we have to invert the Z at all, but reflection is wrong without it
1134            mAutoTextureMatrix[0] = M[0]; mAutoTextureMatrix[1] = M[4]; mAutoTextureMatrix[2] = -M[8];
1135            mAutoTextureMatrix[4] = M[1]; mAutoTextureMatrix[5] = M[5]; mAutoTextureMatrix[6] = -M[9];
1136            mAutoTextureMatrix[8] = M[2]; mAutoTextureMatrix[9] = M[6]; mAutoTextureMatrix[10] = -M[10];
1137            mAutoTextureMatrix[3] = mAutoTextureMatrix[7] = mAutoTextureMatrix[11] = 0.0f;
1138            mAutoTextureMatrix[12] = mAutoTextureMatrix[13] = mAutoTextureMatrix[14] = 0.0f;
1139            mAutoTextureMatrix[15] = 1.0f;
1140
1141            break;
1142        case TEXCALC_ENVIRONMENT_MAP_NORMAL:
1143            glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
1144            glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
1145            glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
1146
1147            glEnable( GL_TEXTURE_GEN_S );
1148            glEnable( GL_TEXTURE_GEN_T );
1149            glEnable( GL_TEXTURE_GEN_R );
1150            glDisable( GL_TEXTURE_GEN_Q );
1151            break;
1152        case TEXCALC_PROJECTIVE_TEXTURE:
1153            glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1154            glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1155            glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1156            glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1157            glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
1158            glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
1159            glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
1160            glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
1161            glEnable(GL_TEXTURE_GEN_S);
1162            glEnable(GL_TEXTURE_GEN_T);
1163            glEnable(GL_TEXTURE_GEN_R);
1164            glEnable(GL_TEXTURE_GEN_Q);
1165
1166            mUseAutoTextureMatrix = true;
1167
1168            // Set scale and translation matrix for projective textures
1169            projectionBias = Matrix4::ZERO;
1170            projectionBias[0][0] = 0.5; projectionBias[1][1] = -0.5;
1171            projectionBias[2][2] = 1.0; projectionBias[0][3] = 0.5;
1172            projectionBias[1][3] = 0.5; projectionBias[3][3] = 1.0;
1173
1174            projectionBias = projectionBias * frustum->getProjectionMatrix();
1175            projectionBias = projectionBias * frustum->getViewMatrix();
1176            projectionBias = projectionBias * mWorldMatrix;
1177
1178            makeGLMatrix(mAutoTextureMatrix, projectionBias);
1179            break;
1180        default:
1181            break;
1182        }
1183        glActiveTextureARB_ptr( GL_TEXTURE0 );
1184    }
1185    //-----------------------------------------------------------------------------
1186    void GLRenderSystem::_setTextureAddressingMode(size_t stage, TextureUnitState::TextureAddressingMode tam)
1187    {
1188        GLint type;
1189        switch(tam)
1190        {
1191        case TextureUnitState::TAM_WRAP:
1192            type = GL_REPEAT;
1193            break;
1194        case TextureUnitState::TAM_MIRROR:
1195            type = GL_MIRRORED_REPEAT;
1196            break;
1197        case TextureUnitState::TAM_CLAMP:
1198            type = GL_CLAMP_TO_EDGE;
1199            break;
1200        }
1201
1202        glActiveTextureARB_ptr( GL_TEXTURE0 + stage );
1203        glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S, type );
1204        glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T, type );
1205        glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R, type );
1206        glActiveTextureARB_ptr( GL_TEXTURE0 );
1207    }
1208    //-----------------------------------------------------------------------------
1209    void GLRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xform)
1210    {
1211        GLfloat mat[16];
1212        makeGLMatrix(mat, xform);
1213
1214                if(mTextureTypes[stage] != GL_TEXTURE_3D &&
1215                   mTextureTypes[stage] != GL_TEXTURE_CUBE_MAP)
1216                {
1217                        // Convert 3x3 rotation/translation matrix to 4x4
1218                        mat[12] = mat[8];
1219                        mat[13] = mat[9];
1220                }
1221//        mat[14] = mat[10];
1222//        mat[15] = mat[11];
1223
1224//        for (int j=0; j< 4; j++)
1225//        {
1226//            int x = 0;
1227//            for (x = 0; x < 4; x++)
1228//            {
1229//                printf("[%2d]=%0.2f\t", (x*4) + j, mat[(x*4) + j]);
1230//            }
1231//            printf("\n");
1232//        }
1233
1234        glActiveTextureARB_ptr(GL_TEXTURE0 + stage);
1235        glMatrixMode(GL_TEXTURE);
1236
1237        if (mUseAutoTextureMatrix)
1238        {
1239            // Load auto matrix in
1240            glLoadMatrixf(mAutoTextureMatrix);
1241            // Concat new matrix
1242            glMultMatrixf(mat);
1243
1244        }
1245        else
1246        {
1247            // Just load this matrix
1248            glLoadMatrixf(mat);
1249        }
1250
1251        glMatrixMode(GL_MODELVIEW);
1252        glActiveTextureARB_ptr(GL_TEXTURE0);
1253    }
1254    //-----------------------------------------------------------------------------
1255    GLint GLRenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const
1256    {
1257        switch(ogreBlend)
1258        {
1259        case SBF_ONE:
1260            return GL_ONE;
1261        case SBF_ZERO:
1262            return GL_ZERO;
1263        case SBF_DEST_COLOUR:
1264            return GL_DST_COLOR;
1265        case SBF_SOURCE_COLOUR:
1266            return GL_SRC_COLOR;
1267        case SBF_ONE_MINUS_DEST_COLOUR:
1268            return GL_ONE_MINUS_DST_COLOR;
1269        case SBF_ONE_MINUS_SOURCE_COLOUR:
1270            return GL_ONE_MINUS_SRC_COLOR;
1271        case SBF_DEST_ALPHA:
1272            return GL_DST_ALPHA;
1273        case SBF_SOURCE_ALPHA:
1274            return GL_SRC_ALPHA;
1275        case SBF_ONE_MINUS_DEST_ALPHA:
1276            return GL_ONE_MINUS_DST_ALPHA;
1277        case SBF_ONE_MINUS_SOURCE_ALPHA:
1278            return GL_ONE_MINUS_SRC_ALPHA;
1279        };
1280                // to keep compiler happy
1281                return GL_ONE;
1282    }
1283
1284    void GLRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
1285    {
1286        GLint sourceBlend = getBlendMode(sourceFactor);
1287        GLint destBlend = getBlendMode(destFactor);
1288       
1289        glEnable(GL_BLEND);
1290        glBlendFunc(sourceBlend, destBlend);
1291    }
1292    //-----------------------------------------------------------------------------
1293    void GLRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value)
1294    {
1295        glEnable(GL_ALPHA_TEST);
1296        glAlphaFunc(convertCompareFunction(func), value / 255.0f);
1297    }
1298    //-----------------------------------------------------------------------------
1299    void GLRenderSystem::_setViewport(Viewport *vp)
1300    {
1301        // Check if viewport is different
1302        if (vp != mActiveViewport || vp->_isUpdated())
1303        {
1304            RenderTarget* target;
1305            target = vp->getTarget();
1306            _setRenderTarget(target);
1307            mActiveViewport = vp;
1308             
1309              GLsizei x, y, w, h;
1310 
1311              // Calculate the "lower-left" corner of the viewport
1312              w = vp->getActualWidth();
1313              h = vp->getActualHeight();
1314              x = vp->getActualLeft();
1315              y = target->getHeight() - vp->getActualTop() - h;
1316 
1317              glViewport(x, y, w, h);
1318 
1319              // Configure the viewport clipping
1320              glScissor(x, y, w, h);
1321 
1322              vp->_clearUpdatedFlag();
1323        }
1324    }
1325
1326        void GLRenderSystem::setLights()
1327        {
1328        for (size_t i = 0; i < MAX_LIGHTS; ++i)
1329        {
1330            if (mLights[i] != NULL)
1331            {
1332                Light* lt = mLights[i];
1333                setGLLightPositionDirection(lt, GL_LIGHT0 + i);
1334            }
1335        }
1336        }
1337
1338    //-----------------------------------------------------------------------------
1339    void GLRenderSystem::_beginFrame(void)
1340    {
1341        OgreGuard( "GLRenderSystem::_beginFrame" );
1342       
1343        if (!mActiveViewport)
1344            OGRE_EXCEPT(999, "Cannot begin frame - no viewport selected.",
1345                "GLRenderSystem::_beginFrame");
1346
1347        // Clear the viewport if required
1348        if (mActiveViewport->getClearEveryFrame())
1349        {
1350            // Activate the viewport clipping
1351            glEnable(GL_SCISSOR_TEST);
1352
1353            clearFrameBuffer(FBT_COLOUR | FBT_DEPTH,
1354                mActiveViewport->getBackgroundColour());
1355        }       
1356
1357        OgreUnguard();
1358    }
1359   
1360    //-----------------------------------------------------------------------------
1361    void GLRenderSystem::_endFrame(void)
1362    {
1363        // Deactivate the viewport clipping.
1364        glDisable(GL_SCISSOR_TEST);
1365    }
1366
1367    //-----------------------------------------------------------------------------
1368    void GLRenderSystem::_setCullingMode(CullingMode mode)
1369    {
1370        // NB: Because two-sided stencil API dependence of the front face, we must
1371        // use the same 'winding' for the front face everywhere. As the OGRE default
1372        // culling mode is clockwise, we also treat anticlockwise winding as front
1373        // face for consistently. On the assumption that, we can't change the front
1374        // face by glFrontFace anywhere.
1375
1376        GLenum cullMode;
1377
1378        switch( mode )
1379        {
1380        case CULL_NONE:
1381            glDisable( GL_CULL_FACE );
1382            return;
1383        case CULL_CLOCKWISE:
1384            if (mActiveRenderTarget &&
1385                ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
1386                (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
1387            {
1388                cullMode = GL_FRONT;
1389            }
1390            else
1391            {
1392                cullMode = GL_BACK;
1393            }
1394            break;
1395        case CULL_ANTICLOCKWISE:
1396            if (mActiveRenderTarget &&
1397                ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
1398                (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
1399            {
1400                cullMode = GL_BACK;
1401            }
1402            else
1403            {
1404                cullMode = GL_FRONT;
1405            }
1406            break;
1407        }
1408
1409        glEnable( GL_CULL_FACE );
1410        glCullFace( cullMode );
1411    }
1412    //-----------------------------------------------------------------------------
1413    void GLRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
1414    {
1415        _setDepthBufferCheckEnabled(depthTest);
1416        _setDepthBufferWriteEnabled(depthWrite);
1417        _setDepthBufferFunction(depthFunction);
1418    }
1419    //-----------------------------------------------------------------------------
1420    void GLRenderSystem::_setDepthBufferCheckEnabled(bool enabled)
1421    {
1422        if (enabled)
1423        {
1424            glClearDepth(1.0f);
1425            glEnable(GL_DEPTH_TEST);
1426        }
1427        else
1428        {
1429            glDisable(GL_DEPTH_TEST);
1430        }
1431    }
1432    //-----------------------------------------------------------------------------
1433    void GLRenderSystem::_setDepthBufferWriteEnabled(bool enabled)
1434    {
1435        GLboolean flag = enabled ? GL_TRUE : GL_FALSE;
1436        glDepthMask( flag ); 
1437        // Store for reference in _beginFrame
1438        mDepthWrite = enabled;
1439    }
1440    //-----------------------------------------------------------------------------
1441    void GLRenderSystem::_setDepthBufferFunction(CompareFunction func)
1442    {
1443        glDepthFunc(convertCompareFunction(func));
1444    }
1445    //-----------------------------------------------------------------------------
1446    void GLRenderSystem::_setDepthBias(ushort bias)
1447    {
1448        if (bias > 0)
1449        {
1450            glEnable(GL_POLYGON_OFFSET_FILL);
1451            glEnable(GL_POLYGON_OFFSET_POINT);
1452            glEnable(GL_POLYGON_OFFSET_LINE);
1453            // Bias is in {0, 16}, scale the unit addition appropriately
1454            glPolygonOffset(0.0f, -bias);
1455        }
1456        else
1457        {
1458            glDisable(GL_POLYGON_OFFSET_FILL);
1459            glDisable(GL_POLYGON_OFFSET_POINT);
1460            glDisable(GL_POLYGON_OFFSET_LINE);
1461        }
1462    }
1463        //-----------------------------------------------------------------------------
1464        void GLRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
1465        {
1466                glColorMask(red, green, blue, alpha);
1467                // record this
1468                mColourWrite[0] = red;
1469                mColourWrite[1] = blue;
1470                mColourWrite[2] = green;
1471                mColourWrite[3] = alpha;
1472        }
1473        //-----------------------------------------------------------------------------
1474    String GLRenderSystem::getErrorDescription(long errCode) const
1475    {
1476        const GLubyte *errString = gluErrorString (errCode);
1477        return String((const char*) errString);
1478    }
1479    //-----------------------------------------------------------------------------
1480    void GLRenderSystem::setLightingEnabled(bool enabled)
1481    {
1482        if (enabled)
1483        {     
1484            glEnable(GL_LIGHTING);
1485        }
1486        else
1487        {
1488            glDisable(GL_LIGHTING);
1489        }
1490    }
1491    //-----------------------------------------------------------------------------
1492    void GLRenderSystem::_setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
1493    {
1494
1495        GLint fogMode;
1496        switch (mode)
1497        {
1498        case FOG_EXP:
1499            fogMode = GL_EXP;
1500            break;
1501        case FOG_EXP2:
1502            fogMode = GL_EXP2;
1503            break;
1504        case FOG_LINEAR:
1505            fogMode = GL_LINEAR;
1506            break;
1507        default:
1508            // Give up on it
1509            glDisable(GL_FOG);
1510            return;
1511        }
1512
1513        glEnable(GL_FOG);
1514        glFogi(GL_FOG_MODE, fogMode);
1515        GLfloat fogColor[4] = {colour.r, colour.g, colour.b, colour.a};
1516        glFogfv(GL_FOG_COLOR, fogColor);
1517        glFogf(GL_FOG_DENSITY, density);
1518        glFogf(GL_FOG_START, start);
1519        glFogf(GL_FOG_END, end);
1520        // XXX Hint here?
1521    }
1522
1523    void GLRenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest)
1524    {
1525    #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
1526        *pDest = colour.getAsRGBA();
1527    #else
1528      // GL accesses by byte, so use ABGR so little-endian format will make it RGBA in byte mode
1529        *pDest = colour.getAsABGR();
1530    #endif
1531    }
1532   
1533    void GLRenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane,
1534        Real farPlane, Matrix4& dest, bool forGpuProgram)
1535    {
1536        Radian thetaY ( fovy / 2.0f );
1537        Real tanThetaY = Math::Tan(thetaY);
1538        //Real thetaX = thetaY * aspect;
1539        //Real tanThetaX = Math::Tan(thetaX);
1540
1541        // Calc matrix elements
1542        Real w = (1.0f / tanThetaY) / aspect;
1543        Real h = 1.0f / tanThetaY;
1544        Real q, qn;
1545        if (farPlane == 0)
1546        {
1547            // Infinite far plane
1548            q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
1549            qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
1550        }
1551        else
1552        {
1553            q = -(farPlane + nearPlane) / (farPlane - nearPlane);
1554            qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
1555        }
1556
1557        // NB This creates Z in range [-1,1]
1558        //
1559        // [ w   0   0   0  ]
1560        // [ 0   h   0   0  ]
1561        // [ 0   0   q   qn ]
1562        // [ 0   0   -1  0  ]
1563
1564        dest = Matrix4::ZERO;
1565        dest[0][0] = w;
1566        dest[1][1] = h;
1567        dest[2][2] = q;
1568        dest[2][3] = qn;
1569        dest[3][2] = -1;
1570
1571    }
1572   
1573    void GLRenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane,
1574        Real farPlane, Matrix4& dest, bool forGpuProgram)
1575    {
1576        Radian thetaY (fovy / 2.0f);
1577        Real tanThetaY = Math::Tan(thetaY);
1578
1579        //Real thetaX = thetaY * aspect;
1580        Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX);
1581        Real half_w = tanThetaX * nearPlane;
1582        Real half_h = tanThetaY * nearPlane;
1583        Real iw = 1.0 / half_w;
1584        Real ih = 1.0 / half_h;
1585        Real q;
1586        if (farPlane == 0)
1587        {
1588            q = 0;
1589        }
1590        else
1591        {
1592            q = 2.0 / (farPlane - nearPlane);
1593        }
1594        dest = Matrix4::ZERO;
1595        dest[0][0] = iw;
1596        dest[1][1] = ih;
1597        dest[2][2] = -q;
1598        dest[2][3] = - (farPlane + nearPlane)/(farPlane - nearPlane);
1599        dest[3][3] = 1;
1600        }
1601
1602    void GLRenderSystem::_setRasterisationMode(SceneDetailLevel level)
1603    {
1604        GLenum glmode;
1605        switch(level)
1606        {
1607        case SDL_POINTS:
1608            glmode = GL_POINT;
1609            break;
1610        case SDL_WIREFRAME:
1611            glmode = GL_LINE;
1612            break;
1613        case SDL_SOLID:
1614            glmode = GL_FILL;
1615            break;
1616        }
1617        glPolygonMode(GL_FRONT_AND_BACK, glmode);
1618    }
1619    //---------------------------------------------------------------------
1620    void GLRenderSystem::setStencilCheckEnabled(bool enabled)
1621    {
1622        if (enabled)
1623        {
1624            glEnable(GL_STENCIL_TEST);
1625        }
1626        else
1627        {
1628            glDisable(GL_STENCIL_TEST);
1629        }
1630    }
1631    //---------------------------------------------------------------------
1632    void GLRenderSystem::setStencilBufferParams(CompareFunction func,
1633        uint32 refValue, uint32 mask, StencilOperation stencilFailOp,
1634        StencilOperation depthFailOp, StencilOperation passOp,
1635        bool twoSidedOperation)
1636    {
1637        bool flip;
1638
1639        if (twoSidedOperation)
1640        {
1641            if (!mCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL))
1642                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported",
1643                    "GLRenderSystem::setStencilBufferParams");
1644            glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
1645            // NB: We should always treat CCW as front face for consistent with default
1646            // culling mode. Therefore, we must take care with two-sided stencil settings.
1647            flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) ||
1648                   (!mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping());
1649
1650            // Set alternative versions of ops
1651            glActiveStencilFaceEXT_ptr(GL_BACK);
1652            glStencilMask(mask);
1653            glStencilFunc(convertCompareFunction(func), refValue, mask);
1654            glStencilOp(
1655                convertStencilOp(stencilFailOp, !flip),
1656                convertStencilOp(depthFailOp, !flip),
1657                convertStencilOp(passOp, !flip));
1658            // reset
1659            glActiveStencilFaceEXT_ptr(GL_FRONT);
1660        }
1661        else
1662        {
1663            glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
1664            flip = false;
1665        }
1666
1667        glStencilMask(mask);
1668        glStencilFunc(convertCompareFunction(func), refValue, mask);
1669        glStencilOp(
1670            convertStencilOp(stencilFailOp, flip),
1671            convertStencilOp(depthFailOp, flip),
1672            convertStencilOp(passOp, flip));
1673    }
1674    //---------------------------------------------------------------------
1675    GLint GLRenderSystem::convertCompareFunction(CompareFunction func) const
1676    {
1677        switch(func)
1678        {
1679        case CMPF_ALWAYS_FAIL:
1680            return GL_NEVER;
1681        case CMPF_ALWAYS_PASS:
1682            return GL_ALWAYS;
1683        case CMPF_LESS:
1684            return GL_LESS;
1685        case CMPF_LESS_EQUAL:
1686            return GL_LEQUAL;
1687        case CMPF_EQUAL:
1688            return GL_EQUAL;
1689        case CMPF_NOT_EQUAL:
1690            return GL_NOTEQUAL;
1691        case CMPF_GREATER_EQUAL:
1692            return GL_GEQUAL;
1693        case CMPF_GREATER:
1694            return GL_GREATER;
1695        };
1696        // to keep compiler happy
1697        return GL_ALWAYS;
1698    }
1699    //---------------------------------------------------------------------
1700    GLint GLRenderSystem::convertStencilOp(StencilOperation op, bool invert) const
1701    {
1702        switch(op)
1703        {
1704        case SOP_KEEP:
1705            return GL_KEEP;
1706        case SOP_ZERO:
1707            return GL_ZERO;
1708        case SOP_REPLACE:
1709            return GL_REPLACE;
1710        case SOP_INCREMENT:
1711            return invert ? GL_DECR : GL_INCR;
1712        case SOP_DECREMENT:
1713            return invert ? GL_INCR : GL_DECR;
1714        case SOP_INCREMENT_WRAP:
1715            return invert ? GL_DECR_WRAP_EXT : GL_INCR_WRAP_EXT;
1716        case SOP_DECREMENT_WRAP:
1717            return invert ? GL_INCR_WRAP_EXT : GL_DECR_WRAP_EXT;
1718        case SOP_INVERT:
1719            return GL_INVERT;
1720        };
1721        // to keep compiler happy
1722        return SOP_KEEP;
1723    }
1724        //---------------------------------------------------------------------
1725    GLuint GLRenderSystem::getCombinedMinMipFilter(void) const
1726    {
1727        switch(mMinFilter)
1728        {
1729        case FO_ANISOTROPIC:
1730        case FO_LINEAR:
1731            switch(mMipFilter)
1732            {
1733            case FO_ANISOTROPIC:
1734            case FO_LINEAR:
1735                // linear min, linear mip
1736                return GL_LINEAR_MIPMAP_LINEAR;
1737            case FO_POINT:
1738                // linear min, point mip
1739                return GL_LINEAR_MIPMAP_NEAREST;
1740            case FO_NONE:
1741                // linear min, no mip
1742                return GL_LINEAR;
1743            }
1744            break;
1745        case FO_POINT:
1746        case FO_NONE:
1747            switch(mMipFilter)
1748            {
1749            case FO_ANISOTROPIC:
1750            case FO_LINEAR:
1751                // nearest min, linear mip
1752                return GL_NEAREST_MIPMAP_LINEAR;
1753            case FO_POINT:
1754                // nearest min, point mip
1755                return GL_NEAREST_MIPMAP_NEAREST;
1756            case FO_NONE:
1757                // nearest min, no mip
1758                return GL_NEAREST;
1759            }
1760            break;
1761        }
1762
1763        // should never get here
1764        return 0;
1765
1766    }
1767        //---------------------------------------------------------------------
1768    void GLRenderSystem::_setTextureUnitFiltering(size_t unit,
1769        FilterType ftype, FilterOptions fo)
1770        {
1771        OgreGuard( "GLRenderSystem::_setTextureUnitFiltering" );       
1772
1773                glActiveTextureARB_ptr( GL_TEXTURE0 + unit );
1774        switch(ftype)
1775        {
1776        case FT_MIN:
1777            mMinFilter = fo;
1778            // Combine with existing mip filter
1779                        glTexParameteri(
1780                mTextureTypes[unit],
1781                                GL_TEXTURE_MIN_FILTER,
1782                                getCombinedMinMipFilter());
1783            break;
1784        case FT_MAG:
1785            switch (fo)
1786            {
1787            case FO_ANISOTROPIC: // GL treats linear and aniso the same
1788            case FO_LINEAR:
1789                            glTexParameteri(
1790                    mTextureTypes[unit],
1791                                    GL_TEXTURE_MAG_FILTER,
1792                                    GL_LINEAR);
1793                break;
1794            case FO_POINT:
1795            case FO_NONE:
1796                            glTexParameteri(
1797                    mTextureTypes[unit],
1798                                    GL_TEXTURE_MAG_FILTER,
1799                                    GL_NEAREST);
1800                break;
1801            }
1802            break;
1803        case FT_MIP:
1804            mMipFilter = fo;
1805            // Combine with existing min filter
1806                        glTexParameteri(
1807                mTextureTypes[unit],
1808                                GL_TEXTURE_MIN_FILTER,
1809                                getCombinedMinMipFilter());
1810            break;
1811                }
1812
1813        glActiveTextureARB_ptr( GL_TEXTURE0 );
1814
1815                OgreUnguard();
1816        }
1817        //---------------------------------------------------------------------
1818        GLfloat GLRenderSystem::_getCurrentAnisotropy(size_t unit)
1819        {
1820                GLfloat curAniso = 0;
1821                glGetTexParameterfv(mTextureTypes[unit],
1822            GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso);
1823                return curAniso ? curAniso : 1;
1824        }
1825        //---------------------------------------------------------------------
1826        void GLRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
1827        {
1828       if (!mCapabilities->hasCapability(RSC_ANISOTROPY))
1829                        return;
1830
1831                GLfloat largest_supported_anisotropy = 0;
1832                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
1833                if (maxAnisotropy > largest_supported_anisotropy)
1834                        maxAnisotropy = largest_supported_anisotropy ? largest_supported_anisotropy : 1;
1835                if (_getCurrentAnisotropy(unit) != maxAnisotropy)
1836                        glTexParameterf(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
1837        }
1838        //-----------------------------------------------------------------------------
1839    void GLRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm)
1840    {       
1841        // Check to see if blending is supported
1842        if(!mCapabilities->hasCapability(RSC_BLENDING))
1843            return;
1844
1845        GLenum src1op, src2op, cmd;
1846        GLfloat cv1[4], cv2[4];
1847
1848                if (bm.blendType == LBT_COLOUR)
1849        {
1850                    cv1[0] = bm.colourArg1.r;
1851                    cv1[1] = bm.colourArg1.g;
1852                    cv1[2] = bm.colourArg1.b;
1853                    cv1[3] = bm.colourArg1.a;
1854                        mManualBlendColours[stage][0] = bm.colourArg1;
1855
1856
1857                    cv2[0] = bm.colourArg2.r;
1858                    cv2[1] = bm.colourArg2.g;
1859                    cv2[2] = bm.colourArg2.b;
1860                    cv2[3] = bm.colourArg2.a;
1861                        mManualBlendColours[stage][1] = bm.colourArg2;
1862        }
1863
1864                if (bm.blendType == LBT_ALPHA)
1865        {
1866                    cv1[0] = mManualBlendColours[stage][0].r;
1867                    cv1[1] = mManualBlendColours[stage][0].g;
1868                    cv1[2] = mManualBlendColours[stage][0].b;
1869                    cv1[3] = bm.alphaArg1;
1870
1871                    cv2[0] = mManualBlendColours[stage][1].r;
1872                    cv2[1] = mManualBlendColours[stage][1].g;
1873                    cv2[2] = mManualBlendColours[stage][1].b;
1874                    cv2[3] = bm.alphaArg2;
1875        }
1876
1877        switch (bm.source1)
1878        {
1879        case LBS_CURRENT:
1880            src1op = GL_PREVIOUS;
1881            break;
1882        case LBS_TEXTURE:
1883            src1op = GL_TEXTURE;
1884            break;
1885        case LBS_MANUAL:
1886            src1op = GL_CONSTANT;
1887                        break;
1888        case LBS_DIFFUSE:
1889            src1op = GL_PRIMARY_COLOR;
1890                        break;
1891        // XXX
1892        case LBS_SPECULAR:
1893                default:
1894            src1op = 0;
1895        }
1896
1897        switch (bm.source2)
1898        {
1899        case LBS_CURRENT:
1900            src2op = GL_PREVIOUS;
1901            break;
1902        case LBS_TEXTURE:
1903            src2op = GL_TEXTURE;
1904            break;
1905        case LBS_MANUAL:
1906                        src2op = GL_CONSTANT;
1907                        break;
1908                case LBS_DIFFUSE:
1909            src2op = GL_PRIMARY_COLOR;
1910                        break;
1911        // XXX
1912        case LBS_SPECULAR:
1913                default:
1914            src2op = 0;
1915        }
1916
1917        switch (bm.operation)
1918        {
1919        case LBX_SOURCE1:
1920            cmd = GL_REPLACE;
1921            break;
1922        case LBX_SOURCE2:
1923            cmd = GL_REPLACE;
1924            break;
1925        case LBX_MODULATE:
1926            cmd = GL_MODULATE;
1927            break;
1928        case LBX_MODULATE_X2:
1929            cmd = GL_MODULATE;
1930            break;
1931        case LBX_MODULATE_X4:
1932            cmd = GL_MODULATE;
1933            break;
1934        case LBX_ADD:
1935            cmd = GL_ADD;
1936            break;
1937        case LBX_ADD_SIGNED:
1938            cmd = GL_ADD_SIGNED;
1939            break;
1940        case LBX_SUBTRACT:
1941            cmd = GL_SUBTRACT;
1942            break;
1943        case LBX_BLEND_DIFFUSE_ALPHA:
1944            cmd = GL_INTERPOLATE;
1945            break;
1946        case LBX_BLEND_TEXTURE_ALPHA:
1947            cmd = GL_INTERPOLATE;
1948            break;
1949        case LBX_BLEND_CURRENT_ALPHA:
1950            cmd = GL_INTERPOLATE;
1951            break;
1952        case LBX_BLEND_MANUAL:
1953            cmd = GL_INTERPOLATE;
1954            break;
1955        case LBX_DOTPRODUCT:
1956            cmd = mCapabilities->hasCapability(RSC_DOT3)
1957                ? GL_DOT3_RGB : GL_MODULATE;
1958            break;
1959                default:
1960            cmd = 0;
1961        }
1962
1963                glActiveTextureARB_ptr(GL_TEXTURE0 + stage);
1964                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1965
1966            if (bm.blendType == LBT_COLOUR)
1967            {
1968                    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, cmd);
1969                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, src1op);
1970                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, src2op);
1971                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
1972            }
1973            else
1974            {
1975                    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, cmd);
1976                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, src1op);
1977                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, src2op);
1978                    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
1979            }
1980
1981        float blendValue[4] = {0, 0, 0, bm.factor};
1982        switch (bm.operation)
1983        {
1984        case LBX_BLEND_DIFFUSE_ALPHA:
1985            glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
1986            glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
1987            break;
1988        case LBX_BLEND_TEXTURE_ALPHA:
1989                        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
1990                        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE);
1991            break;
1992        case LBX_BLEND_CURRENT_ALPHA:
1993                        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);
1994                        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS);
1995            break;
1996        case LBX_BLEND_MANUAL:
1997            glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendValue);
1998            break;
1999        default:
2000            break;
2001        };
2002
2003        switch (bm.operation)
2004        {
2005        case LBX_MODULATE_X2:
2006                        glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
2007                GL_RGB_SCALE : GL_ALPHA_SCALE, 2);
2008            break;
2009        case LBX_MODULATE_X4:
2010                        glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
2011                GL_RGB_SCALE : GL_ALPHA_SCALE, 4);
2012            break;
2013        default:
2014                        glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
2015                GL_RGB_SCALE : GL_ALPHA_SCALE, 1);
2016            break;
2017                }
2018
2019                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
2020                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
2021                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
2022                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
2023                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
2024                glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
2025        if(bm.source1 == LBS_MANUAL)
2026            glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv1);
2027        if (bm.source2 == LBS_MANUAL)
2028            glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv2);
2029
2030        glActiveTextureARB_ptr(GL_TEXTURE0);
2031        }
2032    //---------------------------------------------------------------------
2033    void GLRenderSystem::setGLLightPositionDirection(Light* lt, GLenum lightindex)
2034    {
2035        // Set position / direction
2036        Vector4 vec;
2037                // Use general 4D vector which is the same as GL's approach
2038                vec = lt->getAs4DVector();
2039
2040#if OGRE_DOUBLE_PRECISION
2041                // Must convert to float*
2042                float tmp[4] = {vec.x, vec.y, vec.z, vec.w};
2043                glLightfv(lightindex, GL_POSITION, tmp);
2044#else
2045                glLightfv(lightindex, GL_POSITION, vec.val);
2046#endif
2047                // Set spotlight direction
2048        if (lt->getType() == Light::LT_SPOTLIGHT)
2049        {
2050            vec = lt->getDerivedDirection();
2051            vec.w = 0.0;
2052#if OGRE_DOUBLE_PRECISION
2053                        // Must convert to float*
2054                        float tmp2[4] = {vec.x, vec.y, vec.z, vec.w};
2055                        glLightfv(lightindex, GL_SPOT_DIRECTION, tmp2);
2056#else
2057            glLightfv(lightindex, GL_SPOT_DIRECTION, vec.val);
2058#endif
2059        }
2060    }
2061    //---------------------------------------------------------------------
2062        void GLRenderSystem::setVertexDeclaration(VertexDeclaration* decl)
2063        {
2064        }
2065    //---------------------------------------------------------------------
2066        void GLRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
2067        {
2068        }
2069    //---------------------------------------------------------------------
2070    void GLRenderSystem::_render(const RenderOperation& op)
2071        {
2072        // Guard
2073        OgreGuard ("GLRenderSystem::_render");
2074        // Call super class
2075        RenderSystem::_render(op);
2076
2077        void* pBufferData = 0;
2078       
2079        const VertexDeclaration::VertexElementList& decl =
2080            op.vertexData->vertexDeclaration->getElements();
2081        VertexDeclaration::VertexElementList::const_iterator elem, elemEnd;
2082        elemEnd = decl.end();
2083
2084        for (elem = decl.begin(); elem != elemEnd; ++elem)
2085        {
2086            HardwareVertexBufferSharedPtr vertexBuffer =
2087                op.vertexData->vertexBufferBinding->getBuffer(elem->getSource());
2088            if(mCapabilities->hasCapability(RSC_VBO))
2089            {
2090                glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB,
2091                    static_cast<const GLHardwareVertexBuffer*>(vertexBuffer.get())->getGLBufferId());
2092                pBufferData = VBO_BUFFER_OFFSET(elem->getOffset());
2093            }
2094            else
2095            {
2096                pBufferData = static_cast<const GLDefaultHardwareVertexBuffer*>(vertexBuffer.get())->getDataPtr(elem->getOffset());
2097            }
2098
2099            unsigned int i = 0;
2100
2101            switch(elem->getSemantic())
2102            {
2103            case VES_POSITION:
2104                glVertexPointer(VertexElement::getTypeCount(
2105                    elem->getType()),
2106                    GLHardwareBufferManager::getGLType(elem->getType()),
2107                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2108                    pBufferData);
2109                glEnableClientState( GL_VERTEX_ARRAY );
2110                break;
2111            case VES_NORMAL:
2112                glNormalPointer(
2113                    GLHardwareBufferManager::getGLType(elem->getType()),
2114                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2115                    pBufferData);
2116                glEnableClientState( GL_NORMAL_ARRAY );
2117                break;
2118            case VES_DIFFUSE:
2119                glColorPointer(4,
2120                    GLHardwareBufferManager::getGLType(elem->getType()),
2121                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2122                    pBufferData);
2123                glEnableClientState( GL_COLOR_ARRAY );
2124                break;
2125            case VES_SPECULAR:
2126                glSecondaryColorPointerEXT_ptr(4,
2127                    GLHardwareBufferManager::getGLType(elem->getType()),
2128                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2129                    pBufferData);
2130                glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
2131                break;
2132            case VES_TEXTURE_COORDINATES:
2133
2134                for (i = 0; i < mCapabilities->getNumTextureUnits(); i++)
2135                {
2136                                        // Only set this texture unit's texcoord pointer if it
2137                                        // is supposed to be using this element's index
2138                                        if (mTextureCoordIndex[i] == elem->getIndex())
2139                                        {
2140                                                glClientActiveTextureARB_ptr(GL_TEXTURE0 + i);
2141                                                glTexCoordPointer(
2142                                                        VertexElement::getTypeCount(elem->getType()),
2143                                                        GLHardwareBufferManager::getGLType(elem->getType()),
2144                            static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2145                                pBufferData);
2146                                                glEnableClientState( GL_TEXTURE_COORD_ARRAY );
2147                                        }
2148                }
2149                break;
2150            case VES_BLEND_INDICES:
2151                assert(mCapabilities->hasCapability(RSC_VERTEX_PROGRAM));
2152                glVertexAttribPointerARB_ptr(
2153                    7, // matrix indices are vertex attribute 7 (no def?)
2154                    VertexElement::getTypeCount(elem->getType()),
2155                    GLHardwareBufferManager::getGLType(elem->getType()),
2156                    GL_FALSE, // normalisation disabled
2157                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2158                    pBufferData);
2159                glEnableVertexAttribArrayARB_ptr(7);
2160                break;
2161            case VES_BLEND_WEIGHTS:
2162                assert(mCapabilities->hasCapability(RSC_VERTEX_PROGRAM));
2163                glVertexAttribPointerARB_ptr(
2164                    1, // weights are vertex attribute 1 (no def?)
2165                    VertexElement::getTypeCount(elem->getType()),
2166                    GLHardwareBufferManager::getGLType(elem->getType()),
2167                    GL_FALSE, // normalisation disabled
2168                    static_cast<GLsizei>(vertexBuffer->getVertexSize()),
2169                    pBufferData);
2170                glEnableVertexAttribArrayARB_ptr(1);
2171                break;
2172            default:
2173                break;
2174            };
2175
2176        }
2177
2178        glClientActiveTextureARB_ptr(GL_TEXTURE0);
2179
2180        // Find the correct type to render
2181        GLint primType;
2182        switch (op.operationType)
2183        {
2184        case RenderOperation::OT_POINT_LIST:
2185            primType = GL_POINTS;
2186            break;
2187        case RenderOperation::OT_LINE_LIST:
2188            primType = GL_LINES;
2189            break;
2190        case RenderOperation::OT_LINE_STRIP:
2191            primType = GL_LINE_STRIP;
2192            break;
2193        case RenderOperation::OT_TRIANGLE_LIST:
2194            primType = GL_TRIANGLES;
2195            break;
2196        case RenderOperation::OT_TRIANGLE_STRIP:
2197            primType = GL_TRIANGLE_STRIP;
2198            break;
2199        case RenderOperation::OT_TRIANGLE_FAN:
2200            primType = GL_TRIANGLE_FAN;
2201            break;
2202        }
2203
2204        if (op.useIndexes)
2205        {
2206            if(mCapabilities->hasCapability(RSC_VBO))
2207            {
2208                glBindBufferARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB,
2209                    static_cast<GLHardwareIndexBuffer*>(
2210                        op.indexData->indexBuffer.get())->getGLBufferId());
2211
2212                pBufferData = VBO_BUFFER_OFFSET(
2213                    op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
2214            }
2215            else
2216            {
2217                pBufferData = static_cast<GLDefaultHardwareIndexBuffer*>(
2218                    op.indexData->indexBuffer.get())->getDataPtr(
2219                        op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
2220            }
2221
2222            GLenum indexType = (op.indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
2223
2224            glDrawElements(primType, op.indexData->indexCount, indexType, pBufferData);
2225
2226        }
2227        else
2228        {
2229            glDrawArrays(primType, op.vertexData->vertexStart,
2230                op.vertexData->vertexCount);
2231        }
2232
2233        glDisableClientState( GL_VERTEX_ARRAY );
2234        for (int i = 0; i < mCapabilities->getNumTextureUnits(); i++)
2235        {
2236            glClientActiveTextureARB_ptr(GL_TEXTURE0 + i);
2237            glDisableClientState( GL_TEXTURE_COORD_ARRAY );
2238        }
2239        glClientActiveTextureARB_ptr(GL_TEXTURE0);
2240        glDisableClientState( GL_NORMAL_ARRAY );
2241        glDisableClientState( GL_COLOR_ARRAY );
2242        glDisableClientState( GL_SECONDARY_COLOR_ARRAY );
2243        if (mCapabilities->hasCapability(RSC_VERTEX_PROGRAM))
2244        {
2245            glDisableVertexAttribArrayARB_ptr(7); // disable indices
2246            glDisableVertexAttribArrayARB_ptr(1); // disable weights
2247        }
2248        glColor4f(1,1,1,1);
2249        glSecondaryColor3fEXT_ptr(0.0f, 0.0f, 0.0f);
2250
2251        // UnGuard
2252        OgreUnguard();
2253        }
2254    //---------------------------------------------------------------------
2255    void GLRenderSystem::setNormaliseNormals(bool normalise)
2256    {
2257        if (normalise)
2258            glEnable(GL_NORMALIZE);
2259        else
2260            glDisable(GL_NORMALIZE);
2261
2262    }
2263        //---------------------------------------------------------------------
2264    void GLRenderSystem::bindGpuProgram(GpuProgram* prg)
2265    {
2266        GLGpuProgram* glprg = static_cast<GLGpuProgram*>(prg);
2267        glprg->bindProgram();
2268        if (glprg->getType() == GPT_VERTEX_PROGRAM)
2269        {
2270            mCurrentVertexProgram = glprg;
2271        }
2272        else
2273        {
2274            mCurrentFragmentProgram = glprg;
2275        }
2276    }
2277        //---------------------------------------------------------------------
2278    void GLRenderSystem::unbindGpuProgram(GpuProgramType gptype)
2279    {
2280
2281        if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram)
2282        {
2283            mCurrentVertexProgram->unbindProgram();
2284            mCurrentVertexProgram = 0;
2285        }
2286        else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram)
2287        {
2288            mCurrentFragmentProgram->unbindProgram();
2289            mCurrentFragmentProgram = 0;
2290        }
2291
2292
2293    }
2294        //---------------------------------------------------------------------
2295    void GLRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params)
2296    {
2297        if (gptype == GPT_VERTEX_PROGRAM)
2298        {
2299            mCurrentVertexProgram->bindProgramParameters(params);
2300        }
2301        else
2302        {
2303            mCurrentFragmentProgram->bindProgramParameters(params);
2304        }
2305    }
2306        //---------------------------------------------------------------------
2307    void GLRenderSystem::setClipPlanes(const PlaneList& clipPlanes)
2308    {
2309        size_t i;
2310        size_t numClipPlanes;
2311        GLdouble clipPlane[4];
2312
2313        numClipPlanes = clipPlanes.size();
2314        for (i = 0; i < numClipPlanes; ++i)
2315        {
2316            GLenum clipPlaneId = static_cast<GLenum>(GL_CLIP_PLANE0 + i);
2317            const Plane& plane = clipPlanes[i];
2318
2319            if (i >= GL_MAX_CLIP_PLANES)
2320            {
2321                OGRE_EXCEPT(0, "Unable to set clip plane",
2322                    "GLRenderSystem::setClipPlanes");
2323            }
2324
2325            clipPlane[0] = plane.normal.x;
2326            clipPlane[1] = plane.normal.y;
2327            clipPlane[2] = plane.normal.z;
2328            clipPlane[3] = -plane.d;
2329
2330            glClipPlane(clipPlaneId, clipPlane);
2331            glEnable(clipPlaneId);
2332        }
2333
2334            // disable remaining clip planes
2335        for ( ; i < 6/*GL_MAX_CLIP_PLANES*/; ++i)
2336        {
2337            glDisable(static_cast<GLenum>(GL_CLIP_PLANE0 + i));
2338        }
2339    }
2340        //---------------------------------------------------------------------
2341    void GLRenderSystem::setScissorTest(bool enabled, size_t left,
2342        size_t top, size_t right, size_t bottom)
2343    {
2344        //  GL measures from the bottom, not the top
2345        size_t targetHeight = mActiveRenderTarget->getHeight();
2346        // Calculate the "lower-left" corner of the viewport
2347        GLsizei w, h, x, y;
2348
2349        if (enabled)
2350        {
2351            glEnable(GL_SCISSOR_TEST);
2352            // NB GL uses width / height rather than right / bottom
2353            x = left;
2354            y = targetHeight - bottom;
2355            w = right - left;
2356            h = bottom - top;
2357            glScissor(x, y, w, h);
2358        }
2359        else
2360        {
2361            glDisable(GL_SCISSOR_TEST);
2362            // GL requires you to reset the scissor when disabling
2363            w = mActiveViewport->getActualWidth();
2364            h = mActiveViewport->getActualHeight();
2365            x = mActiveViewport->getActualLeft();
2366            y = targetHeight - mActiveViewport->getActualTop() - h;
2367            glScissor(x, y, w, h);
2368        }
2369    }
2370    //---------------------------------------------------------------------
2371    void GLRenderSystem::clearFrameBuffer(unsigned int buffers,
2372        const ColourValue& colour, Real depth, unsigned short stencil)
2373    {
2374
2375        GLbitfield flags = 0;
2376        if (buffers & FBT_COLOUR)
2377        {
2378            flags |= GL_COLOR_BUFFER_BIT;
2379        }
2380        if (buffers & FBT_DEPTH)
2381        {
2382            flags |= GL_DEPTH_BUFFER_BIT;
2383        }
2384        if (buffers & FBT_STENCIL)
2385        {
2386            flags |= GL_STENCIL_BUFFER_BIT;
2387        }
2388
2389
2390        // Enable depth & colour buffer for writing if it isn't
2391
2392        if (!mDepthWrite)
2393        {
2394            glDepthMask( GL_TRUE );
2395        }
2396        bool colourMask = !mColourWrite[0] || !mColourWrite[1]
2397        || !mColourWrite[2] || mColourWrite[3];
2398        if (colourMask)
2399        {
2400            glColorMask(true, true, true, true);
2401        }
2402        // Set values
2403        glClearColor(colour.r, colour.g, colour.b, colour.a);
2404        glClearDepth(depth);
2405        glClearStencil(stencil);
2406        // Clear buffers
2407        glClear(flags);
2408        // Reset depth write state if appropriate
2409        // Enable depth buffer for writing if it isn't
2410        if (!mDepthWrite)
2411        {
2412            glDepthMask( GL_FALSE );
2413        }
2414        if (colourMask)
2415        {
2416            glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
2417        }
2418
2419    }
2420    // ------------------------------------------------------------------
2421    void GLRenderSystem::_makeProjectionMatrix(Real left, Real right,
2422        Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest,
2423        bool forGpuProgram)
2424    {
2425        Real width = right - left;
2426        Real height = top - bottom;
2427        Real q, qn;
2428        if (farPlane == 0)
2429        {
2430            // Infinite far plane
2431            q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
2432            qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
2433        }
2434        else
2435        {
2436            q = -(farPlane + nearPlane) / (farPlane - nearPlane);
2437            qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
2438        }
2439        dest = Matrix4::ZERO;
2440        dest[0][0] = 2 * nearPlane / width;
2441        dest[0][2] = (right+left) / width;
2442        dest[1][1] = 2 * nearPlane / height;
2443        dest[1][2] = (top+bottom) / height;
2444        dest[2][2] = q;
2445        dest[2][3] = qn;
2446        dest[3][2] = -1;
2447    }
2448
2449    // ------------------------------------------------------------------
2450    void GLRenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D)
2451    {
2452        if (ushort(mClipPlanes.size()) < index+1)
2453            mClipPlanes.resize(index+1);
2454        mClipPlanes[index] = Vector4 (A, B, C, D);
2455        GLdouble plane[4] = { A, B, C, D };
2456        glClipPlane (GL_CLIP_PLANE0 + index, plane);
2457    }
2458
2459    // ------------------------------------------------------------------
2460    void GLRenderSystem::setGLClipPlanes() const
2461    {
2462        size_t size = mClipPlanes.size();
2463        for (size_t i=0; i<size; i++)
2464        {
2465            const Vector4 &p = mClipPlanes[i];
2466            GLdouble plane[4] = { p.x, p.y, p.z, p.w };
2467            glClipPlane (GL_CLIP_PLANE0 + i, plane);
2468        }
2469    }
2470
2471    // ------------------------------------------------------------------
2472    void GLRenderSystem::enableClipPlane (ushort index, bool enable)
2473    {
2474        glEnable (GL_CLIP_PLANE0 + index);
2475    }
2476    //---------------------------------------------------------------------
2477    HardwareOcclusionQuery* GLRenderSystem::createHardwareOcclusionQuery(void)
2478    {
2479        return new GLHardwareOcclusionQuery();
2480    }
2481    //---------------------------------------------------------------------
2482    Real GLRenderSystem::getHorizontalTexelOffset(void)
2483    {
2484        // No offset in GL
2485        return 0.0f;
2486    }
2487    //---------------------------------------------------------------------
2488    Real GLRenderSystem::getVerticalTexelOffset(void)
2489    {
2490        // No offset in GL
2491        return 0.0f;
2492    }
2493        //---------------------------------------------------------------------
2494        void GLRenderSystem::resizeRepositionWindow(void* wich)
2495        {
2496                mGLSupport->resizeRepositionWindow(wich);
2497                for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it)           
2498                {
2499                        if (it->second->isActive())
2500                        {
2501                                mGLSupport->resizeReposition(it->second);
2502                        }
2503                }
2504        }
2505    //---------------------------------------------------------------------
2506    void GLRenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane,
2507        bool forGpuProgram)
2508    {
2509        // Thanks to Eric Lenyel for posting this calculation at www.terathon.com
2510
2511        // Calculate the clip-space corner point opposite the clipping plane
2512        // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
2513        // transform it into camera space by multiplying it
2514        // by the inverse of the projection matrix
2515
2516        Vector4 q;
2517        q.x = (Math::Sign(plane.normal.x) + matrix[0][2]) / matrix[0][0];
2518        q.y = (Math::Sign(plane.normal.y) + matrix[1][2]) / matrix[1][1];
2519        q.z = -1.0F;
2520        q.w = (1.0F + matrix[2][2]) / matrix[2][3];
2521
2522        // Calculate the scaled plane vector
2523        Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d);
2524        Vector4 c = clipPlane4d * (2.0F / (clipPlane4d.dotProduct(q)));
2525
2526        // Replace the third row of the projection matrix
2527        matrix[2][0] = c.x;
2528        matrix[2][1] = c.y;
2529        matrix[2][2] = c.z + 1.0F;
2530        matrix[2][3] = c.w;
2531    }
2532    //---------------------------------------------------------------------
2533    void GLRenderSystem::_oneTimeContextInitialization()
2534    {
2535        // Set nicer lighting model -- d3d9 has this by default
2536        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
2537        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);       
2538        glEnable(GL_COLOR_SUM);
2539
2540        // Check for FSAA
2541        // Enable the extension if it was enabled by the GLSupport
2542        if (mGLSupport->checkExtension("GL_ARB_multisample"))
2543        {
2544            int fsaa_active = false;
2545            glGetIntegerv(GL_SAMPLE_BUFFERS_ARB,(GLint*)&fsaa_active);
2546            if(fsaa_active)
2547            {
2548                glEnable(GL_MULTISAMPLE_ARB);
2549                LogManager::getSingleton().logMessage("Using FSAA from GL_ARB_multisample extension.");
2550            }           
2551        }
2552    }
2553    //---------------------------------------------------------------------
2554    void GLRenderSystem::_setRenderTarget(RenderTarget *target)
2555    {
2556        mActiveRenderTarget = target;
2557        // Switch context if different from current one
2558        ContextMap::iterator i = mContextMap.find(target);
2559        if(i != mContextMap.end() && mCurrentContext != i->second) {
2560            mCurrentContext->endCurrent();
2561            mCurrentContext = i->second;
2562            // Check if the context has already done one-time initialisation
2563            if(!mCurrentContext->getInitialized()) {
2564               _oneTimeContextInitialization();
2565               mCurrentContext->setInitialized();
2566            }
2567            mCurrentContext->setCurrent();
2568        }
2569    }
2570    //---------------------------------------------------------------------
2571    void GLRenderSystem::_registerContext(RenderTarget *target, GLContext *context)
2572    {
2573        mContextMap[target] = context;
2574    }
2575    //---------------------------------------------------------------------
2576    void GLRenderSystem::_unregisterContext(RenderTarget *target)
2577    {
2578        ContextMap::iterator i = mContextMap.find(target);
2579        if(i != mContextMap.end() && mCurrentContext == i->second) {
2580            // Change the context to something else so that a valid context
2581            // remains active. When this is the main context being unregistered,
2582            // we set the main context to 0.
2583            if(mCurrentContext != mMainContext) {
2584                mCurrentContext->endCurrent();
2585                mCurrentContext = mMainContext;
2586                mCurrentContext->setCurrent();
2587            } else {
2588                mMainContext = 0;
2589            }
2590        }
2591        mContextMap.erase(target);
2592    }
2593    //---------------------------------------------------------------------
2594    GLContext *GLRenderSystem::_getMainContext() {
2595        return mMainContext;
2596    }
2597    //---------------------------------------------------------------------
2598    Real GLRenderSystem::getMinimumDepthInputValue(void)
2599    {
2600        // Range [-1.0f, 1.0f]
2601        return -1.0f;
2602    }
2603    //---------------------------------------------------------------------
2604    Real GLRenderSystem::getMaximumDepthInputValue(void)
2605    {
2606        // Range [-1.0f, 1.0f]
2607        return 1.0f;
2608    }
2609
2610}
Note: See TracBrowser for help on using the repository browser.