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

Revision 343, 95.1 KB checked in by mattausch, 19 years ago (diff)

added switch between NV and ARB queries in the render system and in the demos.
Fixed render queue bug: when clearing queue, we traversed through all priority groups
to clear the passmaps. This became very slow because had to traverse many elements (over 1000
for city demo). Now all we destroy the priority groups for each rendering (per hierarchy node).

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