gl_GraphicsAPIWrapper.cpp (14440B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #pragma hdrstop 30 #include "../../idlib/precompiled.h" 31 32 #include "../tr_local.h" 33 34 /* 35 ==================== 36 GL_SelectTexture 37 ==================== 38 */ 39 void GL_SelectTexture( int unit ) { 40 if ( backEnd.glState.currenttmu == unit ) { 41 return; 42 } 43 44 if ( unit < 0 || unit >= glConfig.maxTextureImageUnits ) { 45 common->Warning( "GL_SelectTexture: unit = %i", unit ); 46 return; 47 } 48 49 RENDERLOG_PRINTF( "GL_SelectTexture( %i );\n", unit ); 50 51 backEnd.glState.currenttmu = unit; 52 } 53 54 /* 55 ==================== 56 GL_Cull 57 58 This handles the flipping needed when the view being 59 rendered is a mirored view. 60 ==================== 61 */ 62 void GL_Cull( int cullType ) { 63 if ( backEnd.glState.faceCulling == cullType ) { 64 return; 65 } 66 67 if ( cullType == CT_TWO_SIDED ) { 68 qglDisable( GL_CULL_FACE ); 69 } else { 70 if ( backEnd.glState.faceCulling == CT_TWO_SIDED ) { 71 qglEnable( GL_CULL_FACE ); 72 } 73 74 if ( cullType == CT_BACK_SIDED ) { 75 if ( backEnd.viewDef->isMirror ) { 76 qglCullFace( GL_FRONT ); 77 } else { 78 qglCullFace( GL_BACK ); 79 } 80 } else { 81 if ( backEnd.viewDef->isMirror ) { 82 qglCullFace( GL_BACK ); 83 } else { 84 qglCullFace( GL_FRONT ); 85 } 86 } 87 } 88 89 backEnd.glState.faceCulling = cullType; 90 } 91 92 /* 93 ==================== 94 GL_Scissor 95 ==================== 96 */ 97 void GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h ) { 98 qglScissor( x, y, w, h ); 99 } 100 101 /* 102 ==================== 103 GL_Viewport 104 ==================== 105 */ 106 void GL_Viewport( int x /* left */, int y /* bottom */, int w, int h ) { 107 qglViewport( x, y, w, h ); 108 } 109 110 /* 111 ==================== 112 GL_PolygonOffset 113 ==================== 114 */ 115 void GL_PolygonOffset( float scale, float bias ) { 116 backEnd.glState.polyOfsScale = scale; 117 backEnd.glState.polyOfsBias = bias; 118 if ( backEnd.glState.glStateBits & GLS_POLYGON_OFFSET ) { 119 qglPolygonOffset( scale, bias ); 120 } 121 } 122 123 /* 124 ======================== 125 GL_DepthBoundsTest 126 ======================== 127 */ 128 void GL_DepthBoundsTest( const float zmin, const float zmax ) { 129 if ( !glConfig.depthBoundsTestAvailable || zmin > zmax ) { 130 return; 131 } 132 133 if ( zmin == 0.0f && zmax == 0.0f ) { 134 qglDisable( GL_DEPTH_BOUNDS_TEST_EXT ); 135 } else { 136 qglEnable( GL_DEPTH_BOUNDS_TEST_EXT ); 137 qglDepthBoundsEXT( zmin, zmax ); 138 } 139 } 140 141 /* 142 ======================== 143 GL_StartDepthPass 144 ======================== 145 */ 146 void GL_StartDepthPass( const idScreenRect & rect ) { 147 } 148 149 /* 150 ======================== 151 GL_FinishDepthPass 152 ======================== 153 */ 154 void GL_FinishDepthPass() { 155 } 156 157 /* 158 ======================== 159 GL_GetDepthPassRect 160 ======================== 161 */ 162 void GL_GetDepthPassRect( idScreenRect & rect ) { 163 rect.Clear(); 164 } 165 166 /* 167 ==================== 168 GL_Color 169 ==================== 170 */ 171 void GL_Color( float * color ) { 172 if ( color == NULL ) { 173 return; 174 } 175 GL_Color( color[0], color[1], color[2], color[3] ); 176 } 177 178 /* 179 ==================== 180 GL_Color 181 ==================== 182 */ 183 void GL_Color( float r, float g, float b ) { 184 GL_Color( r, g, b, 1.0f ); 185 } 186 187 /* 188 ==================== 189 GL_Color 190 ==================== 191 */ 192 void GL_Color( float r, float g, float b, float a ) { 193 float parm[4]; 194 parm[0] = idMath::ClampFloat( 0.0f, 1.0f, r ); 195 parm[1] = idMath::ClampFloat( 0.0f, 1.0f, g ); 196 parm[2] = idMath::ClampFloat( 0.0f, 1.0f, b ); 197 parm[3] = idMath::ClampFloat( 0.0f, 1.0f, a ); 198 renderProgManager.SetRenderParm( RENDERPARM_COLOR, parm ); 199 } 200 201 /* 202 ======================== 203 GL_Clear 204 ======================== 205 */ 206 void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a ) { 207 int clearFlags = 0; 208 if ( color ) { 209 qglClearColor( r, g, b, a ); 210 clearFlags |= GL_COLOR_BUFFER_BIT; 211 } 212 if ( depth ) { 213 clearFlags |= GL_DEPTH_BUFFER_BIT; 214 } 215 if ( stencil ) { 216 qglClearStencil( stencilValue ); 217 clearFlags |= GL_STENCIL_BUFFER_BIT; 218 } 219 qglClear( clearFlags ); 220 } 221 222 /* 223 ======================== 224 GL_SetDefaultState 225 226 This should initialize all GL state that any part of the entire program 227 may touch, including the editor. 228 ======================== 229 */ 230 void GL_SetDefaultState() { 231 RENDERLOG_PRINTF( "--- GL_SetDefaultState ---\n" ); 232 233 qglClearDepth( 1.0f ); 234 235 // make sure our GL state vector is set correctly 236 memset( &backEnd.glState, 0, sizeof( backEnd.glState ) ); 237 GL_State( 0, true ); 238 239 // These are changed by GL_Cull 240 qglCullFace( GL_FRONT_AND_BACK ); 241 qglEnable( GL_CULL_FACE ); 242 243 // These are changed by GL_State 244 qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); 245 qglBlendFunc( GL_ONE, GL_ZERO ); 246 qglDepthMask( GL_TRUE ); 247 qglDepthFunc( GL_LESS ); 248 qglDisable( GL_STENCIL_TEST ); 249 qglDisable( GL_POLYGON_OFFSET_FILL ); 250 qglDisable( GL_POLYGON_OFFSET_LINE ); 251 qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 252 253 // These should never be changed 254 qglShadeModel( GL_SMOOTH ); 255 qglEnable( GL_DEPTH_TEST ); 256 qglEnable( GL_BLEND ); 257 qglEnable( GL_SCISSOR_TEST ); 258 qglDrawBuffer( GL_BACK ); 259 qglReadBuffer( GL_BACK ); 260 261 if ( r_useScissor.GetBool() ) { 262 qglScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() ); 263 } 264 } 265 266 /* 267 ==================== 268 GL_State 269 270 This routine is responsible for setting the most commonly changed state 271 ==================== 272 */ 273 void GL_State( uint64 stateBits, bool forceGlState ) { 274 uint64 diff = stateBits ^ backEnd.glState.glStateBits; 275 276 if ( !r_useStateCaching.GetBool() || forceGlState ) { 277 // make sure everything is set all the time, so we 278 // can see if our delta checking is screwing up 279 diff = 0xFFFFFFFFFFFFFFFF; 280 } else if ( diff == 0 ) { 281 return; 282 } 283 284 // 285 // check depthFunc bits 286 // 287 if ( diff & GLS_DEPTHFUNC_BITS ) { 288 switch ( stateBits & GLS_DEPTHFUNC_BITS ) { 289 case GLS_DEPTHFUNC_EQUAL: qglDepthFunc( GL_EQUAL ); break; 290 case GLS_DEPTHFUNC_ALWAYS: qglDepthFunc( GL_ALWAYS ); break; 291 case GLS_DEPTHFUNC_LESS: qglDepthFunc( GL_LEQUAL ); break; 292 case GLS_DEPTHFUNC_GREATER: qglDepthFunc( GL_GEQUAL ); break; 293 } 294 } 295 296 // 297 // check blend bits 298 // 299 if ( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) { 300 GLenum srcFactor = GL_ONE; 301 GLenum dstFactor = GL_ZERO; 302 303 switch ( stateBits & GLS_SRCBLEND_BITS ) { 304 case GLS_SRCBLEND_ZERO: srcFactor = GL_ZERO; break; 305 case GLS_SRCBLEND_ONE: srcFactor = GL_ONE; break; 306 case GLS_SRCBLEND_DST_COLOR: srcFactor = GL_DST_COLOR; break; 307 case GLS_SRCBLEND_ONE_MINUS_DST_COLOR: srcFactor = GL_ONE_MINUS_DST_COLOR; break; 308 case GLS_SRCBLEND_SRC_ALPHA: srcFactor = GL_SRC_ALPHA; break; 309 case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA: srcFactor = GL_ONE_MINUS_SRC_ALPHA; break; 310 case GLS_SRCBLEND_DST_ALPHA: srcFactor = GL_DST_ALPHA; break; 311 case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA: srcFactor = GL_ONE_MINUS_DST_ALPHA; break; 312 default: 313 assert( !"GL_State: invalid src blend state bits\n" ); 314 break; 315 } 316 317 switch ( stateBits & GLS_DSTBLEND_BITS ) { 318 case GLS_DSTBLEND_ZERO: dstFactor = GL_ZERO; break; 319 case GLS_DSTBLEND_ONE: dstFactor = GL_ONE; break; 320 case GLS_DSTBLEND_SRC_COLOR: dstFactor = GL_SRC_COLOR; break; 321 case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR: dstFactor = GL_ONE_MINUS_SRC_COLOR; break; 322 case GLS_DSTBLEND_SRC_ALPHA: dstFactor = GL_SRC_ALPHA; break; 323 case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA: dstFactor = GL_ONE_MINUS_SRC_ALPHA; break; 324 case GLS_DSTBLEND_DST_ALPHA: dstFactor = GL_DST_ALPHA; break; 325 case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA: dstFactor = GL_ONE_MINUS_DST_ALPHA; break; 326 default: 327 assert( !"GL_State: invalid dst blend state bits\n" ); 328 break; 329 } 330 331 // Only actually update GL's blend func if blending is enabled. 332 if ( srcFactor == GL_ONE && dstFactor == GL_ZERO ) { 333 qglDisable( GL_BLEND ); 334 } else { 335 qglEnable( GL_BLEND ); 336 qglBlendFunc( srcFactor, dstFactor ); 337 } 338 } 339 340 // 341 // check depthmask 342 // 343 if ( diff & GLS_DEPTHMASK ) { 344 if ( stateBits & GLS_DEPTHMASK ) { 345 qglDepthMask( GL_FALSE ); 346 } else { 347 qglDepthMask( GL_TRUE ); 348 } 349 } 350 351 // 352 // check colormask 353 // 354 if ( diff & (GLS_REDMASK|GLS_GREENMASK|GLS_BLUEMASK|GLS_ALPHAMASK) ) { 355 GLboolean r = ( stateBits & GLS_REDMASK ) ? GL_FALSE : GL_TRUE; 356 GLboolean g = ( stateBits & GLS_GREENMASK ) ? GL_FALSE : GL_TRUE; 357 GLboolean b = ( stateBits & GLS_BLUEMASK ) ? GL_FALSE : GL_TRUE; 358 GLboolean a = ( stateBits & GLS_ALPHAMASK ) ? GL_FALSE : GL_TRUE; 359 qglColorMask( r, g, b, a ); 360 } 361 362 // 363 // fill/line mode 364 // 365 if ( diff & GLS_POLYMODE_LINE ) { 366 if ( stateBits & GLS_POLYMODE_LINE ) { 367 qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 368 } else { 369 qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 370 } 371 } 372 373 // 374 // polygon offset 375 // 376 if ( diff & GLS_POLYGON_OFFSET ) { 377 if ( stateBits & GLS_POLYGON_OFFSET ) { 378 qglPolygonOffset( backEnd.glState.polyOfsScale, backEnd.glState.polyOfsBias ); 379 qglEnable( GL_POLYGON_OFFSET_FILL ); 380 qglEnable( GL_POLYGON_OFFSET_LINE ); 381 } else { 382 qglDisable( GL_POLYGON_OFFSET_FILL ); 383 qglDisable( GL_POLYGON_OFFSET_LINE ); 384 } 385 } 386 387 #if !defined( USE_CORE_PROFILE ) 388 // 389 // alpha test 390 // 391 if ( diff & ( GLS_ALPHATEST_FUNC_BITS | GLS_ALPHATEST_FUNC_REF_BITS ) ) { 392 if ( ( stateBits & GLS_ALPHATEST_FUNC_BITS ) != 0 ) { 393 qglEnable( GL_ALPHA_TEST ); 394 395 GLenum func = GL_ALWAYS; 396 switch ( stateBits & GLS_ALPHATEST_FUNC_BITS ) { 397 case GLS_ALPHATEST_FUNC_LESS: func = GL_LESS; break; 398 case GLS_ALPHATEST_FUNC_EQUAL: func = GL_EQUAL; break; 399 case GLS_ALPHATEST_FUNC_GREATER: func = GL_GEQUAL; break; 400 default: assert( false ); 401 } 402 GLclampf ref = ( ( stateBits & GLS_ALPHATEST_FUNC_REF_BITS ) >> GLS_ALPHATEST_FUNC_REF_SHIFT ) / (float)0xFF; 403 qglAlphaFunc( func, ref ); 404 } else { 405 qglDisable( GL_ALPHA_TEST ); 406 } 407 } 408 #endif 409 410 // 411 // stencil 412 // 413 if ( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) { 414 if ( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 ) { 415 qglEnable( GL_STENCIL_TEST ); 416 } else { 417 qglDisable( GL_STENCIL_TEST ); 418 } 419 } 420 if ( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) ) { 421 GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); 422 GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); 423 GLenum func = 0; 424 425 switch ( stateBits & GLS_STENCIL_FUNC_BITS ) { 426 case GLS_STENCIL_FUNC_NEVER: func = GL_NEVER; break; 427 case GLS_STENCIL_FUNC_LESS: func = GL_LESS; break; 428 case GLS_STENCIL_FUNC_EQUAL: func = GL_EQUAL; break; 429 case GLS_STENCIL_FUNC_LEQUAL: func = GL_LEQUAL; break; 430 case GLS_STENCIL_FUNC_GREATER: func = GL_GREATER; break; 431 case GLS_STENCIL_FUNC_NOTEQUAL: func = GL_NOTEQUAL; break; 432 case GLS_STENCIL_FUNC_GEQUAL: func = GL_GEQUAL; break; 433 case GLS_STENCIL_FUNC_ALWAYS: func = GL_ALWAYS; break; 434 } 435 qglStencilFunc( func, ref, mask ); 436 } 437 if ( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) ) { 438 GLenum sFail = 0; 439 GLenum zFail = 0; 440 GLenum pass = 0; 441 442 switch ( stateBits & GLS_STENCIL_OP_FAIL_BITS ) { 443 case GLS_STENCIL_OP_FAIL_KEEP: sFail = GL_KEEP; break; 444 case GLS_STENCIL_OP_FAIL_ZERO: sFail = GL_ZERO; break; 445 case GLS_STENCIL_OP_FAIL_REPLACE: sFail = GL_REPLACE; break; 446 case GLS_STENCIL_OP_FAIL_INCR: sFail = GL_INCR; break; 447 case GLS_STENCIL_OP_FAIL_DECR: sFail = GL_DECR; break; 448 case GLS_STENCIL_OP_FAIL_INVERT: sFail = GL_INVERT; break; 449 case GLS_STENCIL_OP_FAIL_INCR_WRAP: sFail = GL_INCR_WRAP; break; 450 case GLS_STENCIL_OP_FAIL_DECR_WRAP: sFail = GL_DECR_WRAP; break; 451 } 452 switch ( stateBits & GLS_STENCIL_OP_ZFAIL_BITS ) { 453 case GLS_STENCIL_OP_ZFAIL_KEEP: zFail = GL_KEEP; break; 454 case GLS_STENCIL_OP_ZFAIL_ZERO: zFail = GL_ZERO; break; 455 case GLS_STENCIL_OP_ZFAIL_REPLACE: zFail = GL_REPLACE; break; 456 case GLS_STENCIL_OP_ZFAIL_INCR: zFail = GL_INCR; break; 457 case GLS_STENCIL_OP_ZFAIL_DECR: zFail = GL_DECR; break; 458 case GLS_STENCIL_OP_ZFAIL_INVERT: zFail = GL_INVERT; break; 459 case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:zFail = GL_INCR_WRAP; break; 460 case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:zFail = GL_DECR_WRAP; break; 461 } 462 switch ( stateBits & GLS_STENCIL_OP_PASS_BITS ) { 463 case GLS_STENCIL_OP_PASS_KEEP: pass = GL_KEEP; break; 464 case GLS_STENCIL_OP_PASS_ZERO: pass = GL_ZERO; break; 465 case GLS_STENCIL_OP_PASS_REPLACE: pass = GL_REPLACE; break; 466 case GLS_STENCIL_OP_PASS_INCR: pass = GL_INCR; break; 467 case GLS_STENCIL_OP_PASS_DECR: pass = GL_DECR; break; 468 case GLS_STENCIL_OP_PASS_INVERT: pass = GL_INVERT; break; 469 case GLS_STENCIL_OP_PASS_INCR_WRAP: pass = GL_INCR_WRAP; break; 470 case GLS_STENCIL_OP_PASS_DECR_WRAP: pass = GL_DECR_WRAP; break; 471 } 472 qglStencilOp( sFail, zFail, pass ); 473 } 474 475 backEnd.glState.glStateBits = stateBits; 476 } 477 478 /* 479 ================= 480 GL_GetCurrentState 481 ================= 482 */ 483 uint64 GL_GetCurrentState() { 484 return backEnd.glState.glStateBits; 485 } 486 487 /* 488 ======================== 489 GL_GetCurrentStateMinusStencil 490 ======================== 491 */ 492 uint64 GL_GetCurrentStateMinusStencil() { 493 return GL_GetCurrentState() & ~(GLS_STENCIL_OP_BITS|GLS_STENCIL_FUNC_BITS|GLS_STENCIL_FUNC_REF_BITS|GLS_STENCIL_FUNC_MASK_BITS); 494 }