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