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