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