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

Revision 193, 94.9 KB checked in by mattausch, 19 years ago (diff)

changed to ogre 103
added readme

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