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