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