ee99b9737ca40365206befd28ac2d09669f5e85d
[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     glViewportWrapper(0, windowSetting.statusBarHeightToUse, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight);
819     OPENGL_CHECK_ERRORS;
820
821     float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f;
822     float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f;
823     float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f;
824     float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f;
825
826 #if SDL_VIDEO_OPENGL
827
828     glBegin(GL_TRIANGLES);
829
830     glColor4f(r,g,b,a);
831
832     OGLRender::TexCoord(g_texRectTVtx[0]);
833     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
834
835     OGLRender::TexCoord(g_texRectTVtx[1]);
836     glVertex3f(g_texRectTVtx[1].x, g_texRectTVtx[1].y, -g_texRectTVtx[1].z);
837
838     OGLRender::TexCoord(g_texRectTVtx[2]);
839     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
840
841     OGLRender::TexCoord(g_texRectTVtx[0]);
842     glVertex3f(g_texRectTVtx[0].x, g_texRectTVtx[0].y, -g_texRectTVtx[0].z);
843
844     OGLRender::TexCoord(g_texRectTVtx[2]);
845     glVertex3f(g_texRectTVtx[2].x, g_texRectTVtx[2].y, -g_texRectTVtx[2].z);
846
847     OGLRender::TexCoord(g_texRectTVtx[3]);
848     glVertex3f(g_texRectTVtx[3].x, g_texRectTVtx[3].y, -g_texRectTVtx[3].z);
849     
850     glEnd();
851     OPENGL_CHECK_ERRORS;
852
853 #elif SDL_VIDEO_OPENGL_ES2
854
855     GLfloat colour[] = {
856             r,g,b,a,
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     };
863
864     GLfloat tex[] = {
865             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
866             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
867             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
868
869             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
870             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
871             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
872     };
873
874      float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
875
876     GLfloat vertices[] = {
877             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
878             -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1,
879             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
880
881             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
882             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
883             -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1
884     };
885
886     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
887     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
888     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
889     OPENGL_CHECK_ERRORS;
890     glDrawArrays(GL_TRIANGLES,0,6);
891     OPENGL_CHECK_ERRORS;
892
893     //Restore old pointers
894     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
895     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
896     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
897
898 #endif
899
900     if( cullface ) glEnable(GL_CULL_FACE);
901     OPENGL_CHECK_ERRORS;
902 }
903
904 void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor, float depth, float rhw)
905 {
906     StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw);
907
908     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
909     glDisable(GL_CULL_FACE);
910     OPENGL_CHECK_ERRORS;
911
912     float a = (dwColor>>24)/255.0f;
913     float r = ((dwColor>>16)&0xFF)/255.0f;
914     float g = ((dwColor>>8)&0xFF)/255.0f;
915     float b = (dwColor&0xFF)/255.0f;
916
917 #if SDL_VIDEO_OPENGL
918
919     glBegin(GL_TRIANGLE_FAN);
920
921     glColor4f(r,g,b,a);
922     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[0].y, -depth);
923     glVertex3f(m_simpleRectVtx[1].x, m_simpleRectVtx[1].y, -depth);
924     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[1].y, -depth);
925     glVertex3f(m_simpleRectVtx[0].x, m_simpleRectVtx[0].y, -depth);
926     
927     glEnd();
928     OPENGL_CHECK_ERRORS;
929
930 #elif SDL_VIDEO_OPENGL_ES2
931
932     GLfloat colour[] = {
933             r,g,b,a,
934             r,g,b,a,
935             r,g,b,a,
936             r,g,b,a};
937     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
938
939     GLfloat vertices[] = {
940             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1,
941             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
942             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
943             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1
944     };
945
946     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
947     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
948     glDisableVertexAttribArray(VS_TEXCOORD0);
949     OPENGL_CHECK_ERRORS;
950     glDrawArrays(GL_TRIANGLE_FAN,0,4);
951     OPENGL_CHECK_ERRORS;
952
953     //Restore old pointers
954     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8)*4, &(g_oglVtxColors[0][0]) );
955     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
956     glEnableVertexAttribArray(VS_TEXCOORD0);
957
958 #endif
959
960     if( cullface ) glEnable(GL_CULL_FACE);
961     OPENGL_CHECK_ERRORS;
962 }
963
964 void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32 tile)
965 {
966     //glEnable(GL_CULL_FACE);
967     EnableTexUnit(0,FALSE);
968     OPENGL_CHECK_ERRORS;
969     glEnable(GL_BLEND);
970     OPENGL_CHECK_ERRORS;
971     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
972     OPENGL_CHECK_ERRORS;
973     //glEnable(GL_ALPHA_TEST);
974 }
975
976 COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor)
977 {
978     uint32 color = curDiffuseColor;
979     uint32 colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag;
980     uint32 alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag;
981     if( colorflag+alphaflag != MUX_0 )
982     {
983         if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 )
984         {
985             color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor));
986         }
987         else
988             color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor));
989     }
990
991     //return (color<<8)|(color>>24);
992     return color;
993 }
994
995 COLOR OGLRender::PostProcessSpecularColor()
996 {
997     return 0;
998 }
999
1000 void OGLRender::SetViewportRender()
1001 {
1002     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight-windowSetting.vpTopW-windowSetting.vpHeightW+windowSetting.statusBarHeightToUse, windowSetting.vpWidthW, windowSetting.vpHeightW);
1003     OPENGL_CHECK_ERRORS;
1004 }
1005
1006 void OGLRender::RenderReset()
1007 {
1008     CRender::RenderReset();
1009
1010     glMatrixMode(GL_PROJECTION);
1011     OPENGL_CHECK_ERRORS;
1012     glLoadIdentity();
1013     OPENGL_CHECK_ERRORS;
1014     glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1015     OPENGL_CHECK_ERRORS;
1016
1017     // position viewer 
1018     glMatrixMode(GL_MODELVIEW);
1019     OPENGL_CHECK_ERRORS;
1020     glLoadIdentity();
1021     OPENGL_CHECK_ERRORS;
1022 }
1023
1024 void OGLRender::SetAlphaTestEnable(BOOL bAlphaTestEnable)
1025 {
1026 #ifdef DEBUGGER
1027     if( bAlphaTestEnable && debuggerEnableAlphaTest )
1028 #else
1029     if( bAlphaTestEnable )
1030 #endif
1031 #if SDL_VIDEO_OPENGL
1032         glEnable(GL_ALPHA_TEST);
1033     else
1034         glDisable(GL_ALPHA_TEST);
1035 #elif SDL_VIDEO_OPENGL_ES2
1036     {
1037         COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
1038         frag->m_AlphaRef = m_dwAlpha / 255.0f;
1039     }
1040     else
1041     {
1042         COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
1043         frag->m_AlphaRef = 0.0f;
1044     }
1045 #endif
1046     OPENGL_CHECK_ERRORS;
1047 }
1048
1049 void OGLRender::BindTexture(GLuint texture, int unitno)
1050 {
1051 #ifdef DEBUGGER
1052     if( unitno != 0 )
1053     {
1054         DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0");
1055     }
1056 #endif
1057     if( m_curBoundTex[0] != texture )
1058     {
1059         glBindTexture(GL_TEXTURE_2D,texture);
1060         OPENGL_CHECK_ERRORS;
1061         m_curBoundTex[0] = texture;
1062     }
1063 }
1064
1065 void OGLRender::DisBindTexture(GLuint texture, int unitno)
1066 {
1067     //EnableTexUnit(0,FALSE);
1068     //glBindTexture(GL_TEXTURE_2D, 0);  //Not to bind any texture
1069 }
1070
1071 void OGLRender::EnableTexUnit(int unitno, BOOL flag)
1072 {
1073 #ifdef DEBUGGER
1074     if( unitno != 0 )
1075     {
1076         DebuggerAppendMsg("Check me, in the base ogl render, unitno!=0");
1077     }
1078 #endif
1079     if( m_texUnitEnabled[0] != flag )
1080     {
1081         m_texUnitEnabled[0] = flag;
1082 #if SDL_VIDEO_OPENGL
1083         if( flag == TRUE )
1084             glEnable(GL_TEXTURE_2D);
1085         else
1086             glDisable(GL_TEXTURE_2D);
1087 #elif SDL_VIDEO_OPENGL_ES2
1088         if(flag)
1089         {
1090             pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1091             OPENGL_CHECK_ERRORS;
1092             glBindTexture(GL_TEXTURE_2D,m_curBoundTex[unitno]);
1093         }
1094         else
1095         {
1096             pglActiveTexture(GL_TEXTURE0_ARB + unitno);
1097             OPENGL_CHECK_ERRORS;
1098             glEnable(GL_BLEND); //Need blend for transparent disabled texture
1099             glBindTexture(GL_TEXTURE_2D,disabledTextureID);
1100         }
1101 #endif
1102         OPENGL_CHECK_ERRORS;
1103     }
1104 }
1105
1106 void OGLRender::TexCoord2f(float u, float v)
1107 {
1108     glTexCoord2f(u, v);
1109 }
1110
1111 void OGLRender::TexCoord(TLITVERTEX &vtxInfo)
1112 {
1113     glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
1114 }
1115
1116 void OGLRender::UpdateScissor()
1117 {
1118     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1119     {
1120         // Hack for RE2
1121         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1122         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1123         glEnable(GL_SCISSOR_TEST);
1124         OPENGL_CHECK_ERRORS;
1125         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1126             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1127         OPENGL_CHECK_ERRORS;
1128     }
1129     else
1130     {
1131         UpdateScissorWithClipRatio();
1132     }
1133 }
1134
1135 void OGLRender::ApplyRDPScissor(bool force)
1136 {
1137     if( !force && status.curScissor == RDP_SCISSOR )    return;
1138
1139     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*g_GraphicsInfo.VI_WIDTH_REG & 0xFFF) )
1140     {
1141         // Hack for RE2
1142         uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1143         uint32 height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
1144         glEnable(GL_SCISSOR_TEST);
1145         OPENGL_CHECK_ERRORS;
1146         glScissor(windowSetting.uDisplayX, windowSetting.uDisplayY+int(height*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1147             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
1148         OPENGL_CHECK_ERRORS;
1149     }
1150     else
1151     {
1152         glScissor(windowSetting.uDisplayX+int(gRDP.scissor.left*windowSetting.fMultX), windowSetting.uDisplayY+int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY+windowSetting.statusBarHeightToUse),
1153             int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY ));
1154         OPENGL_CHECK_ERRORS;
1155     }
1156
1157     status.curScissor = RDP_SCISSOR;
1158 }
1159
1160 void OGLRender::ApplyScissorWithClipRatio(bool force)
1161 {
1162     if( !force && status.curScissor == RSP_SCISSOR )    return;
1163
1164     glEnable(GL_SCISSOR_TEST);
1165     OPENGL_CHECK_ERRORS;
1166     glScissor(windowSetting.uDisplayX+windowSetting.clipping.left, windowSetting.uDisplayY+int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY)+windowSetting.statusBarHeightToUse,
1167         windowSetting.clipping.width, windowSetting.clipping.height);
1168     OPENGL_CHECK_ERRORS;
1169
1170     status.curScissor = RSP_SCISSOR;
1171 }
1172
1173 void OGLRender::SetFogMinMax(float fMin, float fMax)
1174 {
1175 #if SDL_VIDEO_OPENGL
1176     glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1177     OPENGL_CHECK_ERRORS;
1178     glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1179     OPENGL_CHECK_ERRORS;
1180 #elif SDL_VIDEO_OPENGL_ES2
1181     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
1182     OPENGL_CHECK_ERRORS;
1183 #endif
1184 }
1185
1186 void OGLRender::TurnFogOnOff(bool flag)
1187 {
1188 #if SDL_VIDEO_OPENGL
1189     if( flag )
1190         glEnable(GL_FOG);
1191     else
1192         glDisable(GL_FOG);
1193     OPENGL_CHECK_ERRORS;
1194 #elif SDL_VIDEO_OPENGL_ES2
1195     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(flag);
1196     OPENGL_CHECK_ERRORS;
1197 #endif
1198 }
1199
1200 void OGLRender::SetFogEnable(bool bEnable)
1201 {
1202     DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != (bEnable==TRUE) && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable"));
1203
1204     gRSP.bFogEnabled = bEnable&&(options.fogMethod == 1);
1205     
1206     // If force fog
1207     if(options.fogMethod == 2)
1208     {
1209         gRSP.bFogEnabled = true;
1210     }
1211
1212 #if SDL_VIDEO_OPENGL
1213     if( gRSP.bFogEnabled )
1214     {
1215         //TRACE2("Enable fog, min=%f, max=%f",gRSPfFogMin,gRSPfFogMax );
1216         glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1217         OPENGL_CHECK_ERRORS;
1218         glFogf(GL_FOG_START, gRSPfFogMin); // Fog Start Depth
1219         OPENGL_CHECK_ERRORS;
1220         glFogf(GL_FOG_END, gRSPfFogMax); // Fog End Depth
1221         OPENGL_CHECK_ERRORS;
1222         glEnable(GL_FOG);
1223         OPENGL_CHECK_ERRORS;
1224     }
1225     else
1226     {
1227         glDisable(GL_FOG);
1228         OPENGL_CHECK_ERRORS;
1229     }
1230 #elif SDL_VIDEO_OPENGL_ES2
1231     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->UpdateFog(gRSP.bFogEnabled);
1232     OPENGL_CHECK_ERRORS;
1233 #endif
1234 }
1235
1236 void OGLRender::SetFogColor(uint32 r, uint32 g, uint32 b, uint32 a)
1237 {
1238     gRDP.fogColor = COLOR_RGBA(r, g, b, a); 
1239     gRDP.fvFogColor[0] = r/255.0f;      //r
1240     gRDP.fvFogColor[1] = g/255.0f;      //g
1241     gRDP.fvFogColor[2] = b/255.0f;      //b
1242     gRDP.fvFogColor[3] = a/255.0f;      //a
1243 #if SDL_VIDEO_OPENGL
1244     glFogfv(GL_FOG_COLOR, gRDP.fvFogColor); // Set Fog Color
1245 #endif
1246     OPENGL_CHECK_ERRORS;
1247 }
1248
1249 void OGLRender::DisableMultiTexture()
1250 {
1251     pglActiveTexture(GL_TEXTURE1_ARB);
1252     OPENGL_CHECK_ERRORS;
1253     EnableTexUnit(1,FALSE);
1254     pglActiveTexture(GL_TEXTURE0_ARB);
1255     OPENGL_CHECK_ERRORS;
1256     EnableTexUnit(0,FALSE);
1257     pglActiveTexture(GL_TEXTURE0_ARB);
1258     OPENGL_CHECK_ERRORS;
1259     EnableTexUnit(0,TRUE);
1260 }
1261
1262 void OGLRender::EndRendering(void)
1263 {
1264 #if SDL_VIDEO_OPENGL
1265     glFlush();
1266     OPENGL_CHECK_ERRORS;
1267 #endif
1268     if( CRender::gRenderReferenceCount > 0 ) 
1269         CRender::gRenderReferenceCount--;
1270 }
1271
1272 void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag)
1273 {
1274     static GLint mx=0,my=0;
1275     static GLsizei m_width=0, m_height=0;
1276     static bool mflag=true;
1277     
1278     x+=windowSetting.uDisplayX;
1279     y+=windowSetting.uDisplayY;
1280
1281     if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag)
1282     {
1283         mx=x;
1284         my=y;
1285         m_width=width;
1286         m_height=height;
1287         mflag=flag;
1288         glMatrixMode(GL_PROJECTION);
1289         OPENGL_CHECK_ERRORS;
1290         glLoadIdentity();
1291         OPENGL_CHECK_ERRORS;
1292         if( flag )  glOrtho(0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, 0, -1, 1);
1293         OPENGL_CHECK_ERRORS;
1294         glViewport(x,y,width,height);
1295         OPENGL_CHECK_ERRORS;
1296     }
1297 }
1298