gl_GraphicsAPIWrapper.cpp 14 KB

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