DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }