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 #include "OGLES2FragmentShaders.h"
22 #include "OGLRender.h"
23 #include "OGLGraphicsContext.h"
24 #include "OGLTexture.h"
25 #include "TextureManager.h"
26 
27 // FIXME: Use OGL internal L/T and matrix stack
28 // FIXME: Use OGL lookupAt function
29 // FIXME: Use OGL DisplayList
30 
31 UVFlagMap OGLXUVFlagMaps[] =
32 {
33     {TEXTURE_UV_FLAG_WRAP, GL_REPEAT},
34     {TEXTURE_UV_FLAG_MIRROR, GL_MIRRORED_REPEAT},
35     {TEXTURE_UV_FLAG_CLAMP, GL_CLAMP},
36 };
37 
38 //===================================================================
OGLRender()39 OGLRender::OGLRender()
40 {
41     m_bSupportClampToEdge = false;
42     for( int i=0; i<8; i++ )
43     {
44         m_curBoundTex[i]=0;
45         m_texUnitEnabled[i]= false;
46     }
47 
48     m_bEnableMultiTexture = false;
49 }
50 
~OGLRender()51 OGLRender::~OGLRender()
52 {
53     ClearDeviceObjects();
54 }
55 
InitDeviceObjects()56 bool OGLRender::InitDeviceObjects()
57 {
58     // enable Z-buffer by default
59     ZBufferEnable(true);
60     return true;
61 }
62 
ClearDeviceObjects()63 bool OGLRender::ClearDeviceObjects()
64 {
65     return true;
66 }
67 
Initialize(void)68 void OGLRender::Initialize(void)
69 {
70     glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true);
71 
72     OGLXUVFlagMaps[TEXTURE_UV_FLAG_MIRROR].realFlag = GL_MIRRORED_REPEAT;
73     m_bSupportClampToEdge = true;
74     OGLXUVFlagMaps[TEXTURE_UV_FLAG_CLAMP].realFlag = GL_CLAMP_TO_EDGE;
75 
76     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
77 
78 
79     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
80     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
81 
82     glVertexAttribPointer(VS_FOG,1,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][4]));
83 
84     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) );
85 }
86 //===================================================================
87 TextureFilterMap OglTexFilterMap[2]=
88 {
89     {FILTER_POINT, GL_NEAREST},
90     {FILTER_LINEAR, GL_LINEAR},
91 };
92 
ApplyTextureFilter()93 void OGLRender::ApplyTextureFilter()
94 {
95     static uint32_t minflag=0xFFFF, magflag=0xFFFF;
96     static uint32_t mtex;
97 
98     if( m_texUnitEnabled[0] )
99     {
100         if( mtex != m_curBoundTex[0] )
101         {
102             mtex = m_curBoundTex[0];
103             minflag = m_dwMinFilter;
104             magflag = m_dwMagFilter;
105             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
106             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
107         }
108         else
109         {
110             if( minflag != (unsigned int)m_dwMinFilter )
111             {
112                 minflag = m_dwMinFilter;
113                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, OglTexFilterMap[m_dwMinFilter].realFilter);
114             }
115             if( magflag != (unsigned int)m_dwMagFilter )
116             {
117                 magflag = m_dwMagFilter;
118                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, OglTexFilterMap[m_dwMagFilter].realFilter);
119             }
120         }
121     }
122 }
123 
SetShadeMode(RenderShadeMode mode)124 void OGLRender::SetShadeMode(RenderShadeMode mode)
125 {
126 }
127 
ZBufferEnable(bool bZBuffer)128 void OGLRender::ZBufferEnable(bool bZBuffer)
129 {
130     gRSP.bZBufferEnabled = bZBuffer;
131     if( g_curRomInfo.bForceDepthBuffer )
132         bZBuffer = true;
133     if( bZBuffer )
134     {
135         glDepthMask(GL_TRUE);
136         //glEnable(GL_DEPTH_TEST);
137         glDepthFunc( GL_LEQUAL );
138     }
139     else
140     {
141         glDepthMask(GL_FALSE);
142         //glDisable(GL_DEPTH_TEST);
143         glDepthFunc( GL_ALWAYS );
144     }
145 }
146 
ClearBuffer(bool cbuffer,bool zbuffer)147 void OGLRender::ClearBuffer(bool cbuffer, bool zbuffer)
148 {
149     uint32_t flag = 0;
150     float depth   = ((gRDP.originalFillColor&0xFFFF)>>2)/(float)0x3FFF;
151 
152     if( cbuffer )
153        flag |= GL_COLOR_BUFFER_BIT;
154     if( zbuffer )
155        flag |= GL_DEPTH_BUFFER_BIT;
156     glClearDepth(depth);
157     glClear(flag);
158 }
159 
ClearZBuffer(float depth)160 void OGLRender::ClearZBuffer(float depth)
161 {
162     uint32_t flag=GL_DEPTH_BUFFER_BIT;
163     glClearDepth(depth);
164     glClear(flag);
165 }
166 
SetZCompare(bool bZCompare)167 void OGLRender::SetZCompare(bool bZCompare)
168 {
169     if( g_curRomInfo.bForceDepthBuffer )
170         bZCompare = true;
171 
172     gRSP.bZBufferEnabled = bZCompare;
173     if( bZCompare == true )
174     {
175         //glEnable(GL_DEPTH_TEST);
176         glDepthFunc( GL_LEQUAL );
177     }
178     else
179     {
180         //glDisable(GL_DEPTH_TEST);
181         glDepthFunc( GL_ALWAYS );
182     }
183 }
184 
SetZUpdate(bool bZUpdate)185 void OGLRender::SetZUpdate(bool bZUpdate)
186 {
187     if( g_curRomInfo.bForceDepthBuffer )
188         bZUpdate = true;
189 
190     if( bZUpdate )
191     {
192         //glEnable(GL_DEPTH_TEST);
193         glDepthMask(GL_TRUE);
194     }
195     else
196         glDepthMask(GL_FALSE);
197 }
198 
ApplyZBias(int bias)199 void OGLRender::ApplyZBias(int bias)
200 {
201     static int old_bias;
202     float f1 = bias > 0 ? -3.0f : 0.0f;  // z offset = -3.0 * max(abs(dz/dx),abs(dz/dy)) per pixel delta z slope
203     float f2 = bias > 0 ? -3.0f : 0.0f;  // z offset += -3.0 * 1 bit
204 
205     if (bias == old_bias)
206         return;
207     old_bias = bias;
208 
209     if (bias > 0)
210     {
211         glEnable(GL_POLYGON_OFFSET_FILL);  // enable z offsets
212     }
213     else
214     {
215         glDisable(GL_POLYGON_OFFSET_FILL);  // disable z offsets
216     }
217     glPolygonOffset(f1, f2);  // set bias functions
218 }
219 
SetZBias(int bias)220 void OGLRender::SetZBias(int bias)
221 {
222 #if defined(DEBUGGER)
223     if( pauseAtNext == true )
224       DebuggerAppendMsg("Set zbias = %d", bias);
225 #endif
226     // set member variable and apply the setting in opengl
227     m_dwZBias = bias;
228     ApplyZBias(bias);
229 }
230 
SetAlphaRef(uint32_t dwAlpha)231 void OGLRender::SetAlphaRef(uint32_t dwAlpha)
232 {
233     if (m_dwAlpha != dwAlpha)
234     {
235         m_dwAlpha = dwAlpha;
236     }
237 }
238 
ForceAlphaRef(uint32_t dwAlpha)239 void OGLRender::ForceAlphaRef(uint32_t dwAlpha)
240 {
241     m_dwAlpha = dwAlpha;
242 }
243 
SetFillMode(FillMode mode)244 void OGLRender::SetFillMode(FillMode mode)
245 {
246 }
247 
SetCullMode(bool bCullFront,bool bCullBack)248 void OGLRender::SetCullMode(bool bCullFront, bool bCullBack)
249 {
250     CRender::SetCullMode(bCullFront, bCullBack);
251     if( bCullFront && bCullBack )
252     {
253         glCullFace(GL_FRONT_AND_BACK);
254         glEnable(GL_CULL_FACE);
255     }
256     else if( bCullFront )
257     {
258         glCullFace(GL_FRONT);
259         glEnable(GL_CULL_FACE);
260     }
261     else if( bCullBack )
262     {
263         glCullFace(GL_BACK);
264         glEnable(GL_CULL_FACE);
265     }
266     else
267     {
268         glDisable(GL_CULL_FACE);
269     }
270 }
271 
SetCurrentTexture(int tile,CTexture * handler,uint32_t dwTileWidth,uint32_t dwTileHeight,TxtrCacheEntry * pTextureEntry)272 bool OGLRender::SetCurrentTexture(int tile, CTexture *handler,uint32_t dwTileWidth, uint32_t dwTileHeight, TxtrCacheEntry *pTextureEntry)
273 {
274     RenderTexture &texture = g_textures[tile];
275     texture.pTextureEntry = pTextureEntry;
276 
277     if( handler!= NULL  && texture.m_lpsTexturePtr != handler->GetTexture() )
278     {
279         texture.m_pCTexture = handler;
280         texture.m_lpsTexturePtr = handler->GetTexture();
281 
282         texture.m_dwTileWidth = dwTileWidth;
283         texture.m_dwTileHeight = dwTileHeight;
284 
285         if( handler->m_bIsEnhancedTexture )
286         {
287             texture.m_fTexWidth = (float)pTextureEntry->pTexture->m_dwCreatedTextureWidth;
288             texture.m_fTexHeight = (float)pTextureEntry->pTexture->m_dwCreatedTextureHeight;
289         }
290         else
291         {
292             texture.m_fTexWidth = (float)handler->m_dwCreatedTextureWidth;
293             texture.m_fTexHeight = (float)handler->m_dwCreatedTextureHeight;
294         }
295     }
296 
297     return true;
298 }
299 
SetCurrentTexture(int tile,TxtrCacheEntry * pEntry)300 bool OGLRender::SetCurrentTexture(int tile, TxtrCacheEntry *pEntry)
301 {
302     if (pEntry != NULL && pEntry->pTexture != NULL)
303     {
304         SetCurrentTexture( tile, pEntry->pTexture,  pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry);
305         return true;
306     }
307     else
308     {
309         SetCurrentTexture( tile, NULL, 64, 64, NULL );
310         return false;
311     }
312     return true;
313 }
314 
SetAddressUAllStages(uint32_t dwTile,TextureUVFlag dwFlag)315 void OGLRender::SetAddressUAllStages(uint32_t dwTile, TextureUVFlag dwFlag)
316 {
317     SetTextureUFlag(dwFlag, dwTile);
318 }
319 
SetAddressVAllStages(uint32_t dwTile,TextureUVFlag dwFlag)320 void OGLRender::SetAddressVAllStages(uint32_t dwTile, TextureUVFlag dwFlag)
321 {
322     SetTextureVFlag(dwFlag, dwTile);
323 }
324 
SetTexWrapS(int unitno,GLuint flag)325 void OGLRender::SetTexWrapS(int unitno,GLuint flag)
326 {
327     static GLuint mflag;
328     static GLuint mtex;
329 #ifdef DEBUGGER
330     if( unitno != 0 )
331     {
332         DebuggerAppendMsg("Check me, unitno != 0 in base ogl");
333     }
334 #endif
335     if( m_curBoundTex[0] != mtex || mflag != flag )
336     {
337         mtex = m_curBoundTex[0];
338         mflag = flag;
339         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag);
340     }
341 }
SetTexWrapT(int unitno,GLuint flag)342 void OGLRender::SetTexWrapT(int unitno,GLuint flag)
343 {
344     static GLuint mflag;
345     static GLuint mtex;
346     if( m_curBoundTex[0] != mtex || mflag != flag )
347     {
348         mtex = m_curBoundTex[0];
349         mflag = flag;
350         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag);
351     }
352 }
353 
SetTextureUFlag(TextureUVFlag dwFlag,uint32_t dwTile)354 void OGLRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32_t dwTile)
355 {
356     TileUFlags[dwTile] = dwFlag;
357     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
358     {
359         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
360         if( pTexture )
361         {
362             EnableTexUnit(0, true);
363             BindTexture(pTexture->m_dwTextureName, 0);
364         }
365         SetTexWrapS(0, OGLXUVFlagMaps[dwFlag].realFlag);
366     }
367 }
SetTextureVFlag(TextureUVFlag dwFlag,uint32_t dwTile)368 void OGLRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32_t dwTile)
369 {
370     TileVFlags[dwTile] = dwFlag;
371     if( dwTile == gRSP.curTile )    // For basic OGL, only support the 1st texel
372     {
373         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
374         if( pTexture )
375         {
376             EnableTexUnit(0, true);
377             BindTexture(pTexture->m_dwTextureName, 0);
378         }
379         SetTexWrapT(0, OGLXUVFlagMaps[dwFlag].realFlag);
380     }
381 }
382 
383 // Basic render drawing functions
384 
RenderTexRect()385 bool OGLRender::RenderTexRect()
386 {
387     glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true);
388 
389     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
390     glDisable(GL_CULL_FACE);
391 
392     float depth = -(g_texRectTVtx[3].z*2-1);
393 
394     GLfloat colour[] = {
395             (GLfloat)g_texRectTVtx[3].r, (GLfloat)g_texRectTVtx[3].g, (GLfloat)g_texRectTVtx[3].b, (GLfloat)g_texRectTVtx[3].a,
396             (GLfloat)g_texRectTVtx[2].r, (GLfloat)g_texRectTVtx[2].g, (GLfloat)g_texRectTVtx[2].b, (GLfloat)g_texRectTVtx[2].a,
397             (GLfloat)g_texRectTVtx[1].r, (GLfloat)g_texRectTVtx[1].g, (GLfloat)g_texRectTVtx[1].b, (GLfloat)g_texRectTVtx[1].a,
398             (GLfloat)g_texRectTVtx[0].r, (GLfloat)g_texRectTVtx[0].g, (GLfloat)g_texRectTVtx[0].b, (GLfloat)g_texRectTVtx[0].a
399     };
400 
401     GLfloat tex[] = {
402             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
403             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
404             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
405             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v
406     };
407 
408     GLfloat tex2[] = {
409        g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
410        g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
411        g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
412        g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v
413 
414     };
415 
416     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
417 
418     GLfloat vertices[] = {
419             -inv + g_texRectTVtx[3].x / w, inv - g_texRectTVtx[3].y / h, depth, 1,
420             -inv + g_texRectTVtx[2].x / w, inv - g_texRectTVtx[2].y / h, depth, 1,
421             -inv + g_texRectTVtx[1].x / w, inv - g_texRectTVtx[1].y / h, depth, 1,
422             -inv + g_texRectTVtx[0].x / w, inv - g_texRectTVtx[0].y / h, depth, 1
423     };
424 
425     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_TRUE, 0, &colour );
426     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
427     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
428     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2);
429     glDrawArrays(GL_TRIANGLE_FAN,0,4);
430 
431     //Restore old pointers
432     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) );
433     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
434     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
435     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
436 
437     if( cullface ) glEnable(GL_CULL_FACE);
438 
439     return true;
440 }
441 
RenderFillRect(uint32_t dwColor,float depth)442 bool OGLRender::RenderFillRect(uint32_t dwColor, float depth)
443 {
444     float a = (dwColor>>24)/255.0f;
445     float r = ((dwColor>>16)&0xFF)/255.0f;
446     float g = ((dwColor>>8)&0xFF)/255.0f;
447     float b = (dwColor&0xFF)/255.0f;
448     glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true);
449 
450     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
451     glDisable(GL_CULL_FACE);
452 
453     GLfloat colour[] = {
454             r,g,b,a,
455             r,g,b,a,
456             r,g,b,a,
457             r,g,b,a};
458 
459     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
460 
461     GLfloat vertices[] = {
462             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
463             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[1].y / h, depth, 1,
464             -inv + m_fillRectVtx[1].x / w, inv - m_fillRectVtx[0].y / h, depth, 1,
465             -inv + m_fillRectVtx[0].x / w, inv - m_fillRectVtx[0].y / h, depth, 1
466     };
467 
468     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
469     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
470     glDisableVertexAttribArray(VS_TEXCOORD0);
471     glDisableVertexAttribArray(VS_TEXCOORD1);
472 
473     glDrawArrays(GL_TRIANGLE_FAN,0,4);
474 
475     //Restore old pointers
476     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) );
477     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
478     glEnableVertexAttribArray(VS_TEXCOORD0);
479     glEnableVertexAttribArray(VS_TEXCOORD1);
480 
481     if( cullface ) glEnable(GL_CULL_FACE);
482 
483     return true;
484 }
485 
RenderLine3D()486 bool OGLRender::RenderLine3D()
487 {
488     return true;
489 }
490 
491 extern FiddledVtx * g_pVtxBase;
492 
493 // This is so weird that I can not do vertex transform by myself. I have to use
494 // OpenGL internal transform
RenderFlushTris()495 bool OGLRender::RenderFlushTris()
496 {
497    if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
498    {
499       TurnFogOnOff(false);
500    }
501 
502     ApplyZBias(m_dwZBias);  // set the bias factors
503 
504     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight - windowSetting.vpTopW - windowSetting.vpHeightW, windowSetting.vpWidthW, windowSetting.vpHeightW, false);
505 
506     //if options.bOGLVertexClipper == false )
507     {
508         glDrawElements( GL_TRIANGLES, gRSP.numVertices, GL_UNSIGNED_SHORT, g_vtxIndex );
509     }
510 
511     if( !gRDP.bFogEnableInBlender && gRSP.bFogEnabled )
512     {
513        TurnFogOnOff(true);
514     }
515     return true;
516 }
517 
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)518 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)
519 {
520     if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_PRIMITIVE )
521     {
522         status.bVIOriginIsUpdated=false;
523         CGraphicsContext::Get()->UpdateFrame(false);
524     }
525 
526     StartDrawSimple2DTexture(x0, y0, x1, y1, u0, v0, u1, v1, dif, spe, z, rhw);
527 
528     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
529     glDisable(GL_CULL_FACE);
530 
531     glViewportWrapper(0, 0, windowSetting.uDisplayWidth, windowSetting.uDisplayHeight, true);
532 
533     float a = (g_texRectTVtx[0].dcDiffuse >>24)/255.0f;
534     float r = ((g_texRectTVtx[0].dcDiffuse>>16)&0xFF)/255.0f;
535     float g = ((g_texRectTVtx[0].dcDiffuse>>8)&0xFF)/255.0f;
536     float b = (g_texRectTVtx[0].dcDiffuse&0xFF)/255.0f;
537 
538     GLfloat colour[] = {
539             r,g,b,a,
540             r,g,b,a,
541             r,g,b,a,
542             r,g,b,a,
543             r,g,b,a,
544             r,g,b,a
545     };
546 
547     GLfloat tex[] = {
548             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
549             g_texRectTVtx[1].tcord[0].u,g_texRectTVtx[1].tcord[0].v,
550             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
551 
552             g_texRectTVtx[0].tcord[0].u,g_texRectTVtx[0].tcord[0].v,
553             g_texRectTVtx[2].tcord[0].u,g_texRectTVtx[2].tcord[0].v,
554             g_texRectTVtx[3].tcord[0].u,g_texRectTVtx[3].tcord[0].v,
555     };
556 
557     GLfloat tex2[] = {
558        g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
559        g_texRectTVtx[1].tcord[1].u,g_texRectTVtx[1].tcord[1].v,
560        g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
561 
562        g_texRectTVtx[0].tcord[1].u,g_texRectTVtx[0].tcord[1].v,
563        g_texRectTVtx[2].tcord[1].u,g_texRectTVtx[2].tcord[1].v,
564        g_texRectTVtx[3].tcord[1].u,g_texRectTVtx[3].tcord[1].v,
565 
566     };
567 
568      float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
569 
570     GLfloat vertices[] = {
571             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
572             -inv + g_texRectTVtx[1].x/ w, inv - g_texRectTVtx[1].y/ h, -g_texRectTVtx[1].z,1,
573             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
574 
575             -inv + g_texRectTVtx[0].x/ w, inv - g_texRectTVtx[0].y/ h, -g_texRectTVtx[0].z,1,
576             -inv + g_texRectTVtx[2].x/ w, inv - g_texRectTVtx[2].y/ h, -g_texRectTVtx[2].z,1,
577             -inv + g_texRectTVtx[3].x/ w, inv - g_texRectTVtx[3].y/ h, -g_texRectTVtx[3].z,1
578     };
579 
580     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
581     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
582     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, 0, &tex);
583     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, 0, &tex2);
584     glDrawArrays(GL_TRIANGLES,0,6);
585 
586     //Restore old pointers
587     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) );
588     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
589     glVertexAttribPointer(VS_TEXCOORD0,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[0].u));
590     glVertexAttribPointer(VS_TEXCOORD1,2,GL_FLOAT,GL_FALSE, sizeof( TLITVERTEX ), &(g_vtxBuffer[0].tcord[1].u));
591 
592     if( cullface ) glEnable(GL_CULL_FACE);
593 }
594 
DrawSimpleRect(int nX0,int nY0,int nX1,int nY1,uint32_t dwColor,float depth,float rhw)595 void OGLRender::DrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32_t dwColor, float depth, float rhw)
596 {
597     StartDrawSimpleRect(nX0, nY0, nX1, nY1, dwColor, depth, rhw);
598 
599     GLboolean cullface = glIsEnabled(GL_CULL_FACE);
600     glDisable(GL_CULL_FACE);
601 
602     float a = (dwColor>>24)/255.0f;
603     float r = ((dwColor>>16)&0xFF)/255.0f;
604     float g = ((dwColor>>8)&0xFF)/255.0f;
605     float b = (dwColor&0xFF)/255.0f;
606 
607     GLfloat colour[] = {
608             r,g,b,a,
609             r,g,b,a,
610             r,g,b,a,
611             r,g,b,a};
612     float w = windowSetting.uDisplayWidth / 2.0f, h = windowSetting.uDisplayHeight / 2.0f, inv = 1.0f;
613 
614     GLfloat vertices[] = {
615             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1,
616             -inv + m_simpleRectVtx[1].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
617             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[1].y / h, -depth, 1,
618             -inv + m_simpleRectVtx[0].x / w, inv - m_simpleRectVtx[0].y / h, -depth, 1
619     };
620 
621     glVertexAttribPointer(VS_COLOR, 4, GL_FLOAT,GL_FALSE, 0, &colour );
622     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,0,&vertices);
623     glDisableVertexAttribArray(VS_TEXCOORD0);
624     glDisableVertexAttribArray(VS_TEXCOORD1);
625 
626     glDrawArrays(GL_TRIANGLE_FAN,0,4);
627 
628     //Restore old pointers
629     glVertexAttribPointer(VS_COLOR, 4, GL_UNSIGNED_BYTE,GL_TRUE, sizeof(uint8_t)*4, &(g_oglVtxColors[0][0]) );
630     glVertexAttribPointer(VS_POSITION,4,GL_FLOAT,GL_FALSE,sizeof(float)*5,&(g_vtxProjected5[0][0]));
631     glEnableVertexAttribArray(VS_TEXCOORD0);
632     glEnableVertexAttribArray(VS_TEXCOORD1);
633 
634 
635     if( cullface ) glEnable(GL_CULL_FACE);
636 }
637 
638 #if 0
639 void OGLRender::InitCombinerBlenderForSimpleRectDraw(uint32_t tile)
640 {
641     //glEnable(GL_CULL_FACE);
642     EnableTexUnit(0, false);
643     glEnable(GL_BLEND);
644     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
645     //glEnable(GL_ALPHA_TEST);
646 }
647 #endif
648 
PostProcessDiffuseColor(COLOR curDiffuseColor)649 COLOR OGLRender::PostProcessDiffuseColor(COLOR curDiffuseColor)
650 {
651     uint32_t color = curDiffuseColor;
652     uint32_t colorflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeColorChannelFlag;
653     uint32_t alphaflag = m_pColorCombiner->m_pDecodedMux->m_dwShadeAlphaChannelFlag;
654     if( colorflag+alphaflag != MUX_0 )
655     {
656         if( (colorflag & 0xFFFFFF00) == 0 && (alphaflag & 0xFFFFFF00) == 0 )
657             color = (m_pColorCombiner->GetConstFactor(colorflag, alphaflag, curDiffuseColor));
658         else
659             color = (CalculateConstFactor(colorflag, alphaflag, curDiffuseColor));
660     }
661 
662     //return (color<<8)|(color>>24);
663     return color;
664 }
665 
PostProcessSpecularColor()666 COLOR OGLRender::PostProcessSpecularColor()
667 {
668     return 0;
669 }
670 
SetViewportRender()671 void OGLRender::SetViewportRender()
672 {
673     glViewportWrapper(windowSetting.vpLeftW, windowSetting.uDisplayHeight - windowSetting.vpTopW - windowSetting.vpHeightW, windowSetting.vpWidthW, windowSetting.vpHeightW, true);
674 }
675 
RenderReset()676 void OGLRender::RenderReset()
677 {
678     CRender::RenderReset();
679 }
680 
SetAlphaTestEnable(bool bAlphaTestEnable)681 void OGLRender::SetAlphaTestEnable(bool bAlphaTestEnable)
682 {
683 #ifdef DEBUGGER
684     if( bAlphaTestEnable && debuggerEnableAlphaTest )
685 #else
686         COGL_FragmentProgramCombiner* frag = (COGL_FragmentProgramCombiner*)m_pColorCombiner;
687         frag->SetAlphaTestState(bAlphaTestEnable);
688 #endif
689 }
690 
BindTexture(GLuint texture,int unitno)691 void OGLRender::BindTexture(GLuint texture, int unitno)
692 {
693 #ifdef DEBUGGER
694     if( unitno != 0 )
695     {
696         DebuggerAppendMsg("Check me, base ogl bind texture, unit no != 0");
697     }
698 #endif
699     if( m_curBoundTex[0] != texture )
700     {
701         glBindTexture(GL_TEXTURE_2D,texture);
702         m_curBoundTex[0] = texture;
703     }
704 }
705 
DisBindTexture(GLuint texture,int unitno)706 void OGLRender::DisBindTexture(GLuint texture, int unitno)
707 {
708     //EnableTexUnit(0, false);
709     //glBindTexture(GL_TEXTURE_2D, 0);  //Not to bind any texture
710 }
711 
EnableTexUnit(int unitno,bool flag)712 void OGLRender::EnableTexUnit(int unitno, bool flag)
713 {
714 #ifdef DEBUGGER
715     if( unitno != 0 )
716         DebuggerAppendMsg("Check me, in the base OpenGL render, unitno!=0");
717 #endif
718     if( m_texUnitEnabled[0] != flag )
719         m_texUnitEnabled[0] = flag;
720 }
721 
TexCoord2f(float u,float v)722 void OGLRender::TexCoord2f(float u, float v)
723 {
724     glTexCoord2f(u, v);
725 }
726 
TexCoord(TLITVERTEX & vtxInfo)727 void OGLRender::TexCoord(TLITVERTEX &vtxInfo)
728 {
729     glTexCoord2f(vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
730 }
731 
UpdateScissor()732 void OGLRender::UpdateScissor()
733 {
734     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*gfx_info.VI_WIDTH_REG & 0xFFF) )
735     {
736         // Hack for RE2
737         uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF;
738         uint32_t height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
739         glEnable(GL_SCISSOR_TEST);
740         glScissor(0, int(height * windowSetting.fMultY),
741             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
742     }
743     else
744     {
745         UpdateScissorWithClipRatio();
746     }
747 }
748 
ApplyRDPScissor(bool force)749 void OGLRender::ApplyRDPScissor(bool force)
750 {
751     if( !force && status.curScissor == RDP_SCISSOR )
752         return;
753 
754     if( options.bEnableHacks && g_CI.dwWidth == 0x200 && gRDP.scissor.right == 0x200 && g_CI.dwWidth>(*gfx_info.VI_WIDTH_REG & 0xFFF) )
755     {
756         // Hack for RE2
757         uint32_t width = *gfx_info.VI_WIDTH_REG & 0xFFF;
758         uint32_t height = (gRDP.scissor.right*gRDP.scissor.bottom)/width;
759         glEnable(GL_SCISSOR_TEST);
760         glScissor(0, int(height * windowSetting.fMultY),
761             int(width*windowSetting.fMultX), int(height*windowSetting.fMultY) );
762     }
763     else
764     {
765         glScissor(int(gRDP.scissor.left*windowSetting.fMultX), int((windowSetting.uViHeight-gRDP.scissor.bottom)*windowSetting.fMultY),
766             int((gRDP.scissor.right-gRDP.scissor.left)*windowSetting.fMultX), int((gRDP.scissor.bottom-gRDP.scissor.top)*windowSetting.fMultY ));
767     }
768 
769     status.curScissor = RDP_SCISSOR;
770 }
771 
ApplyScissorWithClipRatio(bool force)772 void OGLRender::ApplyScissorWithClipRatio(bool force)
773 {
774     if( !force && status.curScissor == RSP_SCISSOR )
775         return;
776 
777     glEnable(GL_SCISSOR_TEST);
778     glScissor(windowSetting.clipping.left, int((windowSetting.uViHeight-gRSP.real_clip_scissor_bottom)*windowSetting.fMultY),
779         windowSetting.clipping.width, windowSetting.clipping.height);
780 
781     status.curScissor = RSP_SCISSOR;
782 }
783 
SetFogMinMax(float fMin,float fMax)784 void OGLRender::SetFogMinMax(float fMin, float fMax)
785 {
786 }
787 
TurnFogOnOff(bool flag)788 void OGLRender::TurnFogOnOff(bool flag)
789 {
790     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(flag);
791 }
792 
SetFogEnable(bool bEnable)793 void OGLRender::SetFogEnable(bool bEnable)
794 {
795     gRSP.bFogEnabled = bEnable;
796 
797     // If force fog
798     if(options.fogMethod == 2)
799         gRSP.bFogEnabled = true;
800 
801     ((COGL_FragmentProgramCombiner*)m_pColorCombiner)->SetFogState(gRSP.bFogEnabled);
802 }
803 
SetFogColor(uint32_t r,uint32_t g,uint32_t b,uint32_t a)804 void OGLRender::SetFogColor(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
805 {
806     gRDP.fogColor = COLOR_RGBA(r, g, b, a);
807     gRDP.fvFogColor[0] = r/255.0f;      //r
808     gRDP.fvFogColor[1] = g/255.0f;      //g
809     gRDP.fvFogColor[2] = b/255.0f;      //b
810     gRDP.fvFogColor[3] = a/255.0f;      //a
811 }
812 
DisableMultiTexture()813 void OGLRender::DisableMultiTexture()
814 {
815     glActiveTexture(GL_TEXTURE1);
816     EnableTexUnit(1, false);
817     glActiveTexture(GL_TEXTURE0);
818     EnableTexUnit(0, false);
819     glActiveTexture(GL_TEXTURE0);
820     EnableTexUnit(0, true);
821 }
822 
EndRendering(void)823 void OGLRender::EndRendering(void)
824 {
825     if( CRender::gRenderReferenceCount > 0 )
826         CRender::gRenderReferenceCount--;
827 }
828 
glViewportWrapper(GLint x,GLint y,GLsizei width,GLsizei height,bool flag)829 void OGLRender::glViewportWrapper(GLint x, GLint y, GLsizei width, GLsizei height, bool flag)
830 {
831     static GLint mx=0,my=0;
832     static GLsizei m_width=0, m_height=0;
833     static bool mflag=true;
834 
835     if( x!=mx || y!=my || width!=m_width || height!=m_height || mflag!=flag)
836     {
837         mx=x;
838         my=y;
839         m_width=width;
840         m_height=height;
841         mflag=flag;
842         glViewport(x,y,width,height);
843     }
844 }
845 
846