draw_arb.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 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 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. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "tr_local.h"
  23. /*
  24. with standard calls, we can't do bump mapping or vertex colors with
  25. shader colors
  26. 2 texture units:
  27. falloff
  28. --
  29. light cube
  30. bump
  31. --
  32. light projection
  33. diffuse
  34. 3 texture units:
  35. light cube
  36. bump
  37. --
  38. falloff
  39. light projection
  40. diffuse
  41. 5 texture units:
  42. light cube
  43. bump
  44. falloff
  45. light projection
  46. diffuse
  47. */
  48. /*
  49. ==================
  50. RB_ARB_DrawInteraction
  51. backEnd.vLight
  52. backEnd.depthFunc must be equal for alpha tested surfaces to work right,
  53. it is set to lessThan for blended transparent surfaces
  54. ==================
  55. */
  56. static void RB_ARB_DrawInteraction( const drawInteraction_t *din ) {
  57. const drawSurf_t *surf = din->surf;
  58. const srfTriangles_t *tri = din->surf->geo;
  59. // set the vertex arrays, which may not all be enabled on a given pass
  60. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  61. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  62. GL_SelectTexture( 0 );
  63. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st );
  64. //-----------------------------------------------------
  65. //
  66. // bump / falloff
  67. //
  68. //-----------------------------------------------------
  69. // render light falloff * bumpmap lighting
  70. //
  71. // draw light falloff to the alpha channel
  72. //
  73. GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc );
  74. qglColor3f( 1, 1, 1 );
  75. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  76. qglEnable( GL_TEXTURE_GEN_S );
  77. qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[3].ToFloatPtr() );
  78. qglTexCoord2f( 0, 0.5 );
  79. // ATI R100 can't do partial texgens
  80. #define NO_MIXED_TEXGEN
  81. #ifdef NO_MIXED_TEXGEN
  82. idVec4 plane;
  83. plane[0] = 0;
  84. plane[1] = 0;
  85. plane[2] = 0;
  86. plane[3] = 0.5;
  87. qglEnable( GL_TEXTURE_GEN_T );
  88. qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane.ToFloatPtr() );
  89. plane[0] = 0;
  90. plane[1] = 0;
  91. plane[2] = 0;
  92. plane[3] = 1;
  93. qglEnable( GL_TEXTURE_GEN_Q );
  94. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane.ToFloatPtr() );
  95. #endif
  96. din->lightFalloffImage->Bind();
  97. // draw it
  98. RB_DrawElementsWithCounters( tri );
  99. qglDisable( GL_TEXTURE_GEN_S );
  100. #ifdef NO_MIXED_TEXGEN
  101. qglDisable( GL_TEXTURE_GEN_T );
  102. qglDisable( GL_TEXTURE_GEN_Q );
  103. #endif
  104. #if 0
  105. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK
  106. | backEnd.depthFunc );
  107. // the texccords are the non-normalized vector towards the light origin
  108. GL_SelectTexture( 0 );
  109. globalImages->normalCubeMapImage->Bind();
  110. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  111. qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() );
  112. // draw it
  113. RB_DrawElementsWithCounters( tri );
  114. return;
  115. #endif
  116. // we can't do bump mapping with standard calls, so skip it
  117. if ( glConfig.envDot3Available && glConfig.cubeMapAvailable ) {
  118. //
  119. // draw the bump map result onto the alpha channel
  120. //
  121. GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_COLORMASK | GLS_DEPTHMASK
  122. | backEnd.depthFunc );
  123. // texture 0 will be the per-surface bump map
  124. GL_SelectTexture( 0 );
  125. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  126. // FIXME: matrix work! RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf );
  127. din->bumpImage->Bind();
  128. // texture 1 is the normalization cube map
  129. // the texccords are the non-normalized vector towards the light origin
  130. GL_SelectTexture( 1 );
  131. if ( din->ambientLight ) {
  132. globalImages->ambientNormalMap->Bind(); // fixed value
  133. } else {
  134. globalImages->normalCubeMapImage->Bind();
  135. }
  136. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  137. qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() );
  138. // I just want alpha = Dot( texture0, texture1 )
  139. GL_TexEnv( GL_COMBINE_ARB );
  140. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB );
  141. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
  142. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
  143. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  144. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
  145. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  146. qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 );
  147. // draw it
  148. RB_DrawElementsWithCounters( tri );
  149. GL_TexEnv( GL_MODULATE );
  150. globalImages->BindNull();
  151. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  152. GL_SelectTexture( 0 );
  153. // RB_FinishStageTexture( &surfaceStage->texture, surf );
  154. }
  155. //-----------------------------------------------------
  156. //
  157. // projected light / surface color for diffuse maps
  158. //
  159. //-----------------------------------------------------
  160. // don't trash alpha
  161. GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_ALPHAMASK | GLS_DEPTHMASK
  162. | backEnd.depthFunc );
  163. // texture 0 will get the surface color texture
  164. GL_SelectTexture( 0 );
  165. // select the vertex color source
  166. if ( din->vertexColor == SVC_IGNORE ) {
  167. qglColor4fv( din->diffuseColor.ToFloatPtr() );
  168. } else {
  169. // FIXME: does this not get diffuseColor blended in?
  170. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
  171. qglEnableClientState( GL_COLOR_ARRAY );
  172. if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
  173. GL_TexEnv( GL_COMBINE_ARB );
  174. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
  175. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
  176. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
  177. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  178. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR );
  179. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  180. }
  181. }
  182. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  183. // FIXME: does this not get the texture matrix?
  184. // RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf );
  185. din->diffuseImage->Bind();
  186. // texture 1 will get the light projected texture
  187. GL_SelectTexture( 1 );
  188. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  189. qglEnable( GL_TEXTURE_GEN_S );
  190. qglEnable( GL_TEXTURE_GEN_T );
  191. qglEnable( GL_TEXTURE_GEN_Q );
  192. qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[0].ToFloatPtr() );
  193. qglTexGenfv( GL_T, GL_OBJECT_PLANE, din->lightProjection[1].ToFloatPtr() );
  194. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, din->lightProjection[2].ToFloatPtr() );
  195. din->lightImage->Bind();
  196. // draw it
  197. RB_DrawElementsWithCounters( tri );
  198. qglDisable( GL_TEXTURE_GEN_S );
  199. qglDisable( GL_TEXTURE_GEN_T );
  200. qglDisable( GL_TEXTURE_GEN_Q );
  201. globalImages->BindNull();
  202. GL_SelectTexture( 0 );
  203. if ( din->vertexColor != SVC_IGNORE ) {
  204. qglDisableClientState( GL_COLOR_ARRAY );
  205. GL_TexEnv( GL_MODULATE );
  206. }
  207. // RB_FinishStageTexture( &surfaceStage->texture, surf );
  208. }
  209. /*
  210. ==================
  211. RB_ARB_DrawThreeTextureInteraction
  212. Used by radeon R100 and Intel graphics parts
  213. backEnd.vLight
  214. backEnd.depthFunc must be equal for alpha tested surfaces to work right,
  215. it is set to lessThan for blended transparent surfaces
  216. ==================
  217. */
  218. static void RB_ARB_DrawThreeTextureInteraction( const drawInteraction_t *din ) {
  219. const drawSurf_t *surf = din->surf;
  220. const srfTriangles_t *tri = din->surf->geo;
  221. // set the vertex arrays, which may not all be enabled on a given pass
  222. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  223. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  224. GL_SelectTexture( 0 );
  225. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st );
  226. qglColor3f( 1, 1, 1 );
  227. //
  228. // bump map dot cubeMap into the alpha channel
  229. //
  230. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_COLORMASK | GLS_DEPTHMASK
  231. | backEnd.depthFunc );
  232. // texture 0 will be the per-surface bump map
  233. GL_SelectTexture( 0 );
  234. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  235. // FIXME: matrix work! RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf );
  236. din->bumpImage->Bind();
  237. // texture 1 is the normalization cube map
  238. // the texccords are the non-normalized vector towards the light origin
  239. GL_SelectTexture( 1 );
  240. if ( din->ambientLight ) {
  241. globalImages->ambientNormalMap->Bind(); // fixed value
  242. } else {
  243. globalImages->normalCubeMapImage->Bind();
  244. }
  245. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  246. qglTexCoordPointer( 3, GL_FLOAT, sizeof( lightingCache_t ), ((lightingCache_t *)vertexCache.Position(tri->lightingCache))->localLightVector.ToFloatPtr() );
  247. // I just want alpha = Dot( texture0, texture1 )
  248. GL_TexEnv( GL_COMBINE_ARB );
  249. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB );
  250. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
  251. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB );
  252. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  253. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
  254. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  255. qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 );
  256. // draw it
  257. RB_DrawElementsWithCounters( tri );
  258. GL_TexEnv( GL_MODULATE );
  259. globalImages->BindNull();
  260. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  261. GL_SelectTexture( 0 );
  262. // RB_FinishStageTexture( &surfaceStage->texture, surf );
  263. //-----------------------------------------------------
  264. //
  265. // light falloff / projected light / surface color for diffuse maps
  266. //
  267. //-----------------------------------------------------
  268. // multiply result by alpha, but don't trash alpha
  269. GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_ALPHAMASK | GLS_DEPTHMASK
  270. | backEnd.depthFunc );
  271. // texture 0 will get the surface color texture
  272. GL_SelectTexture( 0 );
  273. // select the vertex color source
  274. if ( din->vertexColor == SVC_IGNORE ) {
  275. qglColor4fv( din->diffuseColor.ToFloatPtr() );
  276. } else {
  277. // FIXME: does this not get diffuseColor blended in?
  278. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
  279. qglEnableClientState( GL_COLOR_ARRAY );
  280. if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
  281. GL_TexEnv( GL_COMBINE_ARB );
  282. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
  283. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
  284. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
  285. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  286. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR );
  287. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  288. }
  289. }
  290. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  291. // FIXME: does this not get the texture matrix?
  292. // RB_BindStageTexture( surfaceRegs, &surfaceStage->texture, surf );
  293. din->diffuseImage->Bind();
  294. // texture 1 will get the light projected texture
  295. GL_SelectTexture( 1 );
  296. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  297. qglEnable( GL_TEXTURE_GEN_S );
  298. qglEnable( GL_TEXTURE_GEN_T );
  299. qglEnable( GL_TEXTURE_GEN_Q );
  300. qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[0].ToFloatPtr() );
  301. qglTexGenfv( GL_T, GL_OBJECT_PLANE, din->lightProjection[1].ToFloatPtr() );
  302. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, din->lightProjection[2].ToFloatPtr() );
  303. din->lightImage->Bind();
  304. // texture 2 will get the light falloff texture
  305. GL_SelectTexture( 2 );
  306. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  307. qglEnable( GL_TEXTURE_GEN_S );
  308. qglEnable( GL_TEXTURE_GEN_T );
  309. qglEnable( GL_TEXTURE_GEN_Q );
  310. qglTexGenfv( GL_S, GL_OBJECT_PLANE, din->lightProjection[3].ToFloatPtr() );
  311. idVec4 plane;
  312. plane[0] = 0;
  313. plane[1] = 0;
  314. plane[2] = 0;
  315. plane[3] = 0.5;
  316. qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane.ToFloatPtr() );
  317. plane[0] = 0;
  318. plane[1] = 0;
  319. plane[2] = 0;
  320. plane[3] = 1;
  321. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane.ToFloatPtr() );
  322. din->lightFalloffImage->Bind();
  323. // draw it
  324. RB_DrawElementsWithCounters( tri );
  325. qglDisable( GL_TEXTURE_GEN_S );
  326. qglDisable( GL_TEXTURE_GEN_T );
  327. qglDisable( GL_TEXTURE_GEN_Q );
  328. globalImages->BindNull();
  329. GL_SelectTexture( 1 );
  330. qglDisable( GL_TEXTURE_GEN_S );
  331. qglDisable( GL_TEXTURE_GEN_T );
  332. qglDisable( GL_TEXTURE_GEN_Q );
  333. globalImages->BindNull();
  334. GL_SelectTexture( 0 );
  335. if ( din->vertexColor != SVC_IGNORE ) {
  336. qglDisableClientState( GL_COLOR_ARRAY );
  337. GL_TexEnv( GL_MODULATE );
  338. }
  339. // RB_FinishStageTexture( &surfaceStage->texture, surf );
  340. }
  341. /*
  342. ==================
  343. RB_CreateDrawInteractions
  344. ==================
  345. */
  346. static void RB_CreateDrawInteractions( const drawSurf_t *surf ) {
  347. if ( !surf ) {
  348. return;
  349. }
  350. // force a space calculation
  351. backEnd.currentSpace = NULL;
  352. if ( r_useTripleTextureARB.GetBool() && glConfig.maxTextureUnits >= 3 ) {
  353. for ( ; surf ; surf = surf->nextOnLight ) {
  354. // break it up into multiple primitive draw interactions if necessary
  355. RB_CreateSingleDrawInteractions( surf, RB_ARB_DrawThreeTextureInteraction );
  356. }
  357. } else {
  358. for ( ; surf ; surf = surf->nextOnLight ) {
  359. // break it up into multiple primitive draw interactions if necessary
  360. RB_CreateSingleDrawInteractions( surf, RB_ARB_DrawInteraction );
  361. }
  362. }
  363. }
  364. /*
  365. ==================
  366. RB_RenderViewLight
  367. ==================
  368. */
  369. static void RB_RenderViewLight( viewLight_t *vLight ) {
  370. backEnd.vLight = vLight;
  371. // do fogging later
  372. if ( vLight->lightShader->IsFogLight() ) {
  373. return;
  374. }
  375. if ( vLight->lightShader->IsBlendLight() ) {
  376. return;
  377. }
  378. RB_LogComment( "---------- RB_RenderViewLight 0x%p ----------\n", vLight );
  379. // clear the stencil buffer if needed
  380. if ( vLight->globalShadows || vLight->localShadows ) {
  381. backEnd.currentScissor = vLight->scissorRect;
  382. if ( r_useScissor.GetBool() ) {
  383. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  384. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  385. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  386. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  387. }
  388. qglClear( GL_STENCIL_BUFFER_BIT );
  389. } else {
  390. // no shadows, so no need to read or write the stencil buffer
  391. // we might in theory want to use GL_ALWAYS instead of disabling
  392. // completely, to satisfy the invarience rules
  393. qglStencilFunc( GL_ALWAYS, 128, 255 );
  394. }
  395. backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
  396. RB_StencilShadowPass( vLight->globalShadows );
  397. RB_CreateDrawInteractions( vLight->localInteractions );
  398. RB_StencilShadowPass( vLight->localShadows );
  399. RB_CreateDrawInteractions( vLight->globalInteractions );
  400. if ( r_skipTranslucent.GetBool() ) {
  401. return;
  402. }
  403. // disable stencil testing for translucent interactions, because
  404. // the shadow isn't calculated at their point, and the shadow
  405. // behind them may be depth fighting with a back side, so there
  406. // isn't any reasonable thing to do
  407. qglStencilFunc( GL_ALWAYS, 128, 255 );
  408. backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
  409. RB_CreateDrawInteractions( vLight->translucentInteractions );
  410. }
  411. /*
  412. ==================
  413. RB_ARB_DrawInteractions
  414. ==================
  415. */
  416. void RB_ARB_DrawInteractions( void ) {
  417. qglEnable( GL_STENCIL_TEST );
  418. for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  419. RB_RenderViewLight( vLight );
  420. }
  421. }