]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/COpenGLCoreCacheHandler.h
Fix OpenGL3 driver to compile standalone
[irrlicht.git] / source / Irrlicht / COpenGLCoreCacheHandler.h
1 // Copyright (C) 2015 Patryk Nadrowski\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #ifndef __C_OGLCORE_CACHE_HANDLER_H_INCLUDED__\r
6 #define __C_OGLCORE_CACHE_HANDLER_H_INCLUDED__\r
7 \r
8 \r
9 #include "SMaterial.h"\r
10 #include "ITexture.h"\r
11 \r
12 namespace irr\r
13 {\r
14 namespace video\r
15 {\r
16 \r
17 enum ESetTextureActive\r
18 {\r
19         EST_ACTIVE_ALWAYS,              // texture unit always active after set call\r
20         EST_ACTIVE_ON_CHANGE    // texture unit only active after call when texture changed in cache\r
21 };\r
22 \r
23 \r
24 template <class TOpenGLDriver, class TOpenGLTexture>\r
25 class COpenGLCoreCacheHandler\r
26 {\r
27         class STextureCache\r
28         {\r
29         public:\r
30                 STextureCache(COpenGLCoreCacheHandler& cacheHandler, E_DRIVER_TYPE driverType, u32 textureCount) :\r
31                         CacheHandler(cacheHandler), DriverType(driverType), TextureCount(textureCount)\r
32                 {\r
33                         for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)\r
34                         {\r
35                                 Texture[i] = 0;\r
36                         }\r
37                 }\r
38 \r
39                 ~STextureCache()\r
40                 {\r
41                         clear();\r
42                 }\r
43 \r
44                 const TOpenGLTexture* operator[](int index) const\r
45                 {\r
46                         if (static_cast<u32>(index) < MATERIAL_MAX_TEXTURES)\r
47                                 return Texture[static_cast<u32>(index)];\r
48 \r
49                         return 0;\r
50                 }\r
51 \r
52                 const TOpenGLTexture* get(u32 index) const\r
53                 {\r
54                         if (index < MATERIAL_MAX_TEXTURES)\r
55                                 return Texture[index];\r
56 \r
57                         return 0;\r
58                 }\r
59 \r
60                 bool set(u32 index, const ITexture* texture, ESetTextureActive esa=EST_ACTIVE_ALWAYS)\r
61                 {\r
62                         bool status = false;\r
63 \r
64                         E_DRIVER_TYPE type = DriverType;\r
65 \r
66                         if (index < MATERIAL_MAX_TEXTURES && index < TextureCount)\r
67                         {\r
68                                 if ( esa == EST_ACTIVE_ALWAYS )\r
69                                         CacheHandler.setActiveTexture(GL_TEXTURE0 + index);\r
70 \r
71                                 const TOpenGLTexture* prevTexture = Texture[index];\r
72 \r
73                                 if (texture != prevTexture)\r
74                                 {\r
75                                         if ( esa == EST_ACTIVE_ON_CHANGE )\r
76                                                 CacheHandler.setActiveTexture(GL_TEXTURE0 + index);\r
77 \r
78                                         if (texture)\r
79                                         {\r
80                                                 type = texture->getDriverType();\r
81 \r
82                                                 if (type == DriverType)\r
83                                                 {\r
84                                                         texture->grab();\r
85 \r
86                                                         const TOpenGLTexture* curTexture = static_cast<const TOpenGLTexture*>(texture);\r
87                                                         const GLenum curTextureType = curTexture->getOpenGLTextureType();\r
88                                                         const GLenum prevTextureType = (prevTexture) ? prevTexture->getOpenGLTextureType() : curTextureType;\r
89 \r
90                                                         if (curTextureType != prevTextureType)\r
91                                                         {\r
92                                                                 glBindTexture(prevTextureType, 0);\r
93 \r
94 #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )\r
95                                                                 glDisable(prevTextureType);\r
96                                                                 glEnable(curTextureType);\r
97 #endif\r
98                                                         }\r
99 #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )\r
100                                                         else if (!prevTexture)\r
101                                                                 glEnable(curTextureType);\r
102 #endif\r
103 \r
104                                                         glBindTexture(curTextureType, static_cast<const TOpenGLTexture*>(texture)->getOpenGLTextureName());\r
105                                                 }\r
106                                                 else\r
107                                                 {\r
108                                                         texture = 0;\r
109 \r
110                                                         os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);\r
111                                                         os::Printer::log("Texture type", irr::core::stringc((int)type), ELL_ERROR);\r
112                                                         os::Printer::log("Driver (or cache handler) type", irr::core::stringc((int)DriverType), ELL_ERROR);\r
113                                                 }\r
114                                         }\r
115 \r
116                                         if (!texture && prevTexture)\r
117                                         {\r
118                                                 const GLenum prevTextureType = prevTexture->getOpenGLTextureType();\r
119 \r
120                                                 glBindTexture(prevTextureType, 0);\r
121 \r
122 #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )\r
123                                                 glDisable(prevTextureType);\r
124 #endif\r
125                                         }\r
126 \r
127                                         Texture[index] = static_cast<const TOpenGLTexture*>(texture);\r
128 \r
129                                         if (prevTexture)\r
130                                                 prevTexture->drop();\r
131                                 }\r
132 \r
133                                 status = true;\r
134                         }\r
135 \r
136                         return (status && type == DriverType);\r
137                 }\r
138 \r
139                 void remove(ITexture* texture)\r
140                 {\r
141                         if (!texture)\r
142                                 return;\r
143 \r
144                         for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)\r
145                         {\r
146                                 if (Texture[i] == texture)\r
147                                 {\r
148                                         Texture[i] = 0;\r
149 \r
150                                         texture->drop();\r
151                                 }\r
152                         }\r
153                 }\r
154 \r
155                 void clear()\r
156                 {\r
157                         for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)\r
158                         {\r
159                                 if (Texture[i])\r
160                                 {\r
161                                         const TOpenGLTexture* prevTexture = Texture[i];\r
162 \r
163                                         Texture[i] = 0;\r
164 \r
165                                         prevTexture->drop();\r
166                                 }\r
167                         }\r
168                 }\r
169 \r
170         private:\r
171                 COpenGLCoreCacheHandler& CacheHandler;\r
172 \r
173                 E_DRIVER_TYPE DriverType;\r
174 \r
175                 const TOpenGLTexture* Texture[MATERIAL_MAX_TEXTURES];\r
176                 u32 TextureCount;\r
177         };\r
178 \r
179 public:\r
180         COpenGLCoreCacheHandler(TOpenGLDriver* driver) :\r
181                 Driver(driver),\r
182 #if defined(_MSC_VER)\r
183 #pragma warning(push)\r
184 #pragma warning(disable: 4355)  // Warning: "'this' : used in base member initializer list. ". It's OK, we don't use the reference in STextureCache constructor.\r
185 #endif\r
186                 TextureCache(STextureCache(*this, driver->getDriverType(), driver->getFeature().MaxTextureUnits)),\r
187 #if defined(_MSC_VER)\r
188 #pragma warning(pop)\r
189 #endif\r
190                 FrameBufferCount(0), BlendEquation(0), BlendSourceRGB(0),\r
191                 BlendDestinationRGB(0), BlendSourceAlpha(0), BlendDestinationAlpha(0), Blend(0), BlendEquationInvalid(false), BlendFuncInvalid(false), BlendInvalid(false),\r
192                 ColorMask(0), ColorMaskInvalid(false), CullFaceMode(GL_BACK), CullFace(false), DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), FrameBufferID(0),\r
193                 ProgramID(0), ActiveTexture(GL_TEXTURE0), ViewportX(0), ViewportY(0)\r
194         {\r
195                 const COpenGLCoreFeature& feature = Driver->getFeature();\r
196 \r
197                 FrameBufferCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(feature.MultipleRenderTarget));\r
198 \r
199                 BlendEquation = new GLenum[FrameBufferCount];\r
200                 BlendSourceRGB = new GLenum[FrameBufferCount];\r
201                 BlendDestinationRGB = new GLenum[FrameBufferCount];\r
202                 BlendSourceAlpha = new GLenum[FrameBufferCount];\r
203                 BlendDestinationAlpha = new GLenum[FrameBufferCount];\r
204                 Blend = new bool[FrameBufferCount];\r
205                 ColorMask = new u8[FrameBufferCount];\r
206 \r
207                 // Initial OpenGL values from specification.\r
208 \r
209                 if (feature.BlendOperation)\r
210                 {\r
211                         Driver->irrGlBlendEquation(GL_FUNC_ADD);\r
212                 }\r
213 \r
214                 for (u32 i = 0; i < FrameBufferCount; ++i)\r
215                 {\r
216                         BlendEquation[i] = GL_FUNC_ADD;\r
217 \r
218                         BlendSourceRGB[i] = GL_ONE;\r
219                         BlendDestinationRGB[i] = GL_ZERO;\r
220                         BlendSourceAlpha[i] = GL_ONE;\r
221                         BlendDestinationAlpha[i] = GL_ZERO;\r
222 \r
223                         Blend[i] = false;\r
224                         ColorMask[i] = ECP_ALL;\r
225                 }\r
226 \r
227                 glBlendFunc(GL_ONE, GL_ZERO);\r
228                 glDisable(GL_BLEND);\r
229 \r
230                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);\r
231 \r
232                 glCullFace(CullFaceMode);\r
233                 glDisable(GL_CULL_FACE);\r
234 \r
235                 glDepthFunc(DepthFunc);\r
236                 glDepthMask(GL_TRUE);\r
237                 glDisable(GL_DEPTH_TEST);\r
238 \r
239                 Driver->irrGlActiveTexture(ActiveTexture);\r
240 \r
241 #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )\r
242                 glDisable(GL_TEXTURE_2D);\r
243 #endif\r
244 \r
245                 const core::dimension2d<u32> ScreenSize = Driver->getScreenSize();\r
246                 ViewportWidth = ScreenSize.Width;\r
247                 ViewportHeight = ScreenSize.Height;\r
248                 glViewport(ViewportX, ViewportY, ViewportWidth, ViewportHeight);\r
249         }\r
250 \r
251         virtual ~COpenGLCoreCacheHandler()\r
252         {\r
253                 delete[] BlendEquation;\r
254                 delete[] BlendSourceRGB;\r
255                 delete[] BlendDestinationRGB;\r
256                 delete[] BlendSourceAlpha;\r
257                 delete[] BlendDestinationAlpha;\r
258                 delete[] Blend;\r
259 \r
260                 delete[] ColorMask;\r
261         }\r
262 \r
263         E_DRIVER_TYPE getDriverType() const\r
264         {\r
265                 return Driver->getDriverType();\r
266         }\r
267 \r
268         STextureCache& getTextureCache()\r
269         {\r
270                 return TextureCache;\r
271         }\r
272 \r
273         // Blending calls.\r
274 \r
275         void setBlendEquation(GLenum mode)\r
276         {\r
277                 if (BlendEquation[0] != mode || BlendEquationInvalid)\r
278                 {\r
279                         Driver->irrGlBlendEquation(mode);\r
280 \r
281                         for (GLuint i = 0; i < FrameBufferCount; ++i)\r
282                                 BlendEquation[i] = mode;\r
283 \r
284                         BlendEquationInvalid = false;\r
285                 }\r
286         }\r
287 \r
288         void setBlendEquationIndexed(GLuint index, GLenum mode)\r
289         {\r
290                 if (index < FrameBufferCount && BlendEquation[index] != mode)\r
291                 {\r
292                         Driver->irrGlBlendEquationIndexed(index, mode);\r
293 \r
294                         BlendEquation[index] = mode;\r
295                         BlendEquationInvalid = true;\r
296                 }\r
297         }\r
298 \r
299         void setBlendFunc(GLenum source, GLenum destination)\r
300         {\r
301                 if (BlendSourceRGB[0] != source || BlendDestinationRGB[0] != destination ||\r
302                         BlendSourceAlpha[0] != source || BlendDestinationAlpha[0] != destination ||\r
303                         BlendFuncInvalid)\r
304                 {\r
305                         glBlendFunc(source, destination);\r
306 \r
307                         for (GLuint i = 0; i < FrameBufferCount; ++i)\r
308                         {\r
309                                 BlendSourceRGB[i] = source;\r
310                                 BlendDestinationRGB[i] = destination;\r
311                                 BlendSourceAlpha[i] = source;\r
312                                 BlendDestinationAlpha[i] = destination;\r
313                         }\r
314 \r
315                         BlendFuncInvalid = false;\r
316                 }\r
317         }\r
318 \r
319         void setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)\r
320         {\r
321                 if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)\r
322                 {\r
323                         if (BlendSourceRGB[0] != sourceRGB || BlendDestinationRGB[0] != destinationRGB ||\r
324                                 BlendSourceAlpha[0] != sourceAlpha || BlendDestinationAlpha[0] != destinationAlpha ||\r
325                                 BlendFuncInvalid)\r
326                         {\r
327                                 Driver->irrGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);\r
328 \r
329                                 for (GLuint i = 0; i < FrameBufferCount; ++i)\r
330                                 {\r
331                                         BlendSourceRGB[i] = sourceRGB;\r
332                                         BlendDestinationRGB[i] = destinationRGB;\r
333                                         BlendSourceAlpha[i] = sourceAlpha;\r
334                                         BlendDestinationAlpha[i] = destinationAlpha;\r
335                                 }\r
336 \r
337                                 BlendFuncInvalid = false;\r
338                         }\r
339                 }\r
340                 else\r
341                 {\r
342                         setBlendFunc(sourceRGB, destinationRGB);\r
343                 }\r
344         }\r
345 \r
346         void setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination)\r
347         {\r
348                 if (index < FrameBufferCount && (BlendSourceRGB[index] != source || BlendDestinationRGB[index] != destination ||\r
349                         BlendSourceAlpha[index] != source || BlendDestinationAlpha[index] != destination))\r
350                 {\r
351                         Driver->irrGlBlendFuncIndexed(index, source, destination);\r
352 \r
353                         BlendSourceRGB[index] = source;\r
354                         BlendDestinationRGB[index] = destination;\r
355                         BlendSourceAlpha[index] = source;\r
356                         BlendDestinationAlpha[index] = destination;\r
357                         BlendFuncInvalid = true;\r
358                 }\r
359         }\r
360 \r
361         void setBlendFuncSeparateIndexed(GLuint index, GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)\r
362         {\r
363                 if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)\r
364                 {\r
365                         if (index < FrameBufferCount && (BlendSourceRGB[index] != sourceRGB || BlendDestinationRGB[index] != destinationRGB ||\r
366                                 BlendSourceAlpha[index] != sourceAlpha || BlendDestinationAlpha[index] != destinationAlpha))\r
367                         {\r
368                                 Driver->irrGlBlendFuncSeparateIndexed(index, sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);\r
369 \r
370                                 BlendSourceRGB[index] = sourceRGB;\r
371                                 BlendDestinationRGB[index] = destinationRGB;\r
372                                 BlendSourceAlpha[index] = sourceAlpha;\r
373                                 BlendDestinationAlpha[index] = destinationAlpha;\r
374                                 BlendFuncInvalid = true;\r
375                         }\r
376                 }\r
377                 else\r
378                 {\r
379                         setBlendFuncIndexed(index, sourceRGB, destinationRGB);\r
380                 }\r
381         }\r
382 \r
383         void setBlend(bool enable)\r
384         {\r
385                 if (Blend[0] != enable || BlendInvalid)\r
386                 {\r
387                         if (enable)\r
388                                 glEnable(GL_BLEND);\r
389                         else\r
390                                 glDisable(GL_BLEND);\r
391 \r
392                         for (GLuint i = 0; i < FrameBufferCount; ++i)\r
393                                 Blend[i] = enable;\r
394 \r
395                         BlendInvalid = false;\r
396                 }\r
397         }\r
398 \r
399         void setBlendIndexed(GLuint index, bool enable)\r
400         {\r
401                 if (index < FrameBufferCount && Blend[index] != enable)\r
402                 {\r
403                         if (enable)\r
404                                 Driver->irrGlEnableIndexed(GL_BLEND, index);\r
405                         else\r
406                                 Driver->irrGlDisableIndexed(GL_BLEND, index);\r
407 \r
408                         Blend[index] = enable;\r
409                         BlendInvalid = true;\r
410                 }\r
411         }\r
412 \r
413         // Color Mask.\r
414 \r
415         void getColorMask(u8& mask)\r
416         {\r
417                 mask = ColorMask[0];\r
418         }\r
419 \r
420         void setColorMask(u8 mask)\r
421         {\r
422                 if (ColorMask[0] != mask || ColorMaskInvalid)\r
423                 {\r
424                         glColorMask((mask & ECP_RED) ? GL_TRUE : GL_FALSE, (mask & ECP_GREEN) ? GL_TRUE : GL_FALSE, (mask & ECP_BLUE) ? GL_TRUE : GL_FALSE, (mask & ECP_ALPHA) ? GL_TRUE : GL_FALSE);\r
425 \r
426                         for (GLuint i = 0; i < FrameBufferCount; ++i)\r
427                                 ColorMask[i] = mask;\r
428 \r
429                         ColorMaskInvalid = false;\r
430                 }\r
431         }\r
432 \r
433         void setColorMaskIndexed(GLuint index, u8 mask)\r
434         {\r
435                 if (index < FrameBufferCount && ColorMask[index] != mask)\r
436                 {\r
437                         Driver->irrGlColorMaskIndexed(index, (mask & ECP_RED) ? GL_TRUE : GL_FALSE, (mask & ECP_GREEN) ? GL_TRUE : GL_FALSE, (mask & ECP_BLUE) ? GL_TRUE : GL_FALSE, (mask & ECP_ALPHA) ? GL_TRUE : GL_FALSE);\r
438 \r
439                         ColorMask[index] = mask;\r
440                         ColorMaskInvalid = true;\r
441                 }\r
442         }\r
443 \r
444         // Cull face calls.\r
445 \r
446         void setCullFaceFunc(GLenum mode)\r
447         {\r
448                 if (CullFaceMode != mode)\r
449                 {\r
450                         glCullFace(mode);\r
451                         CullFaceMode = mode;\r
452                 }\r
453         }\r
454 \r
455         void setCullFace(bool enable)\r
456         {\r
457                 if (CullFace != enable)\r
458                 {\r
459                         if (enable)\r
460                                 glEnable(GL_CULL_FACE);\r
461                         else\r
462                                 glDisable(GL_CULL_FACE);\r
463 \r
464                         CullFace = enable;\r
465                 }\r
466         }\r
467 \r
468         // Depth calls.\r
469 \r
470         void setDepthFunc(GLenum mode)\r
471         {\r
472                 if (DepthFunc != mode)\r
473                 {\r
474                         glDepthFunc(mode);\r
475                         DepthFunc = mode;\r
476                 }\r
477         }\r
478 \r
479         void getDepthMask(bool& depth)\r
480         {\r
481                 depth = DepthMask;\r
482         }\r
483 \r
484         void setDepthMask(bool enable)\r
485         {\r
486                 if (DepthMask != enable)\r
487                 {\r
488                         if (enable)\r
489                                 glDepthMask(GL_TRUE);\r
490                         else\r
491                                 glDepthMask(GL_FALSE);\r
492 \r
493                         DepthMask = enable;\r
494                 }\r
495         }\r
496 \r
497     void getDepthTest(bool& enable)\r
498     {\r
499         enable = DepthTest;\r
500     }\r
501 \r
502         void setDepthTest(bool enable)\r
503         {\r
504                 if (DepthTest != enable)\r
505                 {\r
506                         if (enable)\r
507                                 glEnable(GL_DEPTH_TEST);\r
508                         else\r
509                                 glDisable(GL_DEPTH_TEST);\r
510 \r
511                         DepthTest = enable;\r
512                 }\r
513         }\r
514 \r
515         // FBO calls.\r
516 \r
517         void getFBO(GLuint& frameBufferID) const\r
518         {\r
519                 frameBufferID = FrameBufferID;\r
520         }\r
521 \r
522         void setFBO(GLuint frameBufferID)\r
523         {\r
524                 if (FrameBufferID != frameBufferID)\r
525                 {\r
526                         Driver->irrGlBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);\r
527                         FrameBufferID = frameBufferID;\r
528                 }\r
529         }\r
530 \r
531         // Shaders calls.\r
532 \r
533         void getProgram(GLuint& programID) const\r
534         {\r
535                 programID = ProgramID;\r
536         }\r
537 \r
538         void setProgram(GLuint programID)\r
539         {\r
540                 if (ProgramID != programID)\r
541                 {\r
542                         Driver->irrGlUseProgram(programID);\r
543                         ProgramID = programID;\r
544                 }\r
545         }\r
546 \r
547         // Texture calls.\r
548 \r
549         void getActiveTexture(GLenum& texture) const\r
550         {\r
551                 texture = ActiveTexture;\r
552         }\r
553 \r
554         void setActiveTexture(GLenum texture)\r
555         {\r
556                 if (ActiveTexture != texture)\r
557                 {\r
558                         Driver->irrGlActiveTexture(texture);\r
559                         ActiveTexture = texture;\r
560                 }\r
561         }\r
562 \r
563         // Viewport calls.\r
564 \r
565         void getViewport(GLint& viewportX, GLint& viewportY, GLsizei& viewportWidth, GLsizei& viewportHeight) const\r
566         {\r
567                 viewportX = ViewportX;\r
568                 viewportY = ViewportY;\r
569                 viewportWidth = ViewportWidth;\r
570                 viewportHeight = ViewportHeight;\r
571         }\r
572 \r
573         void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight)\r
574         {\r
575                 if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight)\r
576                 {\r
577                         glViewport(viewportX, viewportY, viewportWidth, viewportHeight);\r
578                         ViewportX = viewportX;\r
579                         ViewportY = viewportY;\r
580                         ViewportWidth = viewportWidth;\r
581                         ViewportHeight = viewportHeight;\r
582                 }\r
583         }\r
584 \r
585         //! Compare material to current cache and update it when there are differences\r
586         // Some material renderers do change the cache beyond the original material settings\r
587         // This corrects the material to represent the current cache state again.\r
588         void correctCacheMaterial(irr::video::SMaterial& material)\r
589         {\r
590                 // Fix textures which got removed\r
591                 for ( u32 i=0; i < MATERIAL_MAX_TEXTURES; ++i )\r
592                 {\r
593                         if ( material.TextureLayer[i].Texture && !TextureCache[i] )\r
594                         {\r
595                                 material.TextureLayer[i].Texture = 0;\r
596                         }\r
597                 }\r
598         }\r
599 \r
600 protected:\r
601         TOpenGLDriver* Driver;\r
602 \r
603         STextureCache TextureCache;\r
604 \r
605         GLuint FrameBufferCount;\r
606 \r
607         GLenum* BlendEquation;\r
608         GLenum* BlendSourceRGB;\r
609         GLenum* BlendDestinationRGB;\r
610         GLenum* BlendSourceAlpha;\r
611         GLenum* BlendDestinationAlpha;\r
612         bool* Blend;\r
613         bool BlendEquationInvalid;\r
614         bool BlendFuncInvalid;\r
615         bool BlendInvalid;\r
616 \r
617 \r
618         u8* ColorMask;\r
619         bool ColorMaskInvalid;\r
620 \r
621         GLenum CullFaceMode;\r
622         bool CullFace;\r
623 \r
624         GLenum DepthFunc;\r
625         bool DepthMask;\r
626         bool DepthTest;\r
627 \r
628         GLuint FrameBufferID;\r
629 \r
630         GLuint ProgramID;\r
631 \r
632         GLenum ActiveTexture;\r
633 \r
634         GLint ViewportX;\r
635         GLint ViewportY;\r
636         GLsizei ViewportWidth;\r
637         GLsizei ViewportHeight;\r
638 };\r
639 \r
640 }\r
641 }\r
642 \r
643 #endif\r