GLES11RICE: Some fixes on multi texturing
[mupen64plus-pandora.git] / source / rice_gles / src / OGLRender.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19 #include "osal_opengl.h"
20
21 #if SDL_VIDEO_OPENGL
22 #include "OGLExtensions.h"
23 #elif SDL_VIDEO_OPENGL_ES2
24 #include "OGLES2FragmentShaders.h"
25 #endif
26 #include "OGLDebug.h"
27 #include "OGLRender.h"
28 #include "OGLGraphicsContext.h"
29 #include "OGLTexture.h"
30 #include "TextureManager.h"
31
32 #ifdef PAULSCODE
33 //include "ae_bridge.h"
34 //static int hardwareType = HARDWARE_TYPE_UNKNOWN;
35 #endif
36
37 // FIXME: Use OGL internal L/T and matrix stack
38 // FIXME: Use OGL lookupAt function
39 // FIXME: Use OGL DisplayList
40
41 UVFlagMap OGLXUVFlagMaps[] =
42 {
43     {TEXTURE_UV_FLAG_WRAP, GL_REPEAT},
44     {TEXTURE_UV_FLAG_MIRROR, GL_MIRRORED_REPEAT_ARB},
45     {TEXTURE_UV_FLAG_CLAMP, GL_CLAMP},
46 };
47
48 #if SDL_VIDEO_OPENGL_ES2
49   static GLuint disabledTextureID;
50 #endif
51
52 //===================================================================
53 OGLRender::OGLRender()
54 {
55     COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
56     m_bSupportFogCoordExt = pcontext->m_bSupportFogCoord;
57     m_bMultiTexture = pcontext->m_bSupportMultiTexture;
58 #ifdef HAVE_GLES
59     m_bSupportClampToEdge = true;
60 #else
61     m_bSupportClampToEdge = false;
62 #endif
63     for( int i=0; i<8; i++ )
64     {
65         m_curBoundTex[i]=0;
66         m_texUnitEnabled[i]=FALSE;
67     }
68
69 #if SDL_VIDEO_OPENGL
70 /*#ifdef HAVE_GLES
71     m_bEnableMultiTexture = true;
72 #else*/
73     m_bEnableMultiTexture = false;
74 //#endif
75
76 #elif SDL_VIDEO_OPENGL_ES2
77     m_bEnableMultiTexture = true;
78
79     //Create a texture as replacement for glEnable/Disable(GL_TEXTURE_2D)
80     unsigned int white[8*8];
81         for (int i=0; i<8*8; i++) {
82                 //white[i].r = white[i].g = white[i].b = 0;
83                 //white[i].a = 0;
84                 white[i] = 0;
85         }
86     glGenTextures(1,&disabledTextureID);
87     OPENGL_CHECK_ERRORS;
88     glBindTexture(GL_TEXTURE_2D, disabledTextureID);
89     OPENGL_CHECK_ERRORS;
90     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
91     OPENGL_CHECK_ERRORS;
92     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, white);
93     OPENGL_CHECK_ERRORS;
94 #endif
95 }
96
97 OGLRender::~OGLRender()
98 {
99     ClearDeviceObjects();
100 }
101
102 bool OGLRender::InitDeviceObjects()
103 {
104     // enable Z-buffer by default
105     ZBufferEnable(true);
106     return true;
107 }
108
109 bool OGLRender::ClearDeviceObjects()
110 {
111     return true;
112 }
113
114 void OGLRender::Initialize(void)
115 {
116     glMatrixMode(GL_MODELVIEW);
117     OPENGL_CHECK_ERRORS;
118     glLoadIdentity();
119     OPENGL_CHECK_ERRORS;
120
121     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
122     OPENGL_CHECK_ERRORS;
123
124 #if SDL_VIDEO_OPENGL
125     COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
126 #ifndef HAVE_GLES
127     if( pcontext->IsExtensionSupported("GL_IBM_texture_mirrored_repeat") )
128     {
129         OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT_IBM;
130     }
131     else if( pcontext->IsExtensionSupported("ARB_texture_mirrored_repeat") )
132 #endif
133     {
134         OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT_ARB;
135     }
136 #ifndef HAVE_GLES
137     else
138     {
139         OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_REPEAT;
140     }
141     if( pcontext->IsExtensionSupported("GL_ARB_texture_border_clamp") || pcontext->IsExtensionSupported("GL_EXT_texture_edge_clamp") )
142 #endif
143     {
144         m_bSupportClampToEdge = true;
145         OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE;
146     }
147 #ifndef HAVE_GLES
148     else
149     {
150         m_bSupportClampToEdge = false;
151         OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP;
152     }
153 #endif
154     glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
155     OPENGL_CHECK_ERRORS;
156     glEnableClientState( GL_VERTEX_ARRAY );
157     OPENGL_CHECK_ERRORS;
158
159     if( m_bMultiTexture )
160     {
161         pglClientActiveTextureARB( GL_TEXTURE0_ARB );
162         OPENGL_CHECK_ERRORS;
163         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
164         OPENGL_CHECK_ERRORS;
165         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
166         OPENGL_CHECK_ERRORS;
167
168         pglClientActiveTextureARB( GL_TEXTURE1_ARB );
169         OPENGL_CHECK_ERRORS;
170         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
171         OPENGL_CHECK_ERRORS;
172         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
173         OPENGL_CHECK_ERRORS;
174         }
175     else
176     {
177         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
178         OPENGL_CHECK_ERRORS;
179         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
180         OPENGL_CHECK_ERRORS;
181     }
182 #ifndef HAVE_GLES
183     if (m_bSupportFogCoordExt)
184     {
185         pglFogCoordPointerEXT( GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][4]) );
186         OPENGL_CHECK_ERRORS;
187         glEnableClientState( GL_FOG_COORDINATE_ARRAY_EXT );
188         OPENGL_CHECK_ERRORS;
189         glFogi( GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT );
190         OPENGL_CHECK_ERRORS;
191         glFogi(GL_FOG_MODE, GL_LINEAR); // Fog Mode
192         OPENGL_CHECK_ERRORS;
193         glFogf(GL_FOG_DENSITY, 1.0f); // How Dense Will The Fog Be
194         OPENGL_CHECK_ERRORS;
195         glHint(GL_FOG_HINT, GL_FASTEST); // Fog Hint Value
196         OPENGL_CHECK_ERRORS;
197         glFogi( GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT );
198         OPENGL_CHECK_ERRORS;
199         glFogf( GL_FOG_START, 0.0f );
200         OPENGL_CHECK_ERRORS;
201         glFogf( GL_FOG_END, 1.0f );
202         OPENGL_CHECK_ERRORS;
203     }
204 #endif
205     //glColorPointer( 1, GL_UNSIGNED_BYTE, sizeof(TLITVERTEX), &g_vtxBuffer[0].r);
206     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
207     OPENGL_CHECK_ERRORS;
208     glEnableClientState( GL_COLOR_ARRAY );
209     OPENGL_CHECK_ERRORS;
210 #ifndef HAVE_GLES
211     if( pcontext->IsExtensionSupported("GL_NV_depth_clamp") )
212     {
213         glEnable(GL_DEPTH_CLAMP_NV);
214         OPENGL_CHECK_ERRORS;
215     }
216 #endif
217 #elif SDL_VIDEO_OPENGL_ES2
218     OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT;
219     m_bSupportClampToEdge = true;
220     OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE;
221 #endif
222
223 #ifdef PAULSCODE
224 //    hardwareType = Android_JNI_GetHardwareType();
225 #endif
226 }
227 //===================================================================
228 TextureFilterMap OglTexFilterMap[2]=
229 {
230     {FILTER_POINT, GL_NEAREST},
231     {FILTER_LINEAR, GL_LINEAR},
232 };
233
234 void OGLRender::ApplyTextureFilter()
235 {
236     static uint32 minflag=0xFFFF, magflag=0xFFFF;
237     static uint32 mtex;
238
239     if( m_texUnitEnabled[0] )
240     {
241         if( mtex != m_curBoundTex[0] )
242         {
243             mtex = m_curBoundTex[0];
244             minflag = m_dwMinFilter;
245             magflag = m_dwMagFilter;
246             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
247             OPENGL_CHECK_ERRORS;
248             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
249             OPENGL_CHECK_ERRORS;
250         }
251         else
252         {
253             if( minflag != (unsigned int)m_dwMinFilter )
254             {
255                 minflag = m_dwMinFilter;
256                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
257                 OPENGL_CHECK_ERRORS;
258             }
259             if( magflag != (unsigned int)m_dwMagFilter )
260             {
261                 magflag = m_dwMagFilter;
262                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
263                 OPENGL_CHECK_ERRORS;
264             }   
265         }
266     }
267 }
268
269 void OGLRender::SetShadeMode(RenderShadeMode mode)
270 {
271 #if SDL_VIDEO_OPENGL
272     if( mode == SHADE_SMOOTH )
273         glShadeModel(GL_SMOOTH);
274     else
275         glShadeModel(GL_FLAT);
276     OPENGL_CHECK_ERRORS;
277 #endif
278 }
279
280 void OGLRender::ZBufferEnable(BOOL bZBuffer)
281 {
282     gRSP.bZBufferEnabled = bZBuffer;
283     if( g_curRomInfo.bForceDepthBuffer )
284         bZBuffer = TRUE;
285     if( bZBuffer )
286     {
287         glDepthMask(GL_TRUE);
288         OPENGL_CHECK_ERRORS;
289         //glEnable(GL_DEPTH_TEST);
290         glDepthFunc( GL_LEQUAL );
291         OPENGL_CHECK_ERRORS;
292     }
293     else
294     {
295         glDepthMask(GL_FALSE);
296         OPENGL_CHECK_ERRORS;
297         //glDisable(GL_DEPTH_TEST);
298         glDepthFunc( GL_ALWAYS );
299         OPENGL_CHECK_ERRORS;
300     }
301 }
302
303 void OGLRender::ClearBuffer(bool cbuffer, bool zbuffer)
304 {
305     uint32 flag=0;
306     if( cbuffer )   flag |= GL_COLOR_BUFFER_BIT;
307     if( zbuffer )   flag |= GL_DEPTH_BUFFER_BIT;
308     float depth = ((gRDP.originalFillColor&0xFFFF)>>2)/(float)0x3FFF;
309     glClearDepth(depth);
310     OPENGL_CHECK_ERRORS;
311     glClear(flag);
312     OPENGL_CHECK_ERRORS;
313 }
314
315 void OGLRender::ClearZBuffer(float depth)
316 {
317     uint32 flag=GL_DEPTH_BUFFER_BIT;
318     glClearDepth(depth);
319     OPENGL_CHECK_ERRORS;
320     glClear(flag);
321     OPENGL_CHECK_ERRORS;
322 }
323
324 void OGLRender::SetZCompare(BOOL bZCompare)
325 {
326     if( g_curRomInfo.bForceDepthBuffer )
327         bZCompare = TRUE;
328
329     gRSP.bZBufferEnabled = bZCompare;
330     if( bZCompare == TRUE )
331     {
332         //glEnable(GL_DEPTH_TEST);
333         glDepthFunc( GL_LEQUAL );
334         OPENGL_CHECK_ERRORS;
335     }
336     else
337     {
338         //glDisable(GL_DEPTH_TEST);
339         glDepthFunc( GL_ALWAYS );
340         OPENGL_CHECK_ERRORS;
341     }
342 }
343
344 void OGLRender::SetZUpdate(BOOL bZUpdate)
345 {
346     if( g_curRomInfo.bForceDepthBuffer )
347         bZUpdate = TRUE;
348
349     if( bZUpdate )
350     {
351         //glEnable(GL_DEPTH_TEST);
352         glDepthMask(GL_TRUE);
353         OPENGL_CHECK_ERRORS;
354     }
355     else
356     {
357         glDepthMask(GL_FALSE);
358         OPENGL_CHECK_ERRORS;
359     }
360 }
361
362 void OGLRender::ApplyZBias(int bias)
363 {
364     float f1 = bias > 0 ? -3.0f : 0.0f;  // z offset = -3.0 * max(abs(dz/dx),abs(dz/dy)) per pixel delta z slope
365     float f2 = bias > 0 ? -3.0f : 0.0f;  // z offset += -3.0 * 1 bit
366
367 #ifdef PAULSCODE
368 //    Android_JNI_GetPolygonOffset(hardwareType, bias, &f1, &f2);
369 //      glPolygonOffset(0.2f, 0.2f);
370 #endif
371
372     if (bias > 0)
373     {
374         glEnable(GL_POLYGON_OFFSET_FILL);  // enable z offsets
375         OPENGL_CHECK_ERRORS;
376     }
377     else
378     {
379         glDisable(GL_POLYGON_OFFSET_FILL);  // disable z offsets
380         OPENGL_CHECK_ERRORS;
381     }
382     glPolygonOffset(f1, f2);  // set bias functions
383     OPENGL_CHECK_ERRORS;
384 }
385
386 void OGLRender::SetZBias(int bias)
387 {
388 #if defined(DEBUGGER)
389     if( pauseAtNext == true )
390       DebuggerAppendMsg("Set zbias = %d", bias);
391 #endif
392     // set member variable and apply the setting in opengl
393     m_dwZBias = bias;
394     ApplyZBias(bias);
395 }
396
397 void OGLRender::SetAlphaRef(uint32 dwAlpha)
398 {
399     if (m_dwAlpha != dwAlpha)
400     {
401         m_dwAlpha = dwAlpha;
402 #if SDL_VIDEO_OPENGL
403         glAlphaFunc(GL_GEQUAL, (float)dwAlpha);
404         OPENGL_CHECK_ERRORS;
405 #endif
406     }
407 }
408
409 void OGLRender::ForceAlphaRef(uint32 dwAlpha)
410 {
411 #if SDL_VIDEO_OPENGL
412     float ref = dwAlpha/255.0f;
413     glAlphaFunc(GL_GEQUAL, ref);
414     OPENGL_CHECK_ERRORS;
415 #elif SDL_VIDEO_OPENGL_ES2
416     m_dwAlpha = dwAlpha;
417 #endif
418 }
419
420 void OGLRender::SetFillMode(FillMode mode)
421 {
422 #if SDL_VIDEO_OPENGL
423 #ifndef HAVE_GLES
424     if( mode == RICE_FILLMODE_WINFRAME )
425     {
426         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
427         OPENGL_CHECK_ERRORS;
428     }
429     else
430     {
431         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
432         OPENGL_CHECK_ERRORS;
433     }
434 #endif
435 #endif
436 }
437
438 void OGLRender::SetCullMode(bool bCullFront, bool bCullBack)
439 {
440     CRender::SetCullMode(bCullFront, bCullBack);
441     if( bCullFront && bCullBack )
442     {
443         glCullFace(GL_FRONT_AND_BACK);
444         OPENGL_CHECK_ERRORS;
445         glEnable(GL_CULL_FACE);
446         OPENGL_CHECK_ERRORS;
447     }
448     else if( bCullFront )
449     {
450         glCullFace(GL_FRONT);
451         OPENGL_CHECK_ERRORS;
452         glEnable(GL_CULL_FACE);
453         OPENGL_CHECK_ERRORS;
454     }
455     else if( bCullBack )
456     {
457         glCullFace(GL_BACK);
458         OPENGL_CHECK_ERRORS;
459         glEnable(GL_CULL_FACE);
460         OPENGL_CHECK_ERRORS;
461     }
462     else
463     {
464         glDisable(GL_CULL_FACE);
465         OPENGL_CHECK_ERRORS;
466     }
467 }
468
469 bool OGLRender::SetCurrentTexture(int tile, CTexture *handler,uint32 dwTileWidth, uint32 dwTileHeight, TxtrCacheEntry *pTextureEntry)
470 {
471     RenderTexture &texture = g_textures[tile];
472     texture.pTextureEntry = pTextureEntry;
473
474     if( handler!= NULL  && texture.m_lpsTexturePtr != handler->GetTexture() )
475     {
476         texture.m_pCTexture = handler;
477         texture.m_lpsTexturePtr = handler->GetTexture();
478
479         texture.m_dwTileWidth = dwTileWidth;
480         texture.m_dwTileHeight = dwTileHeight;
481
482         if( handler->m_bIsEnhancedTexture )
483         {
484             texture.m_fTexWidth = (float)pTextureEntry->pTexture->m_dwCreatedTextureWidth;
485             texture.m_fTexHeight = (float)pTextureEntry->pTexture->m_dwCreatedTextureHeight;
486         }
487         else
488         {
489             texture.m_fTexWidth = (float)handler->m_dwCreatedTextureWidth;
490             texture.m_fTexHeight = (float)handler->m_dwCreatedTextureHeight;
491         }
492     }
493     
494     return true;
495 }
496
497 bool OGLRender::SetCurrentTexture(int tile, TxtrCacheEntry *pEntry)
498 {
499     if (pEntry != NULL && pEntry->pTexture != NULL)
500     {   
501         SetCurrentTexture( tile, pEntry->pTexture,  pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry);
502         return true;
503     }
504     else
505     {
506         SetCurrentTexture( tile, NULL, 64, 64, NULL );
507         return false;
508     }
509     return true;
510 }
511
512 void OGLRender::SetAddressUAllStages(uint32 dwTile, TextureUVFlag dwFlag)
513 {
514     SetTextureUFlag(dwFlag, dwTile);
515 }
516
517 void OGLRender::SetAddressVAllStages(uint32 dwTile, TextureUVFlag dwFlag)
518 {
519     SetTextureVFlag(dwFlag, dwTile);
520 }
521
522 void OGLRender::SetTexWrapS(int unitno,GLuint flag)
523 {
524     static GLuint mflag;
525     static GLuint mtex;
526 #ifdef DEBUGGER
527     if( unitno != 0 )
528     {
529         DebuggerAppendMsg("Check me, unitno != 0 in base ogl");
530     }
531 #endif
532     if( m_curBoundTex[0] != mtex || mflag != flag )
533     {
534         mtex = m_curBoundTex[0];
535         mflag = flag;
536         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag);
537         OPENGL_CHECK_ERRORS;
538     }
539 }
540 void OGLRender::SetTexWrapT(int unitno,GLuint flag)
541 {
542     static GLuint mflag;
543     static GLuint mtex;
544     if( m_curBoundTex[0] != mtex || mflag != flag )
545     {
546         mtex = m_curBoundTex[0];
547         mflag = flag;
548         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag);
549         OPENGL_CHECK_ERRORS;
550     }
551 }
552
553 void OGLRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32 dwTile)
554 {
555     TileUFlags[dwTile] = dwFlag;
556     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
557     {
558         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
559         if( pTexture )
560         {
561             EnableTexUnit(0,TRUE);
562             BindTexture(pTexture->m_dwTextureName, 0);
563         }
564         SetTexWrapS(0, OGLXUVFlagMaps[dwFlag].realFlag);
565     }
566 }
567 void OGLRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile)
568 {
569     TileVFlags[dwTile] = dwFlag;
570     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
571     {
572         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
573         if( pTexture ) 
574         {
575             EnableTexUnit(0,TRUE);
576             BindTexture(pTexture->m_dwTextureName, 0);
577         }
578         SetTexWrapT(0, OGLXUVFlagMaps[dwFlag].realFlag);
579     }
580 }
581
582 // Basic render drawing functions
583
584 bool OGLRender::RenderTexRect()
585 {
586     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
587     OPENGL_CHECK_ERRORS;
588
589     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
590     glDisable(GL_CULL_FACE);
591     OPENGL_CHECK_ERRORS;
592
593     float depth = -(g_texRectTVtx[3].z*2-1);
594
595 #if SDL_VIDEO_OPENGL
596 #ifdef HAVE_GLES
597     GLfloat colour[] = {
598             g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a,
599             g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a,
600             g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a,
601             g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a
602     };
603
604     GLfloat tex[] = {
605             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
606             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
607             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
608             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
609     };
610     GLfloat tex2[] = {
611             g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
612             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
613             g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
614             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v
615     };
616
617     GLfloat vertices[] = {
618             g_texRectTVtx[3].x, g_texRectTVtx[3].y, depth, 1,
619             g_texRectTVtx[2].x, g_texRectTVtx[2].y, depth, 1,
620             g_texRectTVtx[1].x, g_texRectTVtx[1].y, depth, 1,
621             g_texRectTVtx[0].x, g_texRectTVtx[0].y, depth, 1
622     };
623
624     if( m_bMultiTexture )
625     {
626                 glClientActiveTexture( GL_TEXTURE1 );
627                 glTexCoordPointer(2, GL_FLOAT, 0, &tex2);
628                 glClientActiveTexture( GL_TEXTURE0 );
629     }
630         glTexCoordPointer(2, GL_FLOAT, 0, &tex);
631
632     glColorPointer(4, GL_FLOAT,0, &colour );
633     glVertexPointer(4,GL_FLOAT, 0, &vertices);
634     glTexCoordPointer(2, GL_FLOAT, 0, &tex);
635     OPENGL_CHECK_ERRORS;
636     glDrawArrays(GL_TRIANGLE_FAN,0,4);
637     OPENGL_CHECK_ERRORS;
638
639     //Restore old pointers
640     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
641
642     glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
643         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
644     if( m_bMultiTexture )
645     {
646                 glClientActiveTexture( GL_TEXTURE1 );
647                 glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
648     }
649 #else
650
651     glBegin(GL_TRIANGLE_FAN);
652
653     glColor4f(g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a);
654     TexCoord(g_texRectTVtx[3]);
655     glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, depth);
656     
657     glColor4f(g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a);
658     TexCoord(g_texRectTVtx[2]);
659     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, depth);
660
661     glColor4f(g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a);
662     TexCoord(g_texRectTVtx[1]);
663     glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, depth);
664
665     glColor4f(g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a);
666     TexCoord(g_texRectTVtx[0]);
667     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, depth);
668
669     glEnd();
670 #endif
671     OPENGL_CHECK_ERRORS;
672
673 #elif SDL_VIDEO_OPENGL_ES2
674     GLfloat colour[] = {
675             g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a,
676             g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a,
677             g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a,
678             g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a
679     };
680
681     GLfloat tex[] = {
682             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
683             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
684             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
685             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
686     };
687
688     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
689
690     GLfloat vertices[] = {
691             -inv + g_texRectTVtx[3].x / w, inv - g_texRectTVtx[3].y / h, depth, 1,
692             -inv + g_texRectTVtx[2].x / w, inv - g_texRectTVtx[2].y / h, depth, 1,
693             -inv + g_texRectTVtx[1].x / w, inv - g_texRectTVtx[1].y / h, depth, 1,
694             -inv + g_texRectTVtx[0].x / w, inv - g_texRectTVtx[0].y / h, depth, 1
695     };
696
697     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_TRUE, 0, &colour );
698     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
699     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
700     OPENGL_CHECK_ERRORS;
701     glDrawArrays(GL_TRIANGLE_FAN,0,4);
702     OPENGL_CHECK_ERRORS;
703
704     //Restore old pointers
705     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
706     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
707     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
708 #endif
709
710     if( cullface ) glEnable(GL_CULL_FACE);
711     OPENGL_CHECK_ERRORS;
712
713     return true;
714 }
715
716 bool OGLRender::RenderFillRect(uint32 dwColor, float depth)
717 {
718     float a = (dwColor>>24)/255.0f;
719     float r = ((dwColor>>16)&0xFF)/255.0f;
720     float g = ((dwColor>>8)&0xFF)/255.0f;
721     float b = (dwColor&0xFF)/255.0f;
722     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
723     OPENGL_CHECK_ERRORS;
724
725     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
726     glDisable(GL_CULL_FACE);
727     OPENGL_CHECK_ERRORS;
728
729 #if SDL_VIDEO_OPENGL
730 #ifdef HAVE_GLES
731     GLfloat colour[] = {
732             r,g,b,a,
733             r,g,b,a,
734             r,g,b,a,
735             r,g,b,a};
736
737     GLfloat vertices[] = {
738             m_fillRectVtx[0].x, m_fillRectVtx[1].y, depth, 1,
739             m_fillRectVtx[1].x, m_fillRectVtx[1].y, depth, 1,
740             m_fillRectVtx[1].x, m_fillRectVtx[0].y, depth, 1,
741             m_fillRectVtx[0].x, m_fillRectVtx[0].y, depth, 1
742     };
743
744     glColorPointer(4, GL_FLOAT, 0, &colour );
745     glVertexPointer(4,GL_FLOAT, 0,&vertices);
746     if( m_bMultiTexture ) {
747                 if (m_texUnitEnabled[1])
748                 {
749                         glClientActiveTexture( GL_TEXTURE1 );
750                         glActiveTexture( GL_TEXTURE1 );
751                         glDisableClientState( GL_TEXTURE_COORD_ARRAY );
752                         glDisable(GL_TEXTURE_2D);
753                 }
754     }
755         if (m_texUnitEnabled[0]) {
756         glClientActiveTexture( GL_TEXTURE0 );
757                 glActiveTexture( GL_TEXTURE0 );
758                 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
759                 glDisable(GL_TEXTURE_2D);
760         }
761     OPENGL_CHECK_ERRORS;
762     glColor4f(r,g,b,a);
763     glDrawArrays(GL_TRIANGLE_FAN,0,4);
764     OPENGL_CHECK_ERRORS;
765     //Restore old pointers
766     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
767     glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
768         if (m_texUnitEnabled[0]) {
769                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
770                 glEnable(GL_TEXTURE_2D);
771         }
772     if( m_bMultiTexture ) {
773                 glClientActiveTexture( GL_TEXTURE1 );
774                 glActiveTexture( GL_TEXTURE1 );
775                 if (m_texUnitEnabled[1])
776                 {
777                         glEnable(GL_TEXTURE_2D);
778                         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
779                 }
780                 glActiveTexture( GL_TEXTURE0 );
781     }
782 #else
783
784     glBegin(GL_TRIANGLE_FAN);
785     glColor4f(r,g,b,a);
786     glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[1].y, depth, 1);
787     glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[1].y, depth, 1);
788     glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[0].y, depth, 1);
789     glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[0].y, depth, 1);
790     glEnd();
791     OPENGL_CHECK_ERRORS;
792 #endif
793 #elif SDL_VIDEO_OPENGL_ES2
794
795     GLfloat colour[] = {
796             r,g,b,a,
797             r,g,b,a,
798             r,g,b,a,
799             r,g,b,a};
800
801     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
802
803     GLfloat vertices[] = {
804             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
805             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
806             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[0].y / h, depth, 1,
807             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[0].y / h, depth, 1
808     };
809
810     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
811     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
812     glDisableVertexAttribArray(VS_TEXCOORD0);
813     OPENGL_CHECK_ERRORS;
814     glDrawArrays(GL_TRIANGLE_FAN,0,4);
815     OPENGL_CHECK_ERRORS;
816
817     //Restore old pointers
818     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
819     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
820     glEnableVertexAttribArray(VS_TEXCOORD0);
821
822 #endif
823
824     if( cullface ) glEnable(GL_CULL_FACE);
825     OPENGL_CHECK_ERRORS;
826
827     return true;
828 }
829
830 bool OGLRender::RenderLine3D()
831 {
832 #if SDL_VIDEO_OPENGL
833     ApplyZBias(0);  // disable z offsets
834
835 #ifdef HAVE_GLES
836     GLfloat colour[] = {
837             m_line3DVtx[1].r,m_line3DVtx[1].g,m_line3DVtx[1].b,m_line3DVtx[1].a,
838             m_line3DVtx[1].r,m_line3DVtx[1].g,m_line3DVtx[1].b,m_line3DVtx[1].a,
839             m_line3DVtx[0].r,m_line3DVtx[0].g,m_line3DVtx[0].b,m_line3DVtx[0].a,
840             m_line3DVtx[0].r,m_line3DVtx[0].g,m_line3DVtx[0].b,m_line3DVtx[0].a};
841
842     GLfloat vertices[] = {
843             m_line3DVector[3].x, m_line3DVector[3].y, -m_line3DVtx[1].z, 1,
844             m_line3DVector[2].x, m_line3DVector[2].y, -m_line3DVtx[0].z, 1,
845             m_line3DVector[1].x, m_line3DVector[1].y, -m_line3DVtx[1].z, 1,
846             m_line3DVector[0].x, m_line3DVector[0].y, -m_line3DVtx[0].z, 1
847     };
848
849     glColorPointer(4, GL_FLOAT, 0, &colour );
850     glVertexPointer(4,GL_FLOAT, 0,&vertices);
851     if( m_bMultiTexture )
852     {
853                 glClientActiveTexture( GL_TEXTURE1 );
854                 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
855         glClientActiveTexture( GL_TEXTURE0 );
856     }
857     glDisableClientState( GL_TEXTURE_COORD_ARRAY );
858     OPENGL_CHECK_ERRORS;
859     glDrawArrays(GL_TRIANGLE_FAN,0,4);
860     OPENGL_CHECK_ERRORS;
861     //Restore old pointers
862     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
863     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
864     glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
865     if( m_bMultiTexture )
866     {
867                 glClientActiveTexture( GL_TEXTURE1 );
868                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
869     }
870 #else
871     glBegin(GL_TRIANGLE_FAN);
872
873     glColor4f(m_line3DVtx[1].r, m_line3DVtx[1].g, m_line3DVtx[1].b, m_line3DVtx[1].a);
874     glVertex3f(m_line3DVector[3].x, m_line3DVector[3].y, -m_line3DVtx[1].z);
875     glVertex3f(m_line3DVector[2].x, m_line3DVector[2].y, -m_line3DVtx[0].z);
876     
877     glColor4ub(m_line3DVtx[0].r, m_line3DVtx[0].g, m_line3DVtx[0].b, m_line3DVtx[0].a);
878     glVertex3f(m_line3DVector[1].x, m_line3DVector[1].y, -m_line3DVtx[1].z);
879     glVertex3f(m_line3DVector[0].x, m_line3DVector[0].y, -m_line3DVtx[0].z);
880
881     glEnd();
882 #endif
883     OPENGL_CHECK_ERRORS;
884
885     ApplyZBias(m_dwZBias);  // set Z offset back to previous value
886 #endif
887
888     return true;
889 }
890
891 extern FiddledVtx * g_pVtxBase;
892
893 // This is so weired that I can not do vertex transform by myself. I have to use
894 // OpenGL internal transform
895 bool OGLRender::RenderFlushTris()
896 {
897     if( !m_bSupportFogCoordExt )    
898         SetFogFlagForNegativeW();
899     else
900     {
901         if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
902         {
903             TurnFogOnOff(false);
904         }
905     }
906
907     ApplyZBias(m_dwZBias);  // set the bias factors
908
909     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW, false);
910     OPENGL_CHECK_ERRORS;
911
912 //    if (options.bOGLVertexClipper == FALSE )
913     {
914         glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
915         OPENGL_CHECK_ERRORS;
916     }
917 /*    else
918     {
919         //ClipVertexesOpenGL();
920         // Redo the index
921         // Set the array
922         glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5Clipped[0][0]) );
923         glEnableClientState( GL_VERTEX_ARRAY );
924
925         pglClientActiveTextureARB( GL_TEXTURE0_ARB );
926         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[0].u) );
927         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
928
929         pglClientActiveTextureARB( GL_TEXTURE1_ARB );
930         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[1].u) );
931         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
932
933         glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
934
935         // Reset the array
936         pglClientActiveTextureARB( GL_TEXTURE0_ARB );
937         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
938         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
939
940         pglClientActiveTextureARB( GL_TEXTURE1_ARB );
941         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
942         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
943
944         glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
945         glEnableClientState( GL_VERTEX_ARRAY );
946     }
947 */
948
949     if( !m_bSupportFogCoordExt )    
950         RestoreFogFlag();
951     else
952     {
953         if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
954         {
955             TurnFogOnOff(true);
956         }
957     }
958     return true;
959 }
960
961 void OGLRender::DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw)
962 {
963     if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE )
964     {
965         status.bVIOriginIsUpdated=false;
966         CGraphicsContext::Get()->UpdateFrame();
967         DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st Simple2DTexture");});
968     }
969
970     StartDrawSimple2DTexture(x0, y0, x1, y1, u0, v0, u1, v1, dif, spe, z, rhw);
971
972     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
973     glDisable(GL_CULL_FACE);
974     OPENGL_CHECK_ERRORS;
975
976     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
977     OPENGL_CHECK_ERRORS;
978
979     float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f;
980     float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f;
981     float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f;
982     float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f;
983
984 #if SDL_VIDEO_OPENGL
985
986 #ifdef HAVE_GLES
987     GLfloat colour[] = {
988             r,g,b,a,
989             r,g,b,a,
990             r,g,b,a,
991             r,g,b,a,
992             r,g,b,a,
993             r,g,b,a};
994
995     GLfloat tex[] = {
996             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
997             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
998             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
999             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
1000             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
1001             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v
1002     };
1003
1004     GLfloat tex2[] = {
1005             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
1006             g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
1007             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
1008             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
1009             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
1010             g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v
1011     };
1012
1013     GLfloat vertices[] = {
1014             g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z, 1,
1015             g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z, 1,
1016             g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z, 1,
1017             g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z, 1,
1018             g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z, 1,
1019             g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z, 1
1020     };
1021
1022     glColorPointer(4, GL_FLOAT, 0, &colour );
1023     glVertexPointer(4,GL_FLOAT, 0,&vertices);
1024     if( m_bMultiTexture )
1025     {
1026                 glClientActiveTexture( GL_TEXTURE1 );
1027                 glTexCoordPointer(2, GL_FLOAT, 0, &tex2);
1028         glClientActiveTexture( GL_TEXTURE0 );
1029     }
1030         glTexCoordPointer(2, GL_FLOAT, 0, &tex);
1031     glDrawArrays(GL_TRIANGLES,0,6);
1032     //Restore old pointers
1033     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
1034     glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
1035         glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
1036     if( m_bMultiTexture )
1037     {
1038                 glClientActiveTexture( GL_TEXTURE1 );
1039                 glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
1040     }
1041 #else
1042     glBegin(GL_TRIANGLES);
1043
1044     glColor4f(r,g,b,a);
1045
1046     OGLRender::TexCoord(g_texRectTVtx[0]);
1047     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
1048
1049     OGLRender::TexCoord(g_texRectTVtx[1]);
1050     glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z);
1051
1052     OGLRender::TexCoord(g_texRectTVtx[2]);
1053     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
1054
1055     OGLRender::TexCoord(g_texRectTVtx[0]);
1056     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
1057
1058     OGLRender::TexCoord(g_texRectTVtx[2]);
1059     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
1060
1061     OGLRender::TexCoord(g_texRectTVtx[3]);
1062     glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z);
1063     glEnd();
1064 #endif    
1065     OPENGL_CHECK_ERRORS;
1066
1067 #elif SDL_VIDEO_OPENGL_ES2
1068
1069     GLfloat colour[] = {
1070             r,g,b,a,
1071             r,g,b,a,
1072             r,g,b,a,
1073             r,g,b,a,
1074             r,g,b,a,
1075             r,g,b,a
1076     };
1077
1078     GLfloat tex[] = {
1079             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
1080             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
1081             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
1082
1083             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
1084             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
1085             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
1086     };
1087
1088      float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
1089
1090     GLfloat vertices[] = {
1091             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
1092             -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1,
1093             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
1094
1095             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
1096             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
1097             -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1
1098     };
1099
1100     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
1101     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
1102     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
1103     OPENGL_CHECK_ERRORS;
1104     glDrawArrays(GL_TRIANGLES,0,6);
1105     OPENGL_CHECK_ERRORS;
1106
1107     //Restore old pointers
1108     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
1109     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
1110     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
1111
1112 #endif
1113
1114     if( cullface ) glEnable(GL_CULL_FACE);
1115     OPENGL_CHECK_ERRORS;
1116 }
1117
1118 void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor, float depth, float rhw)
1119 {
1120     StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw);
1121
1122     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
1123     glDisable(GL_CULL_FACE);
1124     OPENGL_CHECK_ERRORS;
1125
1126     float a = (dwColor>>24)/255.0f;
1127     float r = ((dwColor>>16)&0xFF)/255.0f;
1128     float g = ((dwColor>>8)&0xFF)/255.0f;
1129     float b = (dwColor&0xFF)/255.0f;
1130
1131 #if SDL_VIDEO_OPENGL
1132
1133 #ifdef HAVE_GLES
1134     GLfloat colour[] = {
1135             r,g,b,a,
1136             r,g,b,a,
1137             r,g,b,a,
1138             r,g,b,a};
1139
1140     GLfloat vertices[] = {
1141             m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth, 1,
1142             m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth, 1,
1143             m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth, 1,
1144             m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth, 1
1145     };
1146
1147     glColorPointer(4, GL_FLOAT, 0, &colour );
1148     glVertexPointer(4,GL_FLOAT, 0,&vertices);
1149     if( m_bMultiTexture )
1150     {
1151                 glClientActiveTexture( GL_TEXTURE1 );
1152                 glActiveTexture( GL_TEXTURE1 );
1153                 glDisable(GL_TEXTURE_2D);
1154                 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1155         glClientActiveTexture( GL_TEXTURE0 );
1156     }
1157         glActiveTexture( GL_TEXTURE0 );
1158         glDisable(GL_TEXTURE_2D);
1159
1160     glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1161     OPENGL_CHECK_ERRORS;
1162     glColor4f(r,g,b,a);
1163     glDrawArrays(GL_TRIANGLE_FAN,0,4);
1164     OPENGL_CHECK_ERRORS;
1165     //Restore old pointers
1166     glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
1167     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1168     glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
1169         glEnable(GL_TEXTURE_2D);
1170     if( m_bMultiTexture )
1171     {
1172                 glActiveTexture( GL_TEXTURE1 );
1173                 glEnable(GL_TEXTURE_2D);
1174                 glClientActiveTexture( GL_TEXTURE1 );
1175                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1176     }
1177 #else
1178     glBegin(GL_TRIANGLE_FAN);
1179
1180     glColor4f(r,g,b,a);
1181     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth);
1182     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth);
1183     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth);
1184     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth);
1185     
1186     glEnd();
1187 #endif
1188     OPENGL_CHECK_ERRORS;
1189
1190 #elif SDL_VIDEO_OPENGL_ES2
1191
1192     GLfloat colour[] = {
1193             r,g,b,a,
1194             r,g,b,a,
1195             r,g,b,a,
1196             r,g,b,a};
1197     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
1198
1199     GLfloat vertices[] = {
1200             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1,
1201             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
1202             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
1203             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1
1204     };
1205
1206     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
1207     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
1208     glDisableVertexAttribArray(VS_TEXCOORD0);
1209     OPENGL_CHECK_ERRORS;
1210     glDrawArrays(GL_TRIANGLE_FAN,0,4);
1211     OPENGL_CHECK_ERRORS;
1212
1213     //Restore old pointers
1214     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
1215     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
1216     glEnableVertexAttribArray(VS_TEXCOORD0);
1217
1218 #endif
1219
1220     if( cullface ) glEnable(GL_CULL_FACE);
1221     OPENGL_CHECK_ERRORS;
1222 }
1223
1224 void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32 tile)
1225 {
1226     //glEnable(GL_CULL_FACE);
1227     EnableTexUnit(0,FALSE);
1228     OPENGL_CHECK_ERRORS;
1229     glEnable(GL_BLEND);
1230     OPENGL_CHECK_ERRORS;
1231     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1232     OPENGL_CHECK_ERRORS;
1233     //glEnable(GL_ALPHA_TEST);
1234 }
1235
1236 COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor)
1237 {
1238     uint32 color = curDiffuseColor;
1239     uint32 colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag;
1240     uint32 alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag;
1241     if( colorflag+alphaflag != MUX_0 )
1242     {
1243         if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 )
1244         {
1245             color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor));
1246         }
1247         else
1248             color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor));
1249     }
1250
1251     //return (color<<8)|(color>>24);
1252     return color;
1253 }
1254
1255 COLOR OGLRender::PostProcessSpecularColor()
1256 {
1257     return 0;
1258 }
1259
1260 void OGLRender::SetViewportRender()
1261 {
1262     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW);
1263     OPENGL_CHECK_ERRORS;
1264 }
1265
1266 void OGLRender::RenderReset()
1267 {
1268     CRender::RenderReset();
1269
1270     glMatrixMode(GL_PROJECTION);
1271     OPENGL_CHECK_ERRORS;
1272     glLoadIdentity();
1273     OPENGL_CHECK_ERRORS;
1274     glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1275     OPENGL_CHECK_ERRORS;
1276
1277     // position viewer 
1278     glMatrixMode(GL_MODELVIEW);
1279     OPENGL_CHECK_ERRORS;
1280     glLoadIdentity();
1281     OPENGL_CHECK_ERRORS;
1282 }
1283
1284 void OGLRender::SetAlphaTestEnable(BOOL bAlphaTestEnable)
1285 {
1286 #ifdef DEBUGGER
1287     if( bAlphaTestEnable && debuggerEnableAlphaTest )
1288 #else
1289     if( bAlphaTestEnable )
1290 #endif
1291 #if SDL_VIDEO_OPENGL
1292         glEnable(GL_ALPHA_TEST);
1293     else
1294         glDisable(GL_ALPHA_TEST);
1295 #elif SDL_VIDEO_OPENGL_ES2
1296     {
1297         COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
1298         frag->m_AlphaRef = m_dwAlpha / 255.0f;
1299     }
1300     else
1301     {
1302         COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
1303         frag->m_AlphaRef = 0.0f;
1304     }
1305 #endif
1306     OPENGL_CHECK_ERRORS;
1307 }
1308
1309 void OGLRender::BindTexture(GLuint texture, int unitno)
1310 {
1311 #ifdef DEBUGGER
1312     if( unitno != 0 )
1313     {
1314         DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0");
1315     }
1316 #endif
1317     if( m_curBoundTex[0] != texture )
1318     {
1319         glBindTexture(GL_TEXTURE_2D,texture);
1320         OPENGL_CHECK_ERRORS;
1321         m_curBoundTex[0] = texture;
1322     }
1323 }
1324
1325 void OGLRender::DisBindTexture(GLuint texture, int unitno)
1326 {
1327     //EnableTexUnit(0,FALSE);
1328     //glBindTexture(GL_TEXTURE_2D, 0);  //Not to bind any texture
1329 }
1330
1331 void OGLRender::EnableTexUnit(int unitno, BOOL flag)
1332 {
1333 #ifdef DEBUGGER
1334     if( unitno != 0 )
1335     {
1336         DebuggerAppendMsg("Check me, in the base ogl render, unitno!=0");
1337     }
1338 #endif
1339     if( m_texUnitEnabled[0] != flag )           //strange, why 0 and not unitno?
1340     {
1341         m_texUnitEnabled[0] = flag;
1342 #if SDL_VIDEO_OPENGL
1343         if( flag == TRUE ) {
1344 //                      pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1345             glEnable(GL_TEXTURE_2D);
1346         } else {
1347 //                      pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1348             glDisable(GL_TEXTURE_2D);
1349                 }
1350 /*              if (m_bMultiTexture)
1351                         pglActiveTexture(GL_TEXTURE1_ARB);*/
1352 #elif SDL_VIDEO_OPENGL_ES2
1353         if(flag)
1354         {
1355             pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1356             OPENGL_CHECK_ERRORS;
1357             glBindTexture(GL_TEXTURE_2D,m_curBoundTex[unitno]);
1358         }
1359         else
1360         {
1361             pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1362             OPENGL_CHECK_ERRORS;
1363             glEnable(GL_BLEND); //Need blend for transparent disabled texture
1364             glBindTexture(GL_TEXTURE_2D,disabledTextureID);
1365         }
1366 #endif
1367         OPENGL_CHECK_ERRORS;
1368     }
1369 }
1370
1371 void OGLRender::TexCoord2f(float u, float v)
1372 {
1373 #ifdef HAVE_GLES
1374         printf("*SEB* TexCoord2f(%f, %f)\n", u, v);
1375 #else
1376     glTexCoord2f(u, v);
1377 #endif
1378 }
1379
1380 void OGLRender::TexCoord(TLITVERTEX &vtxInfo)
1381 {
1382 #ifdef HAVE_GLES
1383         printf("*SEB* TexCoord(%f, %f)\n", vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
1384 #else
1385     glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
1386 #endif
1387 }
1388
1389 void OGLRender::UpdateScissor()
1390 {
1391     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1392     {
1393         // Hack for RE2
1394         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1395         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1396         glEnable(GL_SCISSOR_TEST);
1397         OPENGL_CHECK_ERRORS;
1398         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1399             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1400         OPENGL_CHECK_ERRORS;
1401     }
1402     else
1403     {
1404         UpdateScissorWithClipRatio();
1405     }
1406 }
1407
1408 void OGLRender::ApplyRDPScissor(bool force)
1409 {
1410     if( !force && status.curScissor == RDP_SCISSOR )    return;
1411
1412     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1413     {
1414         // Hack for RE2
1415         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1416         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1417         glEnable(GL_SCISSOR_TEST);
1418         OPENGL_CHECK_ERRORS;
1419         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1420             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1421         OPENGL_CHECK_ERRORS;
1422     }
1423     else
1424     {
1425         glScissor(windowSetting.uDisplayX+int(gRDP.scissor.left*windowSetting.fMultX), windowSetting.uDisplayY+int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1426             int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY ));
1427         OPENGL_CHECK_ERRORS;
1428     }
1429
1430     status.curScissor = RDP_SCISSOR;
1431 }
1432
1433 void OGLRender::ApplyScissorWithClipRatio(bool force)
1434 {
1435     if( !force && status.curScissor == RSP_SCISSOR )    return;
1436
1437     glEnable(GL_SCISSOR_TEST);
1438     OPENGL_CHECK_ERRORS;
1439     glScissor(windowSetting.uDisplayX+windowSetting.clipping.left, windowSetting.uDisplayY+int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse,
1440         windowSetting.clipping.width, windowSetting.clipping.height);
1441     OPENGL_CHECK_ERRORS;
1442
1443     status.curScissor = RSP_SCISSOR;
1444 }
1445
1446 void OGLRender::SetFogMinMax(float fMin, float fMax)
1447 {
1448 #if SDL_VIDEO_OPENGL
1449     glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1450     OPENGL_CHECK_ERRORS;
1451     glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1452     OPENGL_CHECK_ERRORS;
1453 #elif SDL_VIDEO_OPENGL_ES2
1454     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
1455     OPENGL_CHECK_ERRORS;
1456 #endif
1457 }
1458
1459 void OGLRender::TurnFogOnOff(bool flag)
1460 {
1461 #if SDL_VIDEO_OPENGL
1462     if( flag )
1463         glEnable(GL_FOG);
1464     else
1465         glDisable(GL_FOG);
1466     OPENGL_CHECK_ERRORS;
1467 #elif SDL_VIDEO_OPENGL_ES2
1468     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(flag);
1469     OPENGL_CHECK_ERRORS;
1470 #endif
1471 }
1472
1473 void OGLRender::SetFogEnable(bool bEnable)
1474 {
1475     DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != (bEnable==TRUE) && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable"));
1476
1477     gRSP.bFogEnabled = bEnable&&(options.fogMethod == 1);
1478     
1479     // If force fog
1480     if(options.fogMethod == 2)
1481     {
1482         gRSP.bFogEnabled = true;
1483     }
1484
1485 #if SDL_VIDEO_OPENGL
1486     if( gRSP.bFogEnabled )
1487     {
1488         //TRACE2("Enable fog, min=%f, max=%f",gRSPfFogMin,gRSPfFogMax );
1489         glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1490         OPENGL_CHECK_ERRORS;
1491         glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1492         OPENGL_CHECK_ERRORS;
1493         glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1494         OPENGL_CHECK_ERRORS;
1495         glEnable(GL_FOG);
1496         OPENGL_CHECK_ERRORS;
1497     }
1498     else
1499     {
1500         glDisable(GL_FOG);
1501         OPENGL_CHECK_ERRORS;
1502     }
1503 #elif SDL_VIDEO_OPENGL_ES2
1504     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
1505     OPENGL_CHECK_ERRORS;
1506 #endif
1507 }
1508
1509 void OGLRender::SetFogColor(uint32 r, uint32 g, uint32 b, uint32 a)
1510 {
1511     gRDP.fogColor = COLOR_RGBA(r, g, b, a); 
1512     gRDP.fvFogColor[0] = r/255.0f;      //r
1513     gRDP.fvFogColor[1] = g/255.0f;      //g
1514     gRDP.fvFogColor[2] = b/255.0f;      //b
1515     gRDP.fvFogColor[3] = a/255.0f;      //a
1516 #if SDL_VIDEO_OPENGL
1517     glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1518 #endif
1519     OPENGL_CHECK_ERRORS;
1520 }
1521
1522 void OGLRender::DisableMultiTexture()
1523 {
1524     pglActiveTexture(GL_TEXTURE1_ARB);
1525     OPENGL_CHECK_ERRORS;
1526     EnableTexUnit(1,FALSE);
1527     pglActiveTexture(GL_TEXTURE0_ARB);
1528     OPENGL_CHECK_ERRORS;
1529     EnableTexUnit(0,FALSE);
1530     pglActiveTexture(GL_TEXTURE0_ARB);
1531     OPENGL_CHECK_ERRORS;
1532     EnableTexUnit(0,TRUE);
1533 }
1534
1535 void OGLRender::EndRendering(void)
1536 {
1537 #if SDL_VIDEO_OPENGL
1538     glFlush();
1539     OPENGL_CHECK_ERRORS;
1540 #endif
1541     if( CRender::gRenderReferenceCount > 0 ) 
1542         CRender::gRenderReferenceCount--;
1543 }
1544
1545 void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag)
1546 {
1547     static GLint mx=0,my=0;
1548     static GLsizei m_width=0, m_height=0;
1549     static bool mflag=true;
1550         
1551     x+=windowSetting.uDisplayX;
1552     y+=windowSetting.uDisplayY;
1553
1554     if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag)
1555     {
1556         mx=x;
1557         my=y;
1558         m_width=width;
1559         m_height=height;
1560         mflag=flag;
1561         glMatrixMode(GL_PROJECTION);
1562         OPENGL_CHECK_ERRORS;
1563         glLoadIdentity();
1564         OPENGL_CHECK_ERRORS;
1565         if( flag )  glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1566         OPENGL_CHECK_ERRORS;
1567         glViewport(x,y,width,height);
1568 //printf("glViewport(%i, %i, %i, %i)\n", x, y, width, height);
1569         OPENGL_CHECK_ERRORS;
1570     }
1571 }