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