f11798eff509e93cf4b1e00b114d71ab2fdaf888
[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     float f1 = bias > 0 ? -3.0f : 0.0f;  // z offset = -3.0 * max(abs(dz/dx),abs(dz/dy)) per pixel delta z slope
354     float f2 = bias > 0 ? -3.0f : 0.0f;  // z offset += -3.0 * 1 bit
355
356 #ifdef PAULSCODE
357 //    Android_JNI_GetPolygonOffset(hardwareType, bias, &f1, &f2);
358 //      glPolygonOffset(0.2f, 0.2f);
359 #endif
360
361     if (bias > 0)
362     {
363         glEnable(GL_POLYGON_OFFSET_FILL);  // enable z offsets
364         OPENGL_CHECK_ERRORS;
365     }
366     else
367     {
368         glDisable(GL_POLYGON_OFFSET_FILL);  // disable z offsets
369         OPENGL_CHECK_ERRORS;
370     }
371     glPolygonOffset(f1, f2);  // set bias functions
372     OPENGL_CHECK_ERRORS;
373 }
374
375 void OGLRender::SetZBias(int bias)
376 {
377 #if defined(DEBUGGER)
378     if( pauseAtNext == true )
379       DebuggerAppendMsg("Set zbias = %d", bias);
380 #endif
381     // set member variable and apply the setting in opengl
382     m_dwZBias = bias;
383     ApplyZBias(bias);
384 }
385
386 void OGLRender::SetAlphaRef(uint32 dwAlpha)
387 {
388     if (m_dwAlpha != dwAlpha)
389     {
390         m_dwAlpha = dwAlpha;
391 #if SDL_VIDEO_OPENGL
392         glAlphaFunc(GL_GEQUAL, (float)dwAlpha);
393         OPENGL_CHECK_ERRORS;
394 #endif
395     }
396 }
397
398 void OGLRender::ForceAlphaRef(uint32 dwAlpha)
399 {
400 #if SDL_VIDEO_OPENGL
401     float ref = dwAlpha/255.0f;
402     glAlphaFunc(GL_GEQUAL, ref);
403     OPENGL_CHECK_ERRORS;
404 #elif SDL_VIDEO_OPENGL_ES2
405     m_dwAlpha = dwAlpha;
406 #endif
407 }
408
409 void OGLRender::SetFillMode(FillMode mode)
410 {
411 #if SDL_VIDEO_OPENGL
412     if( mode == RICE_FILLMODE_WINFRAME )
413     {
414         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
415         OPENGL_CHECK_ERRORS;
416     }
417     else
418     {
419         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
420         OPENGL_CHECK_ERRORS;
421     }
422 #endif
423 }
424
425 void OGLRender::SetCullMode(bool bCullFront, bool bCullBack)
426 {
427     CRender::SetCullMode(bCullFront, bCullBack);
428     if( bCullFront && bCullBack )
429     {
430         glCullFace(GL_FRONT_AND_BACK);
431         OPENGL_CHECK_ERRORS;
432         glEnable(GL_CULL_FACE);
433         OPENGL_CHECK_ERRORS;
434     }
435     else if( bCullFront )
436     {
437         glCullFace(GL_FRONT);
438         OPENGL_CHECK_ERRORS;
439         glEnable(GL_CULL_FACE);
440         OPENGL_CHECK_ERRORS;
441     }
442     else if( bCullBack )
443     {
444         glCullFace(GL_BACK);
445         OPENGL_CHECK_ERRORS;
446         glEnable(GL_CULL_FACE);
447         OPENGL_CHECK_ERRORS;
448     }
449     else
450     {
451         glDisable(GL_CULL_FACE);
452         OPENGL_CHECK_ERRORS;
453     }
454 }
455
456 bool OGLRender::SetCurrentTexture(int tile, CTexture *handler,uint32 dwTileWidth, uint32 dwTileHeight, TxtrCacheEntry *pTextureEntry)
457 {
458     RenderTexture &texture = g_textures[tile];
459     texture.pTextureEntry = pTextureEntry;
460
461     if( handler!= NULL  && texture.m_lpsTexturePtr != handler->GetTexture() )
462     {
463         texture.m_pCTexture = handler;
464         texture.m_lpsTexturePtr = handler->GetTexture();
465
466         texture.m_dwTileWidth = dwTileWidth;
467         texture.m_dwTileHeight = dwTileHeight;
468
469         if( handler->m_bIsEnhancedTexture )
470         {
471             texture.m_fTexWidth = (float)pTextureEntry->pTexture->m_dwCreatedTextureWidth;
472             texture.m_fTexHeight = (float)pTextureEntry->pTexture->m_dwCreatedTextureHeight;
473         }
474         else
475         {
476             texture.m_fTexWidth = (float)handler->m_dwCreatedTextureWidth;
477             texture.m_fTexHeight = (float)handler->m_dwCreatedTextureHeight;
478         }
479     }
480     
481     return true;
482 }
483
484 bool OGLRender::SetCurrentTexture(int tile, TxtrCacheEntry *pEntry)
485 {
486     if (pEntry != NULL && pEntry->pTexture != NULL)
487     {   
488         SetCurrentTexture( tile, pEntry->pTexture,  pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry);
489         return true;
490     }
491     else
492     {
493         SetCurrentTexture( tile, NULL, 64, 64, NULL );
494         return false;
495     }
496     return true;
497 }
498
499 void OGLRender::SetAddressUAllStages(uint32 dwTile, TextureUVFlag dwFlag)
500 {
501     SetTextureUFlag(dwFlag, dwTile);
502 }
503
504 void OGLRender::SetAddressVAllStages(uint32 dwTile, TextureUVFlag dwFlag)
505 {
506     SetTextureVFlag(dwFlag, dwTile);
507 }
508
509 void OGLRender::SetTexWrapS(int unitno,GLuint flag)
510 {
511     static GLuint mflag;
512     static GLuint mtex;
513 #ifdef DEBUGGER
514     if( unitno != 0 )
515     {
516         DebuggerAppendMsg("Check me, unitno != 0 in base ogl");
517     }
518 #endif
519     if( m_curBoundTex[0] != mtex || mflag != flag )
520     {
521         mtex = m_curBoundTex[0];
522         mflag = flag;
523         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag);
524         OPENGL_CHECK_ERRORS;
525     }
526 }
527 void OGLRender::SetTexWrapT(int unitno,GLuint flag)
528 {
529     static GLuint mflag;
530     static GLuint mtex;
531     if( m_curBoundTex[0] != mtex || mflag != flag )
532     {
533         mtex = m_curBoundTex[0];
534         mflag = flag;
535         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag);
536         OPENGL_CHECK_ERRORS;
537     }
538 }
539
540 void OGLRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32 dwTile)
541 {
542     TileUFlags[dwTile] = dwFlag;
543     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
544     {
545         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
546         if( pTexture )
547         {
548             EnableTexUnit(0,TRUE);
549             BindTexture(pTexture->m_dwTextureName, 0);
550         }
551         SetTexWrapS(0, OGLXUVFlagMaps[dwFlag].realFlag);
552     }
553 }
554 void OGLRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile)
555 {
556     TileVFlags[dwTile] = dwFlag;
557     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
558     {
559         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
560         if( pTexture ) 
561         {
562             EnableTexUnit(0,TRUE);
563             BindTexture(pTexture->m_dwTextureName, 0);
564         }
565         SetTexWrapT(0, OGLXUVFlagMaps[dwFlag].realFlag);
566     }
567 }
568
569 // Basic render drawing functions
570
571 bool OGLRender::RenderTexRect()
572 {
573     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
574     OPENGL_CHECK_ERRORS;
575
576     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
577     glDisable(GL_CULL_FACE);
578     OPENGL_CHECK_ERRORS;
579
580     float depth = -(g_texRectTVtx[3].z*2-1);
581
582 #if SDL_VIDEO_OPENGL
583
584     glBegin(GL_TRIANGLE_FAN);
585
586     glColor4f(g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a);
587     TexCoord(g_texRectTVtx[3]);
588     glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, depth);
589     
590     glColor4f(g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a);
591     TexCoord(g_texRectTVtx[2]);
592     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, depth);
593
594     glColor4f(g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a);
595     TexCoord(g_texRectTVtx[1]);
596     glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, depth);
597
598     glColor4f(g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a);
599     TexCoord(g_texRectTVtx[0]);
600     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, depth);
601
602     glEnd();
603     OPENGL_CHECK_ERRORS;
604
605 #elif SDL_VIDEO_OPENGL_ES2
606
607     GLfloat colour[] = {
608             g_texRectTVtx[3].r, g_texRectTVtx[3].g, g_texRectTVtx[3].b, g_texRectTVtx[3].a,
609             g_texRectTVtx[2].r, g_texRectTVtx[2].g, g_texRectTVtx[2].b, g_texRectTVtx[2].a,
610             g_texRectTVtx[1].r, g_texRectTVtx[1].g, g_texRectTVtx[1].b, g_texRectTVtx[1].a,
611             g_texRectTVtx[0].r, g_texRectTVtx[0].g, g_texRectTVtx[0].b, g_texRectTVtx[0].a
612     };
613
614     GLfloat tex[] = {
615             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
616             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
617             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
618             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
619     };
620
621     GLfloat tex2[] = {
622             g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
623             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
624             g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
625             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v
626     };
627
628     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
629
630     GLfloat vertices[] = {
631             -inv + g_texRectTVtx[3].x / w, inv - g_texRectTVtx[3].y / h, depth, 1,
632             -inv + g_texRectTVtx[2].x / w, inv - g_texRectTVtx[2].y / h, depth, 1,
633             -inv + g_texRectTVtx[1].x / w, inv - g_texRectTVtx[1].y / h, depth, 1,
634             -inv + g_texRectTVtx[0].x / w, inv - g_texRectTVtx[0].y / h, depth, 1
635     };
636
637     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_TRUE, 0, &colour );
638     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
639     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
640         glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2);
641     OPENGL_CHECK_ERRORS;
642     glDrawArrays(GL_TRIANGLE_FAN,0,4);
643     OPENGL_CHECK_ERRORS;
644
645     //Restore old pointers
646     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
647     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
648     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
649     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
650 #endif
651
652     if( cullface ) glEnable(GL_CULL_FACE);
653     OPENGL_CHECK_ERRORS;
654
655     return true;
656 }
657
658 bool OGLRender::RenderFillRect(uint32 dwColor, float depth)
659 {
660     float a = (dwColor>>24)/255.0f;
661     float r = ((dwColor>>16)&0xFF)/255.0f;
662     float g = ((dwColor>>8)&0xFF)/255.0f;
663     float b = (dwColor&0xFF)/255.0f;
664     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
665     OPENGL_CHECK_ERRORS;
666
667     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
668     glDisable(GL_CULL_FACE);
669     OPENGL_CHECK_ERRORS;
670
671 #if SDL_VIDEO_OPENGL
672
673     glBegin(GL_TRIANGLE_FAN);
674     glColor4f(r,g,b,a);
675     glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[1].y, depth, 1);
676     glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[1].y, depth, 1);
677     glVertex4f(m_fillRectVtx[1].x, m_fillRectVtx[0].y, depth, 1);
678     glVertex4f(m_fillRectVtx[0].x, m_fillRectVtx[0].y, depth, 1);
679     glEnd();
680     OPENGL_CHECK_ERRORS;
681
682 #elif SDL_VIDEO_OPENGL_ES2
683
684     GLfloat colour[] = {
685             r,g,b,a,
686             r,g,b,a,
687             r,g,b,a,
688             r,g,b,a};
689
690     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
691
692     GLfloat vertices[] = {
693             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
694             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
695             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[0].y / h, depth, 1,
696             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[0].y / h, depth, 1
697     };
698
699     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
700     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
701     glDisableVertexAttribArray(VS_TEXCOORD0);
702         glDisableVertexAttribArray(VS_TEXCOORD1);
703     OPENGL_CHECK_ERRORS;
704     glDrawArrays(GL_TRIANGLE_FAN,0,4);
705     OPENGL_CHECK_ERRORS;
706
707     //Restore old pointers
708     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
709     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
710     glEnableVertexAttribArray(VS_TEXCOORD0);
711         glEnableVertexAttribArray(VS_TEXCOORD1);
712
713 #endif
714
715     if( cullface ) glEnable(GL_CULL_FACE);
716     OPENGL_CHECK_ERRORS;
717
718     return true;
719 }
720
721 bool OGLRender::RenderLine3D()
722 {
723 #if SDL_VIDEO_OPENGL
724     ApplyZBias(0);  // disable z offsets
725
726     glBegin(GL_TRIANGLE_FAN);
727
728     glColor4f(m_line3DVtx[1].r, m_line3DVtx[1].g, m_line3DVtx[1].b, m_line3DVtx[1].a);
729     glVertex3f(m_line3DVector[3].x, m_line3DVector[3].y, -m_line3DVtx[1].z);
730     glVertex3f(m_line3DVector[2].x, m_line3DVector[2].y, -m_line3DVtx[0].z);
731     
732     glColor4ub(m_line3DVtx[0].r, m_line3DVtx[0].g, m_line3DVtx[0].b, m_line3DVtx[0].a);
733     glVertex3f(m_line3DVector[1].x, m_line3DVector[1].y, -m_line3DVtx[1].z);
734     glVertex3f(m_line3DVector[0].x, m_line3DVector[0].y, -m_line3DVtx[0].z);
735
736     glEnd();
737     OPENGL_CHECK_ERRORS;
738
739     ApplyZBias(m_dwZBias);  // set Z offset back to previous value
740 #endif
741
742     return true;
743 }
744
745 extern FiddledVtx * g_pVtxBase;
746
747 // This is so weired that I can not do vertex transform by myself. I have to use
748 // OpenGL internal transform
749 bool OGLRender::RenderFlushTris()
750 {
751     if( !m_bSupportFogCoordExt )    
752         SetFogFlagForNegativeW();
753     else
754     {
755         if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
756         {
757             TurnFogOnOff(false);
758         }
759     }
760
761     ApplyZBias(m_dwZBias);  // set the bias factors
762
763     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW, false);
764     OPENGL_CHECK_ERRORS;
765
766     //if options.bOGLVertexClipper == FALSE )
767     {
768         glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
769         OPENGL_CHECK_ERRORS;
770     }
771 /*  else
772     {
773         //ClipVertexesOpenGL();
774         // Redo the index
775         // Set the array
776         glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5Clipped[0][0]) );
777         glEnableClientState( GL_VERTEX_ARRAY );
778
779         pglClientActiveTextureARB( GL_TEXTURE0_ARB );
780         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[0].u) );
781         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
782
783         pglClientActiveTextureARB( GL_TEXTURE1_ARB );
784         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_clippedVtxBuffer[0].tcord[1].u) );
785         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
786
787         glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_INT, g_vtxIndex );
788
789         // Reset the array
790         pglClientActiveTextureARB( GL_TEXTURE0_ARB );
791         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u) );
792         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
793
794         pglClientActiveTextureARB( GL_TEXTURE1_ARB );
795         glTexCoordPointer( 2, GL_FLOAT, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u) );
796         glEnableClientState( GL_TEXTURE_COORD_ARRAY );
797
798         glVertexPointer( 4, GL_FLOAT, sizeof(float)*5, &(g_vtxProjected5[0][0]) );
799         glEnableClientState( GL_VERTEX_ARRAY );
800     }
801 */
802
803     if( !m_bSupportFogCoordExt )    
804         RestoreFogFlag();
805     else
806     {
807         if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
808         {
809             TurnFogOnOff(true);
810         }
811     }
812     return true;
813 }
814
815 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)
816 {
817     if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE )
818     {
819         status.bVIOriginIsUpdated=false;
820         CGraphicsContext::Get()->UpdateFrame();
821         DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,{DebuggerAppendMsg("Screen Update at 1st Simple2DTexture");});
822     }
823
824     StartDrawSimple2DTexture(x0, y0, x1, y1, u0, v0, u1, v1, dif, spe, z, rhw);
825
826     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
827     glDisable(GL_CULL_FACE);
828     OPENGL_CHECK_ERRORS;
829     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
830     OPENGL_CHECK_ERRORS;
831
832     float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f;
833     float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f;
834     float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f;
835     float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f;
836
837 #if SDL_VIDEO_OPENGL
838
839     glBegin(GL_TRIANGLES);
840
841     glColor4f(r,g,b,a);
842
843     OGLRender::TexCoord(g_texRectTVtx[0]);
844     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
845
846     OGLRender::TexCoord(g_texRectTVtx[1]);
847     glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z);
848
849     OGLRender::TexCoord(g_texRectTVtx[2]);
850     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
851
852     OGLRender::TexCoord(g_texRectTVtx[0]);
853     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
854
855     OGLRender::TexCoord(g_texRectTVtx[2]);
856     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
857
858     OGLRender::TexCoord(g_texRectTVtx[3]);
859     glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z);
860     
861     glEnd();
862     OPENGL_CHECK_ERRORS;
863
864 #elif SDL_VIDEO_OPENGL_ES2
865
866     GLfloat colour[] = {
867             r,g,b,a,
868             r,g,b,a,
869             r,g,b,a,
870             r,g,b,a,
871             r,g,b,a,
872             r,g,b,a
873     };
874
875     GLfloat tex[] = {
876             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
877             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
878             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
879
880             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
881             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
882             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
883     };
884
885     GLfloat tex2[] = {
886             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
887             g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
888             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
889
890             g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
891             g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
892             g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
893     };
894         
895      float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
896
897     GLfloat vertices[] = {
898             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
899             -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1,
900             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
901
902             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
903             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
904             -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1
905     };
906
907     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
908     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
909     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
910         glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2);
911     OPENGL_CHECK_ERRORS;
912     glDrawArrays(GL_TRIANGLES,0,6);
913     OPENGL_CHECK_ERRORS;
914
915     //Restore old pointers
916     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
917     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
918     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
919         glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
920
921 #endif
922
923     if( cullface ) glEnable(GL_CULL_FACE);
924     OPENGL_CHECK_ERRORS;
925 }
926
927 void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor, float depth, float rhw)
928 {
929     StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw);
930
931     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
932     glDisable(GL_CULL_FACE);
933     OPENGL_CHECK_ERRORS;
934
935     float a = (dwColor>>24)/255.0f;
936     float r = ((dwColor>>16)&0xFF)/255.0f;
937     float g = ((dwColor>>8)&0xFF)/255.0f;
938     float b = (dwColor&0xFF)/255.0f;
939
940 #if SDL_VIDEO_OPENGL
941
942     glBegin(GL_TRIANGLE_FAN);
943
944     glColor4f(r,g,b,a);
945     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth);
946     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth);
947     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth);
948     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth);
949     
950     glEnd();
951     OPENGL_CHECK_ERRORS;
952
953 #elif SDL_VIDEO_OPENGL_ES2
954
955     GLfloat colour[] = {
956             r,g,b,a,
957             r,g,b,a,
958             r,g,b,a,
959             r,g,b,a};
960     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
961
962     GLfloat vertices[] = {
963             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1,
964             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
965             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
966             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1
967     };
968
969     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
970     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
971     glDisableVertexAttribArray(VS_TEXCOORD0);
972         glDisableVertexAttribArray(VS_TEXCOORD1);
973     OPENGL_CHECK_ERRORS;
974     glDrawArrays(GL_TRIANGLE_FAN,0,4);
975     OPENGL_CHECK_ERRORS;
976
977     //Restore old pointers
978     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
979     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
980     glEnableVertexAttribArray(VS_TEXCOORD0);
981         glEnableVertexAttribArray(VS_TEXCOORD1);
982
983 #endif
984
985     if( cullface ) glEnable(GL_CULL_FACE);
986     OPENGL_CHECK_ERRORS;
987 }
988
989 void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32 tile)
990 {
991     //glEnable(GL_CULL_FACE);
992     EnableTexUnit(0,FALSE);
993     OPENGL_CHECK_ERRORS;
994     glEnable(GL_BLEND);
995     OPENGL_CHECK_ERRORS;
996     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
997     OPENGL_CHECK_ERRORS;
998     //glEnable(GL_ALPHA_TEST);
999 }
1000
1001 COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor)
1002 {
1003     uint32 color = curDiffuseColor;
1004     uint32 colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag;
1005     uint32 alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag;
1006     if( colorflag+alphaflag != MUX_0 )
1007     {
1008         if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 )
1009         {
1010             color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor));
1011         }
1012         else
1013             color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor));
1014     }
1015
1016     //return (color<<8)|(color>>24);
1017     return color;
1018 }
1019
1020 COLOR OGLRender::PostProcessSpecularColor()
1021 {
1022     return 0;
1023 }
1024
1025 void OGLRender::SetViewportRender()
1026 {
1027     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW);
1028     OPENGL_CHECK_ERRORS;
1029 }
1030
1031 void OGLRender::RenderReset()
1032 {
1033     CRender::RenderReset();
1034
1035     glMatrixMode(GL_PROJECTION);
1036     OPENGL_CHECK_ERRORS;
1037     glLoadIdentity();
1038     OPENGL_CHECK_ERRORS;
1039     glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1040     OPENGL_CHECK_ERRORS;
1041
1042     // position viewer 
1043     glMatrixMode(GL_MODELVIEW);
1044     OPENGL_CHECK_ERRORS;
1045     glLoadIdentity();
1046     OPENGL_CHECK_ERRORS;
1047 }
1048
1049 void OGLRender::SetAlphaTestEnable(BOOL bAlphaTestEnable)
1050 {
1051 #ifdef DEBUGGER
1052     if( bAlphaTestEnable && debuggerEnableAlphaTest )
1053 #else
1054
1055 #if SDL_VIDEO_OPENGL
1056     if( bAlphaTestEnable )
1057         glEnable(GL_ALPHA_TEST);
1058     else
1059         glDisable(GL_ALPHA_TEST);
1060     OPENGL_CHECK_ERRORS;
1061 #elif SDL_VIDEO_OPENGL_ES2
1062     COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
1063     frag->SetAlphaTestState(bAlphaTestEnable);
1064 #endif
1065
1066 #endif
1067 }
1068
1069 void OGLRender::BindTexture(GLuint texture, int unitno)
1070 {
1071 #ifdef DEBUGGER
1072     if( unitno != 0 )
1073     {
1074         DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0");
1075     }
1076 #endif
1077     if( m_curBoundTex[0] != texture )
1078     {
1079         glBindTexture(GL_TEXTURE_2D,texture);
1080         OPENGL_CHECK_ERRORS;
1081         m_curBoundTex[0] = texture;
1082     }
1083 }
1084
1085 void OGLRender::DisBindTexture(GLuint texture, int unitno)
1086 {
1087     //EnableTexUnit(0,FALSE);
1088     //glBindTexture(GL_TEXTURE_2D, 0);  //Not to bind any texture
1089 }
1090
1091 void OGLRender::EnableTexUnit(int unitno, BOOL flag)
1092 {
1093 #ifdef DEBUGGER
1094     if( unitno != 0 )
1095     {
1096         DebuggerAppendMsg("Check me, in the base ogl render, unitno!=0");
1097     }
1098 #endif
1099     if( m_texUnitEnabled[0] != flag )
1100     {
1101         m_texUnitEnabled[0] = flag;
1102
1103         if( flag == TRUE )
1104             glEnable(GL_TEXTURE_2D);
1105         else
1106             glDisable(GL_TEXTURE_2D);
1107     }
1108 }
1109
1110 void OGLRender::TexCoord2f(float u, float v)
1111 {
1112     glTexCoord2f(u, v);
1113 }
1114
1115 void OGLRender::TexCoord(TLITVERTEX &vtxInfo)
1116 {
1117     glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
1118 }
1119
1120 void OGLRender::UpdateScissor()
1121 {
1122     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1123     {
1124         // Hack for RE2
1125         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1126         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1127         glEnable(GL_SCISSOR_TEST);
1128         OPENGL_CHECK_ERRORS;
1129         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1130             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1131         OPENGL_CHECK_ERRORS;
1132     }
1133     else
1134     {
1135         UpdateScissorWithClipRatio();
1136     }
1137 }
1138
1139 void OGLRender::ApplyRDPScissor(bool force)
1140 {
1141     if( !force && status.curScissor == RDP_SCISSOR )    return;
1142
1143     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1144     {
1145         // Hack for RE2
1146         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1147         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1148         glEnable(GL_SCISSOR_TEST);
1149         OPENGL_CHECK_ERRORS;
1150         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1151             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1152         OPENGL_CHECK_ERRORS;
1153     }
1154     else
1155     {
1156         glScissor(windowSetting.uDisplayX+int(gRDP.scissor.left*windowSetting.fMultX), windowSetting.uDisplayY+int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1157             int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY ));
1158         OPENGL_CHECK_ERRORS;
1159     }
1160
1161     status.curScissor = RDP_SCISSOR;
1162 }
1163
1164 void OGLRender::ApplyScissorWithClipRatio(bool force)
1165 {
1166     if( !force && status.curScissor == RSP_SCISSOR )    return;
1167
1168     glEnable(GL_SCISSOR_TEST);
1169     OPENGL_CHECK_ERRORS;
1170     glScissor(windowSetting.uDisplayX+windowSetting.clipping.left, windowSetting.uDisplayY+int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse,
1171         windowSetting.clipping.width, windowSetting.clipping.height);
1172     OPENGL_CHECK_ERRORS;
1173
1174     status.curScissor = RSP_SCISSOR;
1175 }
1176
1177 void OGLRender::SetFogMinMax(float fMin, float fMax)
1178 {
1179 #if SDL_VIDEO_OPENGL
1180     glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1181     OPENGL_CHECK_ERRORS;
1182     glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1183     OPENGL_CHECK_ERRORS;
1184 #endif
1185 }
1186
1187 void OGLRender::TurnFogOnOff(bool flag)
1188 {
1189 #if SDL_VIDEO_OPENGL
1190     if( flag )
1191         glEnable(GL_FOG);
1192     else
1193         glDisable(GL_FOG);
1194     OPENGL_CHECK_ERRORS;
1195 #elif SDL_VIDEO_OPENGL_ES2
1196     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(flag);
1197     OPENGL_CHECK_ERRORS;
1198 #endif
1199 }
1200
1201 void OGLRender::SetFogEnable(bool bEnable)
1202 {
1203     DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != (bEnable==TRUE) && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable"));
1204
1205     gRSP.bFogEnabled = bEnable&&(options.fogMethod == 1);
1206     
1207     // If force fog
1208     if(options.fogMethod == 2)
1209     {
1210         gRSP.bFogEnabled = true;
1211     }
1212
1213 #if SDL_VIDEO_OPENGL
1214     if( gRSP.bFogEnabled )
1215     {
1216         //TRACE2("Enable fog, min=%f, max=%f",gRSPfFogMin,gRSPfFogMax );
1217         glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1218         OPENGL_CHECK_ERRORS;
1219         glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1220         OPENGL_CHECK_ERRORS;
1221         glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1222         OPENGL_CHECK_ERRORS;
1223         glEnable(GL_FOG);
1224         OPENGL_CHECK_ERRORS;
1225     }
1226     else
1227     {
1228         glDisable(GL_FOG);
1229         OPENGL_CHECK_ERRORS;
1230     }
1231 #elif SDL_VIDEO_OPENGL_ES2
1232     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(gRSP.bFogEnabled);
1233     OPENGL_CHECK_ERRORS;
1234 #endif
1235 }
1236
1237 void OGLRender::SetFogColor(uint32 r, uint32 g, uint32 b, uint32 a)
1238 {
1239     gRDP.fogColor = COLOR_RGBA(r, g, b, a); 
1240     gRDP.fvFogColor[0] = r/255.0f;      //r
1241     gRDP.fvFogColor[1] = g/255.0f;      //g
1242     gRDP.fvFogColor[2] = b/255.0f;      //b
1243     gRDP.fvFogColor[3] = a/255.0f;      //a
1244 #if SDL_VIDEO_OPENGL
1245     glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1246 #endif
1247     OPENGL_CHECK_ERRORS;
1248 }
1249
1250 void OGLRender::DisableMultiTexture()
1251 {
1252     pglActiveTexture(GL_TEXTURE1_ARB);
1253     OPENGL_CHECK_ERRORS;
1254     EnableTexUnit(1,FALSE);
1255     pglActiveTexture(GL_TEXTURE0_ARB);
1256     OPENGL_CHECK_ERRORS;
1257     EnableTexUnit(0,FALSE);
1258     pglActiveTexture(GL_TEXTURE0_ARB);
1259     OPENGL_CHECK_ERRORS;
1260     EnableTexUnit(0,TRUE);
1261 }
1262
1263 void OGLRender::EndRendering(void)
1264 {
1265 #if SDL_VIDEO_OPENGL
1266     glFlush();
1267     OPENGL_CHECK_ERRORS;
1268 #endif
1269     if( CRender::gRenderReferenceCount > 0 ) 
1270         CRender::gRenderReferenceCount--;
1271 }
1272
1273 void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag)
1274 {
1275     static GLint mx=0,my=0;
1276     static GLsizei m_width=0, m_height=0;
1277     static bool mflag=true;
1278     
1279     x+=windowSetting.uDisplayX;
1280     y+=windowSetting.uDisplayY;
1281
1282     if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag)
1283     {
1284         mx=x;
1285         my=y;
1286         m_width=width;
1287         m_height=height;
1288         mflag=flag;
1289         glMatrixMode(GL_PROJECTION);
1290         OPENGL_CHECK_ERRORS;
1291         glLoadIdentity();
1292         OPENGL_CHECK_ERRORS;
1293         if( flag )  glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1294         OPENGL_CHECK_ERRORS;
1295         glViewport(x,y,width,height);
1296         OPENGL_CHECK_ERRORS;
1297     }
1298 }
1299