1 /*
2  -----------------------------------------------------------------------------
3  This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5  For the latest info, see http://www.ogre3d.org/
6 
7  Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25  THE SOFTWARE.
26  -----------------------------------------------------------------------------
27  */
28 
29 #include "OgreStableHeaders.h"
30 #include "OgreGLStateCacheManagerImp.h"
31 #include "OgreGLRenderSystem.h"
32 #include "OgreLogManager.h"
33 #include "OgreRoot.h"
34 
35 namespace Ogre {
36 
GLStateCacheManagerImp(void)37     GLStateCacheManagerImp::GLStateCacheManagerImp(void)
38     {
39         clearCache();
40     }
41 
initializeCache()42     void GLStateCacheManagerImp::initializeCache()
43     {
44         glBlendEquation(GL_FUNC_ADD);
45 
46         if(GLEW_VERSION_2_0)
47         {
48             glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
49         }
50         else if(GLEW_EXT_blend_equation_separate)
51         {
52             glBlendEquationSeparateEXT(GL_FUNC_ADD, GL_FUNC_ADD);
53         }
54 
55         glBlendFunc(GL_ONE, GL_ZERO);
56 
57         glCullFace(mCullFace);
58 
59         glDepthFunc(mDepthFunc);
60 
61         glDepthMask(mDepthMask);
62 
63         glStencilMask(mStencilMask);
64 
65         glClearDepth(mClearDepth);
66 
67         glBindTexture(GL_TEXTURE_2D, 0);
68 
69         glBindBuffer(GL_ARRAY_BUFFER, 0);
70 
71         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
72 
73         glBindFramebuffer(GL_FRAMEBUFFER, 0);
74 
75         glBindRenderbuffer(GL_RENDERBUFFER, 0);
76 
77         glActiveTexture(GL_TEXTURE0);
78 
79         glClearColor(mClearColour[0], mClearColour[1], mClearColour[2], mClearColour[3]);
80 
81         glColorMask(mColourMask[0], mColourMask[1], mColourMask[2], mColourMask[3]);
82 
83         glPolygonMode(GL_FRONT_AND_BACK, mPolygonMode);
84     }
85 
clearCache()86     void GLStateCacheManagerImp::clearCache()
87     {
88         mDepthMask = GL_TRUE;
89         mBlendEquation = GL_FUNC_ADD;
90         mBlendEquationRGB = GL_FUNC_ADD;
91         mBlendEquationAlpha = GL_FUNC_ADD;
92         mCullFace = GL_BACK;
93         mDepthFunc = GL_LESS;
94         mStencilMask = 0xFFFFFFFF;
95         mActiveTextureUnit = 0;
96         mDiscardBuffers = 0;
97         mClearDepth = 1.0f;
98         mLastBoundTexID = 0;
99         mShininess = 0.0f;
100         mPolygonMode = GL_FILL;
101         mShadeModel = GL_SMOOTH;
102 
103         // Initialize our cache variables and also the GL so that the
104         // stored values match the GL state
105         mBlendFuncSource = GL_ONE;
106         mBlendFuncDest = GL_ZERO;
107 
108         mClearColour.resize(4);
109         mClearColour[0] = mClearColour[1] = mClearColour[2] = mClearColour[3] = 0.0f;
110 
111         mColourMask.resize(4);
112         mColourMask[0] = mColourMask[1] = mColourMask[2] = mColourMask[3] = GL_TRUE;
113 
114         mEnableVector.reserve(10);
115         mEnableVector.clear();
116         mActiveBufferMap.clear();
117         mTexUnitsMap.clear();
118         mTextureCoordGen.clear();
119 
120         mViewport[0] = 0.0f;
121         mViewport[1] = 0.0f;
122         mViewport[2] = 0.0f;
123         mViewport[3] = 0.0f;
124 
125         mAmbient[0] = 0.2f;
126         mAmbient[1] = 0.2f;
127         mAmbient[2] = 0.2f;
128         mAmbient[3] = 1.0f;
129 
130         mDiffuse[0] = 0.8f;
131         mDiffuse[1] = 0.8f;
132         mDiffuse[2] = 0.8f;
133         mDiffuse[3] = 1.0f;
134 
135         mSpecular[0] = 0.0f;
136         mSpecular[1] = 0.0f;
137         mSpecular[2] = 0.0f;
138         mSpecular[3] = 1.0f;
139 
140         mEmissive[0] = 0.0f;
141         mEmissive[1] = 0.0f;
142         mEmissive[2] = 0.0f;
143         mEmissive[3] = 1.0f;
144 
145         mLightAmbient[0] = 0.2f;
146         mLightAmbient[1] = 0.2f;
147         mLightAmbient[2] = 0.2f;
148         mLightAmbient[3] = 1.0f;
149 
150         mPointSize = 1.0f;
151         mPointSizeMin = 1.0f;
152         mPointSizeMax = 1.0f;
153         mPointAttenuation[0] = 1.0f;
154         mPointAttenuation[1] = 0.0f;
155         mPointAttenuation[2] = 0.0f;
156     }
157 
~GLStateCacheManagerImp(void)158     GLStateCacheManagerImp::~GLStateCacheManagerImp(void)
159     {
160         mColourMask.clear();
161         mClearColour.clear();
162         mActiveBufferMap.clear();
163         mEnableVector.clear();
164         mTexUnitsMap.clear();
165         mTextureCoordGen.clear();
166     }
167 
bindGLBuffer(GLenum target,GLuint buffer,GLenum attach,bool force)168     void GLStateCacheManagerImp::bindGLBuffer(GLenum target, GLuint buffer, GLenum attach, bool force)
169     {
170 		bool update = false;
171         BindBufferMap::iterator i = mActiveBufferMap.find(target);
172         if (i == mActiveBufferMap.end())
173         {
174             // Haven't cached this state yet.  Insert it into the map
175             mActiveBufferMap.insert(BindBufferMap::value_type(target, buffer));
176 			update = true;
177         }
178         else if((*i).second != buffer || force) // Update the cached value if needed
179         {
180 			(*i).second = buffer;
181 			update = true;
182         }
183 
184 		// Update GL
185 		if(update)
186 		{
187             if(target == GL_FRAMEBUFFER)
188             {
189                 glBindFramebuffer(target, buffer);
190             }
191             else if(target == GL_RENDERBUFFER)
192             {
193                 glBindRenderbuffer(target, buffer);
194             }
195             else
196             {
197                 glBindBuffer(target, buffer);
198             }
199 		}
200 
201     }
202 
deleteGLBuffer(GLenum target,GLuint buffer,GLenum attach,bool force)203     void GLStateCacheManagerImp::deleteGLBuffer(GLenum target, GLuint buffer, GLenum attach, bool force)
204     {
205         // Buffer name 0 is reserved and we should never try to delete it
206         if(buffer == 0)
207             return;
208 
209         BindBufferMap::iterator i = mActiveBufferMap.find(target);
210 
211         if (i != mActiveBufferMap.end() && ((*i).second == buffer || force))
212         {
213 			if(target == GL_FRAMEBUFFER)
214             {
215 				glDeleteFramebuffers(1, &buffer);
216             }
217             else if(target == GL_RENDERBUFFER)
218             {
219 				glDeleteRenderbuffers(1, &buffer);
220             }
221             else
222             {
223 				glDeleteBuffers(1, &buffer);
224             }
225 
226             // Currently bound buffer is being deleted, update the cached value to 0,
227             // which it likely the buffer that will be bound by the driver.
228             // An update will be forced next time we try to bind on this target.
229             (*i).second = 0;
230         }
231     }
232 
invalidateStateForTexture(GLuint texture)233     void GLStateCacheManagerImp::invalidateStateForTexture(GLuint texture)
234     {
235         mTexUnitsMap.erase(texture);
236     }
237 
238     // TODO: Store as high/low bits of a GLuint, use vector instead of map for TexParameteriMap
setTexParameteri(GLenum target,GLenum pname,GLint param)239     void GLStateCacheManagerImp::setTexParameteri(GLenum target, GLenum pname, GLint param)
240     {
241         // Check if we have a map entry for this texture id. If not, create a blank one and insert it.
242         TexUnitsMap::iterator it = mTexUnitsMap.find(mLastBoundTexID);
243         if (it == mTexUnitsMap.end())
244         {
245             TextureUnitParams unit;
246             mTexUnitsMap[mLastBoundTexID] = unit;
247 
248             // Update the iterator
249             it = mTexUnitsMap.find(mLastBoundTexID);
250         }
251 
252         // Get a local copy of the parameter map and search for this parameter
253         TexParameteriMap &myMap = (*it).second.mTexParameteriMap;
254         TexParameteriMap::iterator i = myMap.find(pname);
255 
256         if (i == myMap.end())
257         {
258             // Haven't cached this state yet.  Insert it into the map
259             myMap.insert(TexParameteriMap::value_type(pname, param));
260 
261             // Update GL
262             glTexParameteri(target, pname, param);
263         }
264         else
265         {
266             // Update the cached value if needed
267             if((*i).second != param)
268             {
269                 (*i).second = param;
270 
271                 // Update GL
272                 glTexParameteri(target, pname, param);
273             }
274         }
275     }
276 
bindGLTexture(GLenum target,GLuint texture)277     void GLStateCacheManagerImp::bindGLTexture(GLenum target, GLuint texture)
278     {
279         mLastBoundTexID = texture;
280 
281         // Update GL
282         glBindTexture(target, texture);
283     }
284 
activateGLTextureUnit(size_t unit)285     bool GLStateCacheManagerImp::activateGLTextureUnit(size_t unit)
286 	{
287 		if (mActiveTextureUnit != unit)
288 		{
289 			if (unit < dynamic_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem())->getCapabilities()->getNumTextureUnits())
290 			{
291 				glActiveTexture(GL_TEXTURE0 + unit);
292 				mActiveTextureUnit = unit;
293 				return true;
294 			}
295 			else if (!unit)
296 			{
297 				// always ok to use the first unit
298 				return true;
299 			}
300 			else
301 			{
302 				return false;
303 			}
304 		}
305 		else
306 		{
307 			return true;
308 		}
309 	}
310 
311     // TODO: Store as high/low bits of a GLuint
setBlendFunc(GLenum source,GLenum dest)312     void GLStateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest)
313     {
314         if(mBlendFuncSource != source || mBlendFuncDest != dest)
315         {
316             mBlendFuncSource = source;
317             mBlendFuncDest = dest;
318 
319             glBlendFunc(source, dest);
320         }
321     }
322 
setDepthMask(GLboolean mask)323     void GLStateCacheManagerImp::setDepthMask(GLboolean mask)
324     {
325         if(mDepthMask != mask)
326         {
327             mDepthMask = mask;
328 
329             glDepthMask(mask);
330         }
331     }
332 
setDepthFunc(GLenum func)333     void GLStateCacheManagerImp::setDepthFunc(GLenum func)
334     {
335         if(mDepthFunc != func)
336         {
337             mDepthFunc = func;
338 
339             glDepthFunc(func);
340         }
341     }
342 
setClearDepth(GLclampf depth)343     void GLStateCacheManagerImp::setClearDepth(GLclampf depth)
344     {
345         if(mClearDepth != depth)
346         {
347             mClearDepth = depth;
348 
349             glClearDepth(depth);
350         }
351     }
352 
setClearColour(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)353     void GLStateCacheManagerImp::setClearColour(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
354     {
355         if((mClearColour[0] != red) ||
356            (mClearColour[1] != green) ||
357            (mClearColour[2] != blue) ||
358            (mClearColour[3] != alpha))
359         {
360             mClearColour[0] = red;
361             mClearColour[1] = green;
362             mClearColour[2] = blue;
363             mClearColour[3] = alpha;
364 
365             glClearColor(mClearColour[0], mClearColour[1], mClearColour[2], mClearColour[3]);
366         }
367     }
368 
setColourMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)369     void GLStateCacheManagerImp::setColourMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
370     {
371         if((mColourMask[0] != red) ||
372            (mColourMask[1] != green) ||
373            (mColourMask[2] != blue) ||
374            (mColourMask[3] != alpha))
375         {
376             mColourMask[0] = red;
377             mColourMask[1] = green;
378             mColourMask[2] = blue;
379             mColourMask[3] = alpha;
380 
381             glColorMask(mColourMask[0], mColourMask[1], mColourMask[2], mColourMask[3]);
382         }
383     }
384 
setStencilMask(GLuint mask)385     void GLStateCacheManagerImp::setStencilMask(GLuint mask)
386     {
387         if(mStencilMask != mask)
388         {
389             mStencilMask = mask;
390 
391             glStencilMask(mask);
392         }
393     }
394 
setEnabled(GLenum flag)395     void GLStateCacheManagerImp::setEnabled(GLenum flag)
396     {
397         bool found = std::find(mEnableVector.begin(), mEnableVector.end(), flag) != mEnableVector.end();
398         if(!found)
399         {
400             mEnableVector.push_back(flag);
401 
402             glEnable(flag);
403         }
404     }
405 
setDisabled(GLenum flag)406     void GLStateCacheManagerImp::setDisabled(GLenum flag)
407     {
408         vector<GLenum>::iterator iter = std::find(mEnableVector.begin(), mEnableVector.end(), flag);
409         if(iter != mEnableVector.end())
410         {
411             mEnableVector.erase(iter);
412 
413             glDisable(flag);
414         }
415     }
416 
setViewport(GLint x,GLint y,GLsizei width,GLsizei height)417     void GLStateCacheManagerImp::setViewport(GLint x, GLint y, GLsizei width, GLsizei height)
418     {
419         if((mViewport[0] != x) ||
420            (mViewport[1] != y) ||
421            (mViewport[2] != width) ||
422            (mViewport[3] != height))
423         {
424             mViewport[0] = x;
425             mViewport[1] = y;
426             mViewport[2] = width;
427             mViewport[3] = height;
428             glViewport(x, y, width, height);
429         }
430     }
431 
getViewport(int * array)432     void GLStateCacheManagerImp::getViewport(int *array)
433     {
434         for (int i = 0; i < 4; ++i)
435             array[i] = mViewport[i];
436     }
437 
setCullFace(GLenum face)438     void GLStateCacheManagerImp::setCullFace(GLenum face)
439     {
440         if(mCullFace != face)
441         {
442             mCullFace = face;
443 
444             glCullFace(face);
445         }
446     }
447 
setBlendEquation(GLenum eq)448     void GLStateCacheManagerImp::setBlendEquation(GLenum eq)
449     {
450         if(mBlendEquationRGB != eq || mBlendEquationAlpha != eq)
451         {
452             mBlendEquationRGB = eq;
453             mBlendEquationAlpha = eq;
454 
455             if(GLEW_VERSION_1_4 || GLEW_ARB_imaging)
456             {
457                 glBlendEquation(eq);
458             }
459             else if(GLEW_EXT_blend_minmax && (eq == GL_MIN || eq == GL_MAX))
460             {
461                 glBlendEquationEXT(eq);
462             }
463         }
464     }
465 
setBlendEquation(GLenum eqRGB,GLenum eqAlpha)466     void GLStateCacheManagerImp::setBlendEquation(GLenum eqRGB, GLenum eqAlpha)
467     {
468         if(mBlendEquationRGB != eqRGB || mBlendEquationAlpha != eqAlpha)
469         {
470             mBlendEquationRGB = eqRGB;
471             mBlendEquationAlpha = eqAlpha;
472 
473 			if(GLEW_VERSION_2_0)
474             {
475 				glBlendEquationSeparate(eqRGB, eqAlpha);
476 			}
477 			else if(GLEW_EXT_blend_equation_separate)
478             {
479 				glBlendEquationSeparateEXT(eqRGB, eqAlpha);
480 			}
481 		}
482 	}
483 
setMaterialDiffuse(GLfloat r,GLfloat g,GLfloat b,GLfloat a)484     void GLStateCacheManagerImp::setMaterialDiffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
485     {
486         if((mDiffuse[0] != r) ||
487            (mDiffuse[1] != g) ||
488            (mDiffuse[2] != b) ||
489            (mDiffuse[3] != a))
490         {
491             mDiffuse[0] = r;
492             mDiffuse[1] = g;
493             mDiffuse[2] = b;
494             mDiffuse[3] = a;
495 
496             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &mDiffuse[0]);
497         }
498     }
499 
setMaterialAmbient(GLfloat r,GLfloat g,GLfloat b,GLfloat a)500     void GLStateCacheManagerImp::setMaterialAmbient(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
501     {
502         if((mAmbient[0] != r) ||
503            (mAmbient[1] != g) ||
504            (mAmbient[2] != b) ||
505            (mAmbient[3] != a))
506         {
507             mAmbient[0] = r;
508             mAmbient[1] = g;
509             mAmbient[2] = b;
510             mAmbient[3] = a;
511 
512             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &mAmbient[0]);
513         }
514     }
515 
setMaterialEmissive(GLfloat r,GLfloat g,GLfloat b,GLfloat a)516     void GLStateCacheManagerImp::setMaterialEmissive(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
517     {
518         if((mEmissive[0] != r) ||
519            (mEmissive[1] != g) ||
520            (mEmissive[2] != b) ||
521            (mEmissive[3] != a))
522         {
523             mEmissive[0] = r;
524             mEmissive[1] = g;
525             mEmissive[2] = b;
526             mEmissive[3] = a;
527 
528             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &mEmissive[0]);
529         }
530     }
531 
setMaterialSpecular(GLfloat r,GLfloat g,GLfloat b,GLfloat a)532     void GLStateCacheManagerImp::setMaterialSpecular(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
533     {
534         if((mSpecular[0] != r) ||
535            (mSpecular[1] != g) ||
536            (mSpecular[2] != b) ||
537            (mSpecular[3] != a))
538         {
539             mSpecular[0] = r;
540             mSpecular[1] = g;
541             mSpecular[2] = b;
542             mSpecular[3] = a;
543 
544             glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &mSpecular[0]);
545         }
546     }
547 
setMaterialShininess(GLfloat shininess)548     void GLStateCacheManagerImp::setMaterialShininess(GLfloat shininess)
549     {
550         if (mShininess != shininess)
551         {
552             mShininess = shininess;
553             glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
554         }
555     }
556 
setPolygonMode(GLenum mode)557     void GLStateCacheManagerImp::setPolygonMode(GLenum mode)
558     {
559         if (mPolygonMode != mode)
560         {
561             mPolygonMode = mode;
562             glPolygonMode(GL_FRONT_AND_BACK, mPolygonMode);
563         }
564     }
565 
setShadeModel(GLenum model)566     void GLStateCacheManagerImp::setShadeModel(GLenum model)
567     {
568         if (mShadeModel != model)
569         {
570             mShadeModel = model;
571             glShadeModel(model);
572         }
573     }
574 
setLightAmbient(GLfloat r,GLfloat g,GLfloat b)575     void GLStateCacheManagerImp::setLightAmbient(GLfloat r, GLfloat g, GLfloat b)
576     {
577         if((mLightAmbient[0] != r) ||
578            (mLightAmbient[1] != g) ||
579            (mLightAmbient[2] != b))
580         {
581             mLightAmbient[0] = r;
582             mLightAmbient[1] = g;
583             mLightAmbient[2] = b;
584 
585             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &mLightAmbient[0]);
586         }
587     }
588 
setPointSize(GLfloat size)589     void GLStateCacheManagerImp::setPointSize(GLfloat size)
590     {
591         if (mPointSize != size)
592         {
593             mPointSize = size;
594             glPointSize(mPointSize);
595         }
596     }
597 
setPointParameters(GLfloat * attenuation,float minSize,float maxSize)598     void GLStateCacheManagerImp::setPointParameters(GLfloat *attenuation, float minSize, float maxSize)
599     {
600         if (minSize != mPointSizeMin)
601         {
602             mPointSizeMin = minSize;
603             const Ogre::RenderSystemCapabilities* caps = dynamic_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem())->getCapabilities();
604             if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS))
605                 glPointParameterf(GL_POINT_SIZE_MIN, mPointSizeMin);
606             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB))
607                 glPointParameterfARB(GL_POINT_SIZE_MIN, mPointSizeMin);
608             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT))
609                 glPointParameterfEXT(GL_POINT_SIZE_MIN, mPointSizeMin);
610         }
611         if (maxSize != mPointSizeMax)
612         {
613             mPointSizeMax = maxSize;
614             const Ogre::RenderSystemCapabilities* caps = dynamic_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem())->getCapabilities();
615             if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS))
616                 glPointParameterf(GL_POINT_SIZE_MAX, mPointSizeMax);
617             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB))
618                 glPointParameterfARB(GL_POINT_SIZE_MAX, mPointSizeMax);
619             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT))
620                 glPointParameterfEXT(GL_POINT_SIZE_MAX, mPointSizeMax);
621         }
622         if (attenuation[0] != mPointAttenuation[0] || attenuation[1] != mPointAttenuation[1] || attenuation[2] != mPointAttenuation[2])
623         {
624             mPointAttenuation[0] = attenuation[0];
625             mPointAttenuation[1] = attenuation[1];
626             mPointAttenuation[2] = attenuation[2];
627             const Ogre::RenderSystemCapabilities* caps = dynamic_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem())->getCapabilities();
628             if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS))
629                 glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, &mPointAttenuation[0]);
630             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB))
631                 glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION, &mPointAttenuation[0]);
632             else if (caps->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT))
633                 glPointParameterfvEXT(GL_POINT_DISTANCE_ATTENUATION, &mPointAttenuation[0]);
634         }
635     }
636 
enableTextureCoordGen(GLenum type)637     void GLStateCacheManagerImp::enableTextureCoordGen(GLenum type)
638     {
639         HashMap<GLenum, TexGenParams>::iterator it = mTextureCoordGen.find(mActiveTextureUnit);
640         if (it == mTextureCoordGen.end())
641         {
642             glEnable(type);
643             mTextureCoordGen[mActiveTextureUnit].mEnabled.insert(type);
644         }
645         else
646         {
647             if (it->second.mEnabled.find(type) == it->second.mEnabled.end())
648             {
649                 glEnable(type);
650                 it->second.mEnabled.insert(type);
651             }
652         }
653     }
654 
disableTextureCoordGen(GLenum type)655     void GLStateCacheManagerImp::disableTextureCoordGen(GLenum type)
656     {
657         HashMap<GLenum, TexGenParams>::iterator it = mTextureCoordGen.find(mActiveTextureUnit);
658         if (it != mTextureCoordGen.end())
659         {
660             std::set<GLenum>::iterator found = it->second.mEnabled.find(type);
661             if (found != it->second.mEnabled.end())
662             {
663                 glDisable(type);
664                 it->second.mEnabled.erase(found);
665             }
666         }
667     }
668 }
669