draw_common.cpp 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726
  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. =====================
  25. RB_BakeTextureMatrixIntoTexgen
  26. =====================
  27. */
  28. void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float *textureMatrix ) {
  29. float genMatrix[16];
  30. float final[16];
  31. genMatrix[0] = lightProject[0][0];
  32. genMatrix[4] = lightProject[0][1];
  33. genMatrix[8] = lightProject[0][2];
  34. genMatrix[12] = lightProject[0][3];
  35. genMatrix[1] = lightProject[1][0];
  36. genMatrix[5] = lightProject[1][1];
  37. genMatrix[9] = lightProject[1][2];
  38. genMatrix[13] = lightProject[1][3];
  39. genMatrix[2] = 0;
  40. genMatrix[6] = 0;
  41. genMatrix[10] = 0;
  42. genMatrix[14] = 0;
  43. genMatrix[3] = lightProject[2][0];
  44. genMatrix[7] = lightProject[2][1];
  45. genMatrix[11] = lightProject[2][2];
  46. genMatrix[15] = lightProject[2][3];
  47. myGlMultMatrix( genMatrix, backEnd.lightTextureMatrix, final );
  48. lightProject[0][0] = final[0];
  49. lightProject[0][1] = final[4];
  50. lightProject[0][2] = final[8];
  51. lightProject[0][3] = final[12];
  52. lightProject[1][0] = final[1];
  53. lightProject[1][1] = final[5];
  54. lightProject[1][2] = final[9];
  55. lightProject[1][3] = final[13];
  56. }
  57. /*
  58. ================
  59. RB_PrepareStageTexturing
  60. ================
  61. */
  62. void RB_PrepareStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) {
  63. // set privatePolygonOffset if necessary
  64. if ( pStage->privatePolygonOffset ) {
  65. qglEnable( GL_POLYGON_OFFSET_FILL );
  66. qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * pStage->privatePolygonOffset );
  67. }
  68. // set the texture matrix if needed
  69. if ( pStage->texture.hasMatrix ) {
  70. RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture );
  71. }
  72. // texgens
  73. if ( pStage->texture.texgen == TG_DIFFUSE_CUBE ) {
  74. qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  75. }
  76. if ( pStage->texture.texgen == TG_SKYBOX_CUBE || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) {
  77. qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) );
  78. }
  79. if ( pStage->texture.texgen == TG_SCREEN ) {
  80. qglEnable( GL_TEXTURE_GEN_S );
  81. qglEnable( GL_TEXTURE_GEN_T );
  82. qglEnable( GL_TEXTURE_GEN_Q );
  83. float mat[16], plane[4];
  84. myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
  85. plane[0] = mat[0];
  86. plane[1] = mat[4];
  87. plane[2] = mat[8];
  88. plane[3] = mat[12];
  89. qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
  90. plane[0] = mat[1];
  91. plane[1] = mat[5];
  92. plane[2] = mat[9];
  93. plane[3] = mat[13];
  94. qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
  95. plane[0] = mat[3];
  96. plane[1] = mat[7];
  97. plane[2] = mat[11];
  98. plane[3] = mat[15];
  99. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
  100. }
  101. if ( pStage->texture.texgen == TG_SCREEN2 ) {
  102. qglEnable( GL_TEXTURE_GEN_S );
  103. qglEnable( GL_TEXTURE_GEN_T );
  104. qglEnable( GL_TEXTURE_GEN_Q );
  105. float mat[16], plane[4];
  106. myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
  107. plane[0] = mat[0];
  108. plane[1] = mat[4];
  109. plane[2] = mat[8];
  110. plane[3] = mat[12];
  111. qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
  112. plane[0] = mat[1];
  113. plane[1] = mat[5];
  114. plane[2] = mat[9];
  115. plane[3] = mat[13];
  116. qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
  117. plane[0] = mat[3];
  118. plane[1] = mat[7];
  119. plane[2] = mat[11];
  120. plane[3] = mat[15];
  121. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
  122. }
  123. if ( pStage->texture.texgen == TG_GLASSWARP ) {
  124. if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) {
  125. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_GLASSWARP );
  126. qglEnable( GL_FRAGMENT_PROGRAM_ARB );
  127. GL_SelectTexture( 2 );
  128. globalImages->scratchImage->Bind();
  129. GL_SelectTexture( 1 );
  130. globalImages->scratchImage2->Bind();
  131. qglEnable( GL_TEXTURE_GEN_S );
  132. qglEnable( GL_TEXTURE_GEN_T );
  133. qglEnable( GL_TEXTURE_GEN_Q );
  134. float mat[16], plane[4];
  135. myGlMultMatrix( surf->space->modelViewMatrix, backEnd.viewDef->projectionMatrix, mat );
  136. plane[0] = mat[0];
  137. plane[1] = mat[4];
  138. plane[2] = mat[8];
  139. plane[3] = mat[12];
  140. qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane );
  141. plane[0] = mat[1];
  142. plane[1] = mat[5];
  143. plane[2] = mat[9];
  144. plane[3] = mat[13];
  145. qglTexGenfv( GL_T, GL_OBJECT_PLANE, plane );
  146. plane[0] = mat[3];
  147. plane[1] = mat[7];
  148. plane[2] = mat[11];
  149. plane[3] = mat[15];
  150. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, plane );
  151. GL_SelectTexture( 0 );
  152. }
  153. }
  154. if ( pStage->texture.texgen == TG_REFLECT_CUBE ) {
  155. if ( tr.backEndRenderer == BE_ARB2 ) {
  156. // see if there is also a bump map specified
  157. const shaderStage_t *bumpStage = surf->material->GetBumpStage();
  158. if ( bumpStage ) {
  159. // per-pixel reflection mapping with bump mapping
  160. GL_SelectTexture( 1 );
  161. bumpStage->texture.image->Bind();
  162. GL_SelectTexture( 0 );
  163. qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  164. qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
  165. qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
  166. qglEnableVertexAttribArrayARB( 9 );
  167. qglEnableVertexAttribArrayARB( 10 );
  168. qglEnableClientState( GL_NORMAL_ARRAY );
  169. // Program env 5, 6, 7, 8 have been set in RB_SetProgramEnvironmentSpace
  170. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT );
  171. qglEnable( GL_FRAGMENT_PROGRAM_ARB );
  172. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT );
  173. qglEnable( GL_VERTEX_PROGRAM_ARB );
  174. } else {
  175. // per-pixel reflection mapping without a normal map
  176. qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  177. qglEnableClientState( GL_NORMAL_ARRAY );
  178. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT );
  179. qglEnable( GL_FRAGMENT_PROGRAM_ARB );
  180. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT );
  181. qglEnable( GL_VERTEX_PROGRAM_ARB );
  182. }
  183. } else {
  184. qglEnable( GL_TEXTURE_GEN_S );
  185. qglEnable( GL_TEXTURE_GEN_T );
  186. qglEnable( GL_TEXTURE_GEN_R );
  187. qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
  188. qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
  189. qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
  190. qglEnableClientState( GL_NORMAL_ARRAY );
  191. qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  192. qglMatrixMode( GL_TEXTURE );
  193. float mat[16];
  194. R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat );
  195. qglLoadMatrixf( mat );
  196. qglMatrixMode( GL_MODELVIEW );
  197. }
  198. }
  199. }
  200. /*
  201. ================
  202. RB_FinishStageTexturing
  203. ================
  204. */
  205. void RB_FinishStageTexturing( const shaderStage_t *pStage, const drawSurf_t *surf, idDrawVert *ac ) {
  206. // unset privatePolygonOffset if necessary
  207. if ( pStage->privatePolygonOffset && !surf->material->TestMaterialFlag(MF_POLYGONOFFSET) ) {
  208. qglDisable( GL_POLYGON_OFFSET_FILL );
  209. }
  210. if ( pStage->texture.texgen == TG_DIFFUSE_CUBE || pStage->texture.texgen == TG_SKYBOX_CUBE
  211. || pStage->texture.texgen == TG_WOBBLESKY_CUBE ) {
  212. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), (void *)&ac->st );
  213. }
  214. if ( pStage->texture.texgen == TG_SCREEN ) {
  215. qglDisable( GL_TEXTURE_GEN_S );
  216. qglDisable( GL_TEXTURE_GEN_T );
  217. qglDisable( GL_TEXTURE_GEN_Q );
  218. }
  219. if ( pStage->texture.texgen == TG_SCREEN2 ) {
  220. qglDisable( GL_TEXTURE_GEN_S );
  221. qglDisable( GL_TEXTURE_GEN_T );
  222. qglDisable( GL_TEXTURE_GEN_Q );
  223. }
  224. if ( pStage->texture.texgen == TG_GLASSWARP ) {
  225. if ( tr.backEndRenderer == BE_ARB2 /*|| tr.backEndRenderer == BE_NV30*/ ) {
  226. GL_SelectTexture( 2 );
  227. globalImages->BindNull();
  228. GL_SelectTexture( 1 );
  229. if ( pStage->texture.hasMatrix ) {
  230. RB_LoadShaderTextureMatrix( surf->shaderRegisters, &pStage->texture );
  231. }
  232. qglDisable( GL_TEXTURE_GEN_S );
  233. qglDisable( GL_TEXTURE_GEN_T );
  234. qglDisable( GL_TEXTURE_GEN_Q );
  235. qglDisable( GL_FRAGMENT_PROGRAM_ARB );
  236. globalImages->BindNull();
  237. GL_SelectTexture( 0 );
  238. }
  239. }
  240. if ( pStage->texture.texgen == TG_REFLECT_CUBE ) {
  241. if ( tr.backEndRenderer == BE_ARB2 ) {
  242. // see if there is also a bump map specified
  243. const shaderStage_t *bumpStage = surf->material->GetBumpStage();
  244. if ( bumpStage ) {
  245. // per-pixel reflection mapping with bump mapping
  246. GL_SelectTexture( 1 );
  247. globalImages->BindNull();
  248. GL_SelectTexture( 0 );
  249. qglDisableVertexAttribArrayARB( 9 );
  250. qglDisableVertexAttribArrayARB( 10 );
  251. } else {
  252. // per-pixel reflection mapping without bump mapping
  253. }
  254. qglDisableClientState( GL_NORMAL_ARRAY );
  255. qglDisable( GL_FRAGMENT_PROGRAM_ARB );
  256. qglDisable( GL_VERTEX_PROGRAM_ARB );
  257. // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed.
  258. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 );
  259. } else {
  260. qglDisable( GL_TEXTURE_GEN_S );
  261. qglDisable( GL_TEXTURE_GEN_T );
  262. qglDisable( GL_TEXTURE_GEN_R );
  263. qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
  264. qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
  265. qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
  266. qglDisableClientState( GL_NORMAL_ARRAY );
  267. qglMatrixMode( GL_TEXTURE );
  268. qglLoadIdentity();
  269. qglMatrixMode( GL_MODELVIEW );
  270. }
  271. }
  272. if ( pStage->texture.hasMatrix ) {
  273. qglMatrixMode( GL_TEXTURE );
  274. qglLoadIdentity();
  275. qglMatrixMode( GL_MODELVIEW );
  276. }
  277. }
  278. /*
  279. =============================================================================================
  280. FILL DEPTH BUFFER
  281. =============================================================================================
  282. */
  283. /*
  284. ==================
  285. RB_T_FillDepthBuffer
  286. ==================
  287. */
  288. void RB_T_FillDepthBuffer( const drawSurf_t *surf ) {
  289. int stage;
  290. const idMaterial *shader;
  291. const shaderStage_t *pStage;
  292. const float *regs;
  293. float color[4];
  294. const srfTriangles_t *tri;
  295. tri = surf->geo;
  296. shader = surf->material;
  297. // update the clip plane if needed
  298. if ( backEnd.viewDef->numClipPlanes && surf->space != backEnd.currentSpace ) {
  299. GL_SelectTexture( 1 );
  300. idPlane plane;
  301. R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.viewDef->clipPlanes[0], plane );
  302. plane[3] += 0.5; // the notch is in the middle
  303. qglTexGenfv( GL_S, GL_OBJECT_PLANE, plane.ToFloatPtr() );
  304. GL_SelectTexture( 0 );
  305. }
  306. if ( !shader->IsDrawn() ) {
  307. return;
  308. }
  309. // some deforms may disable themselves by setting numIndexes = 0
  310. if ( !tri->numIndexes ) {
  311. return;
  312. }
  313. // translucent surfaces don't put anything in the depth buffer and don't
  314. // test against it, which makes them fail the mirror clip plane operation
  315. if ( shader->Coverage() == MC_TRANSLUCENT ) {
  316. return;
  317. }
  318. if ( !tri->ambientCache ) {
  319. common->Printf( "RB_T_FillDepthBuffer: !tri->ambientCache\n" );
  320. return;
  321. }
  322. // get the expressions for conditionals / color / texcoords
  323. regs = surf->shaderRegisters;
  324. // if all stages of a material have been conditioned off, don't do anything
  325. for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {
  326. pStage = shader->GetStage(stage);
  327. // check the stage enable condition
  328. if ( regs[ pStage->conditionRegister ] != 0 ) {
  329. break;
  330. }
  331. }
  332. if ( stage == shader->GetNumStages() ) {
  333. return;
  334. }
  335. // set polygon offset if necessary
  336. if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
  337. qglEnable( GL_POLYGON_OFFSET_FILL );
  338. qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
  339. }
  340. // subviews will just down-modulate the color buffer by overbright
  341. if ( shader->GetSort() == SS_SUBVIEW ) {
  342. GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHFUNC_LESS );
  343. color[0] =
  344. color[1] =
  345. color[2] = ( 1.0 / backEnd.overBright );
  346. color[3] = 1;
  347. } else {
  348. // others just draw black
  349. color[0] = 0;
  350. color[1] = 0;
  351. color[2] = 0;
  352. color[3] = 1;
  353. }
  354. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  355. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  356. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast<void *>(&ac->st) );
  357. bool drawSolid = false;
  358. if ( shader->Coverage() == MC_OPAQUE ) {
  359. drawSolid = true;
  360. }
  361. // we may have multiple alpha tested stages
  362. if ( shader->Coverage() == MC_PERFORATED ) {
  363. // if the only alpha tested stages are condition register omitted,
  364. // draw a normal opaque surface
  365. bool didDraw = false;
  366. qglEnable( GL_ALPHA_TEST );
  367. // perforated surfaces may have multiple alpha tested stages
  368. for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {
  369. pStage = shader->GetStage(stage);
  370. if ( !pStage->hasAlphaTest ) {
  371. continue;
  372. }
  373. // check the stage enable condition
  374. if ( regs[ pStage->conditionRegister ] == 0 ) {
  375. continue;
  376. }
  377. // if we at least tried to draw an alpha tested stage,
  378. // we won't draw the opaque surface
  379. didDraw = true;
  380. // set the alpha modulate
  381. color[3] = regs[ pStage->color.registers[3] ];
  382. // skip the entire stage if alpha would be black
  383. if ( color[3] <= 0 ) {
  384. continue;
  385. }
  386. qglColor4fv( color );
  387. qglAlphaFunc( GL_GREATER, regs[ pStage->alphaTestRegister ] );
  388. // bind the texture
  389. pStage->texture.image->Bind();
  390. // set texture matrix and texGens
  391. RB_PrepareStageTexturing( pStage, surf, ac );
  392. // draw it
  393. RB_DrawElementsWithCounters( tri );
  394. RB_FinishStageTexturing( pStage, surf, ac );
  395. }
  396. qglDisable( GL_ALPHA_TEST );
  397. if ( !didDraw ) {
  398. drawSolid = true;
  399. }
  400. }
  401. // draw the entire surface solid
  402. if ( drawSolid ) {
  403. qglColor4fv( color );
  404. globalImages->whiteImage->Bind();
  405. // draw it
  406. RB_DrawElementsWithCounters( tri );
  407. }
  408. // reset polygon offset
  409. if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
  410. qglDisable( GL_POLYGON_OFFSET_FILL );
  411. }
  412. // reset blending
  413. if ( shader->GetSort() == SS_SUBVIEW ) {
  414. GL_State( GLS_DEPTHFUNC_LESS );
  415. }
  416. }
  417. /*
  418. =====================
  419. RB_STD_FillDepthBuffer
  420. If we are rendering a subview with a near clip plane, use a second texture
  421. to force the alpha test to fail when behind that clip plane
  422. =====================
  423. */
  424. void RB_STD_FillDepthBuffer( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  425. // if we are just doing 2D rendering, no need to fill the depth buffer
  426. if ( !backEnd.viewDef->viewEntitys ) {
  427. return;
  428. }
  429. RB_LogComment( "---------- RB_STD_FillDepthBuffer ----------\n" );
  430. // enable the second texture for mirror plane clipping if needed
  431. if ( backEnd.viewDef->numClipPlanes ) {
  432. GL_SelectTexture( 1 );
  433. globalImages->alphaNotchImage->Bind();
  434. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  435. qglEnable( GL_TEXTURE_GEN_S );
  436. qglTexCoord2f( 1, 0.5 );
  437. }
  438. // the first texture will be used for alpha tested surfaces
  439. GL_SelectTexture( 0 );
  440. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  441. // decal surfaces may enable polygon offset
  442. qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() );
  443. GL_State( GLS_DEPTHFUNC_LESS );
  444. // Enable stencil test if we are going to be using it for shadows.
  445. // If we didn't do this, it would be legal behavior to get z fighting
  446. // from the ambient pass and the light passes.
  447. qglEnable( GL_STENCIL_TEST );
  448. qglStencilFunc( GL_ALWAYS, 1, 255 );
  449. RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_T_FillDepthBuffer );
  450. if ( backEnd.viewDef->numClipPlanes ) {
  451. GL_SelectTexture( 1 );
  452. globalImages->BindNull();
  453. qglDisable( GL_TEXTURE_GEN_S );
  454. GL_SelectTexture( 0 );
  455. }
  456. }
  457. /*
  458. =============================================================================================
  459. SHADER PASSES
  460. =============================================================================================
  461. */
  462. /*
  463. ==================
  464. RB_SetProgramEnvironment
  465. Sets variables that can be used by all vertex programs
  466. ==================
  467. */
  468. void RB_SetProgramEnvironment( void ) {
  469. float parm[4];
  470. int pot;
  471. if ( !glConfig.ARBVertexProgramAvailable ) {
  472. return;
  473. }
  474. #if 0
  475. // screen power of two correction factor, one pixel in so we don't get a bilerp
  476. // of an uncopied pixel
  477. int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
  478. pot = globalImages->currentRenderImage->uploadWidth;
  479. if ( w == pot ) {
  480. parm[0] = 1.0;
  481. } else {
  482. parm[0] = (float)(w-1) / pot;
  483. }
  484. int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
  485. pot = globalImages->currentRenderImage->uploadHeight;
  486. if ( h == pot ) {
  487. parm[1] = 1.0;
  488. } else {
  489. parm[1] = (float)(h-1) / pot;
  490. }
  491. parm[2] = 0;
  492. parm[3] = 1;
  493. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm );
  494. #else
  495. // screen power of two correction factor, assuming the copy to _currentRender
  496. // also copied an extra row and column for the bilerp
  497. int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
  498. pot = globalImages->currentRenderImage->uploadWidth;
  499. parm[0] = (float)w / pot;
  500. int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
  501. pot = globalImages->currentRenderImage->uploadHeight;
  502. parm[1] = (float)h / pot;
  503. parm[2] = 0;
  504. parm[3] = 1;
  505. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 0, parm );
  506. #endif
  507. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  508. // window coord to 0.0 to 1.0 conversion
  509. parm[0] = 1.0 / w;
  510. parm[1] = 1.0 / h;
  511. parm[2] = 0;
  512. parm[3] = 1;
  513. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm );
  514. //
  515. // set eye position in global space
  516. //
  517. parm[0] = backEnd.viewDef->renderView.vieworg[0];
  518. parm[1] = backEnd.viewDef->renderView.vieworg[1];
  519. parm[2] = backEnd.viewDef->renderView.vieworg[2];
  520. parm[3] = 1.0;
  521. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 1, parm );
  522. }
  523. /*
  524. ==================
  525. RB_SetProgramEnvironmentSpace
  526. Sets variables related to the current space that can be used by all vertex programs
  527. ==================
  528. */
  529. void RB_SetProgramEnvironmentSpace( void ) {
  530. if ( !glConfig.ARBVertexProgramAvailable ) {
  531. return;
  532. }
  533. const struct viewEntity_s *space = backEnd.currentSpace;
  534. float parm[4];
  535. // set eye position in local space
  536. R_GlobalPointToLocal( space->modelMatrix, backEnd.viewDef->renderView.vieworg, *(idVec3 *)parm );
  537. parm[3] = 1.0;
  538. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 5, parm );
  539. // we need the model matrix without it being combined with the view matrix
  540. // so we can transform local vectors to global coordinates
  541. parm[0] = space->modelMatrix[0];
  542. parm[1] = space->modelMatrix[4];
  543. parm[2] = space->modelMatrix[8];
  544. parm[3] = space->modelMatrix[12];
  545. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 6, parm );
  546. parm[0] = space->modelMatrix[1];
  547. parm[1] = space->modelMatrix[5];
  548. parm[2] = space->modelMatrix[9];
  549. parm[3] = space->modelMatrix[13];
  550. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 7, parm );
  551. parm[0] = space->modelMatrix[2];
  552. parm[1] = space->modelMatrix[6];
  553. parm[2] = space->modelMatrix[10];
  554. parm[3] = space->modelMatrix[14];
  555. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 8, parm );
  556. }
  557. /*
  558. ==================
  559. RB_STD_T_RenderShaderPasses
  560. This is also called for the generated 2D rendering
  561. ==================
  562. */
  563. void RB_STD_T_RenderShaderPasses( const drawSurf_t *surf ) {
  564. int stage;
  565. const idMaterial *shader;
  566. const shaderStage_t *pStage;
  567. const float *regs;
  568. float color[4];
  569. const srfTriangles_t *tri;
  570. tri = surf->geo;
  571. shader = surf->material;
  572. if ( !shader->HasAmbient() ) {
  573. return;
  574. }
  575. if ( shader->IsPortalSky() ) {
  576. return;
  577. }
  578. // change the matrix if needed
  579. if ( surf->space != backEnd.currentSpace ) {
  580. qglLoadMatrixf( surf->space->modelViewMatrix );
  581. backEnd.currentSpace = surf->space;
  582. RB_SetProgramEnvironmentSpace();
  583. }
  584. // change the scissor if needed
  585. if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( surf->scissorRect ) ) {
  586. backEnd.currentScissor = surf->scissorRect;
  587. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  588. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  589. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  590. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  591. }
  592. // some deforms may disable themselves by setting numIndexes = 0
  593. if ( !tri->numIndexes ) {
  594. return;
  595. }
  596. if ( !tri->ambientCache ) {
  597. common->Printf( "RB_T_RenderShaderPasses: !tri->ambientCache\n" );
  598. return;
  599. }
  600. // get the expressions for conditionals / color / texcoords
  601. regs = surf->shaderRegisters;
  602. // set face culling appropriately
  603. GL_Cull( shader->GetCullType() );
  604. // set polygon offset if necessary
  605. if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
  606. qglEnable( GL_POLYGON_OFFSET_FILL );
  607. qglPolygonOffset( r_offsetFactor.GetFloat(), r_offsetUnits.GetFloat() * shader->GetPolygonOffset() );
  608. }
  609. if ( surf->space->weaponDepthHack ) {
  610. RB_EnterWeaponDepthHack();
  611. }
  612. if ( surf->space->modelDepthHack != 0.0f ) {
  613. RB_EnterModelDepthHack( surf->space->modelDepthHack );
  614. }
  615. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  616. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  617. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), reinterpret_cast<void *>(&ac->st) );
  618. for ( stage = 0; stage < shader->GetNumStages() ; stage++ ) {
  619. pStage = shader->GetStage(stage);
  620. // check the enable condition
  621. if ( regs[ pStage->conditionRegister ] == 0 ) {
  622. continue;
  623. }
  624. // skip the stages involved in lighting
  625. if ( pStage->lighting != SL_AMBIENT ) {
  626. continue;
  627. }
  628. // skip if the stage is ( GL_ZERO, GL_ONE ), which is used for some alpha masks
  629. if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE ) ) {
  630. continue;
  631. }
  632. // see if we are a new-style stage
  633. newShaderStage_t *newStage = pStage->newStage;
  634. if ( newStage ) {
  635. //--------------------------
  636. //
  637. // new style stages
  638. //
  639. //--------------------------
  640. // completely skip the stage if we don't have the capability
  641. if ( tr.backEndRenderer != BE_ARB2 ) {
  642. continue;
  643. }
  644. if ( r_skipNewAmbient.GetBool() ) {
  645. continue;
  646. }
  647. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
  648. qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
  649. qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
  650. qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  651. qglEnableClientState( GL_COLOR_ARRAY );
  652. qglEnableVertexAttribArrayARB( 9 );
  653. qglEnableVertexAttribArrayARB( 10 );
  654. qglEnableClientState( GL_NORMAL_ARRAY );
  655. GL_State( pStage->drawStateBits );
  656. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, newStage->vertexProgram );
  657. qglEnable( GL_VERTEX_PROGRAM_ARB );
  658. // megaTextures bind a lot of images and set a lot of parameters
  659. if ( newStage->megaTexture ) {
  660. newStage->megaTexture->SetMappingForSurface( tri );
  661. idVec3 localViewer;
  662. R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.viewDef->renderView.vieworg, localViewer );
  663. newStage->megaTexture->BindForViewOrigin( localViewer );
  664. }
  665. for ( int i = 0 ; i < newStage->numVertexParms ; i++ ) {
  666. float parm[4];
  667. parm[0] = regs[ newStage->vertexParms[i][0] ];
  668. parm[1] = regs[ newStage->vertexParms[i][1] ];
  669. parm[2] = regs[ newStage->vertexParms[i][2] ];
  670. parm[3] = regs[ newStage->vertexParms[i][3] ];
  671. qglProgramLocalParameter4fvARB( GL_VERTEX_PROGRAM_ARB, i, parm );
  672. }
  673. for ( int i = 0 ; i < newStage->numFragmentProgramImages ; i++ ) {
  674. if ( newStage->fragmentProgramImages[i] ) {
  675. GL_SelectTexture( i );
  676. newStage->fragmentProgramImages[i]->Bind();
  677. }
  678. }
  679. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, newStage->fragmentProgram );
  680. qglEnable( GL_FRAGMENT_PROGRAM_ARB );
  681. // draw it
  682. RB_DrawElementsWithCounters( tri );
  683. for ( int i = 1 ; i < newStage->numFragmentProgramImages ; i++ ) {
  684. if ( newStage->fragmentProgramImages[i] ) {
  685. GL_SelectTexture( i );
  686. globalImages->BindNull();
  687. }
  688. }
  689. if ( newStage->megaTexture ) {
  690. newStage->megaTexture->Unbind();
  691. }
  692. GL_SelectTexture( 0 );
  693. qglDisable( GL_VERTEX_PROGRAM_ARB );
  694. qglDisable( GL_FRAGMENT_PROGRAM_ARB );
  695. // Fixme: Hack to get around an apparent bug in ATI drivers. Should remove as soon as it gets fixed.
  696. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, 0 );
  697. qglDisableClientState( GL_COLOR_ARRAY );
  698. qglDisableVertexAttribArrayARB( 9 );
  699. qglDisableVertexAttribArrayARB( 10 );
  700. qglDisableClientState( GL_NORMAL_ARRAY );
  701. continue;
  702. }
  703. //--------------------------
  704. //
  705. // old style stages
  706. //
  707. //--------------------------
  708. // set the color
  709. color[0] = regs[ pStage->color.registers[0] ];
  710. color[1] = regs[ pStage->color.registers[1] ];
  711. color[2] = regs[ pStage->color.registers[2] ];
  712. color[3] = regs[ pStage->color.registers[3] ];
  713. // skip the entire stage if an add would be black
  714. if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE )
  715. && color[0] <= 0 && color[1] <= 0 && color[2] <= 0 ) {
  716. continue;
  717. }
  718. // skip the entire stage if a blend would be completely transparent
  719. if ( ( pStage->drawStateBits & (GLS_SRCBLEND_BITS|GLS_DSTBLEND_BITS) ) == ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA )
  720. && color[3] <= 0 ) {
  721. continue;
  722. }
  723. // select the vertex color source
  724. if ( pStage->vertexColor == SVC_IGNORE ) {
  725. qglColor4fv( color );
  726. } else {
  727. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), (void *)&ac->color );
  728. qglEnableClientState( GL_COLOR_ARRAY );
  729. if ( pStage->vertexColor == SVC_INVERSE_MODULATE ) {
  730. GL_TexEnv( GL_COMBINE_ARB );
  731. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
  732. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
  733. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB );
  734. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  735. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR );
  736. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  737. }
  738. // for vertex color and modulated color, we need to enable a second
  739. // texture stage
  740. if ( color[0] != 1 || color[1] != 1 || color[2] != 1 || color[3] != 1 ) {
  741. GL_SelectTexture( 1 );
  742. globalImages->whiteImage->Bind();
  743. GL_TexEnv( GL_COMBINE_ARB );
  744. qglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
  745. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
  746. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
  747. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB );
  748. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
  749. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
  750. qglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1 );
  751. qglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
  752. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB );
  753. qglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT_ARB );
  754. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA );
  755. qglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
  756. qglTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1 );
  757. GL_SelectTexture( 0 );
  758. }
  759. }
  760. // bind the texture
  761. RB_BindVariableStageImage( &pStage->texture, regs );
  762. // set the state
  763. GL_State( pStage->drawStateBits );
  764. RB_PrepareStageTexturing( pStage, surf, ac );
  765. // draw it
  766. RB_DrawElementsWithCounters( tri );
  767. RB_FinishStageTexturing( pStage, surf, ac );
  768. if ( pStage->vertexColor != SVC_IGNORE ) {
  769. qglDisableClientState( GL_COLOR_ARRAY );
  770. GL_SelectTexture( 1 );
  771. GL_TexEnv( GL_MODULATE );
  772. globalImages->BindNull();
  773. GL_SelectTexture( 0 );
  774. GL_TexEnv( GL_MODULATE );
  775. }
  776. }
  777. // reset polygon offset
  778. if ( shader->TestMaterialFlag(MF_POLYGONOFFSET) ) {
  779. qglDisable( GL_POLYGON_OFFSET_FILL );
  780. }
  781. if ( surf->space->weaponDepthHack || surf->space->modelDepthHack != 0.0f ) {
  782. RB_LeaveDepthHack();
  783. }
  784. }
  785. /*
  786. =====================
  787. RB_STD_DrawShaderPasses
  788. Draw non-light dependent passes
  789. =====================
  790. */
  791. int RB_STD_DrawShaderPasses( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  792. int i;
  793. // only obey skipAmbient if we are rendering a view
  794. if ( backEnd.viewDef->viewEntitys && r_skipAmbient.GetBool() ) {
  795. return numDrawSurfs;
  796. }
  797. RB_LogComment( "---------- RB_STD_DrawShaderPasses ----------\n" );
  798. // if we are about to draw the first surface that needs
  799. // the rendering in a texture, copy it over
  800. if ( drawSurfs[0]->material->GetSort() >= SS_POST_PROCESS ) {
  801. if ( r_skipPostProcess.GetBool() ) {
  802. return 0;
  803. }
  804. // only dump if in a 3d view
  805. if ( backEnd.viewDef->viewEntitys && tr.backEndRenderer == BE_ARB2 ) {
  806. globalImages->currentRenderImage->CopyFramebuffer( backEnd.viewDef->viewport.x1,
  807. backEnd.viewDef->viewport.y1, backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1,
  808. backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1, true );
  809. }
  810. backEnd.currentRenderCopied = true;
  811. }
  812. GL_SelectTexture( 1 );
  813. globalImages->BindNull();
  814. GL_SelectTexture( 0 );
  815. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  816. RB_SetProgramEnvironment();
  817. // we don't use RB_RenderDrawSurfListWithFunction()
  818. // because we want to defer the matrix load because many
  819. // surfaces won't draw any ambient passes
  820. backEnd.currentSpace = NULL;
  821. for (i = 0 ; i < numDrawSurfs ; i++ ) {
  822. if ( drawSurfs[i]->material->SuppressInSubview() ) {
  823. continue;
  824. }
  825. if ( backEnd.viewDef->isXraySubview && drawSurfs[i]->space->entityDef ) {
  826. if ( drawSurfs[i]->space->entityDef->parms.xrayIndex != 2 ) {
  827. continue;
  828. }
  829. }
  830. // we need to draw the post process shaders after we have drawn the fog lights
  831. if ( drawSurfs[i]->material->GetSort() >= SS_POST_PROCESS
  832. && !backEnd.currentRenderCopied ) {
  833. break;
  834. }
  835. RB_STD_T_RenderShaderPasses( drawSurfs[i] );
  836. }
  837. GL_Cull( CT_FRONT_SIDED );
  838. qglColor3f( 1, 1, 1 );
  839. return i;
  840. }
  841. /*
  842. ==============================================================================
  843. BACK END RENDERING OF STENCIL SHADOWS
  844. ==============================================================================
  845. */
  846. /*
  847. =====================
  848. RB_T_Shadow
  849. the shadow volumes face INSIDE
  850. =====================
  851. */
  852. static void RB_T_Shadow( const drawSurf_t *surf ) {
  853. const srfTriangles_t *tri;
  854. // set the light position if we are using a vertex program to project the rear surfaces
  855. if ( tr.backEndRendererHasVertexPrograms && r_useShadowVertexProgram.GetBool()
  856. && surf->space != backEnd.currentSpace ) {
  857. idVec4 localLight;
  858. R_GlobalPointToLocal( surf->space->modelMatrix, backEnd.vLight->globalLightOrigin, localLight.ToVec3() );
  859. localLight.w = 0.0f;
  860. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, localLight.ToFloatPtr() );
  861. }
  862. tri = surf->geo;
  863. if ( !tri->shadowCache ) {
  864. return;
  865. }
  866. qglVertexPointer( 4, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position(tri->shadowCache) );
  867. // we always draw the sil planes, but we may not need to draw the front or rear caps
  868. int numIndexes;
  869. bool external = false;
  870. if ( !r_useExternalShadows.GetInteger() ) {
  871. numIndexes = tri->numIndexes;
  872. } else if ( r_useExternalShadows.GetInteger() == 2 ) { // force to no caps for testing
  873. numIndexes = tri->numShadowIndexesNoCaps;
  874. } else if ( !(surf->dsFlags & DSF_VIEW_INSIDE_SHADOW) ) {
  875. // if we aren't inside the shadow projection, no caps are ever needed needed
  876. numIndexes = tri->numShadowIndexesNoCaps;
  877. external = true;
  878. } else if ( !backEnd.vLight->viewInsideLight && !(surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE) ) {
  879. // if we are inside the shadow projection, but outside the light, and drawing
  880. // a non-infinite shadow, we can skip some caps
  881. if ( backEnd.vLight->viewSeesShadowPlaneBits & surf->geo->shadowCapPlaneBits ) {
  882. // we can see through a rear cap, so we need to draw it, but we can skip the
  883. // caps on the actual surface
  884. numIndexes = tri->numShadowIndexesNoFrontCaps;
  885. } else {
  886. // we don't need to draw any caps
  887. numIndexes = tri->numShadowIndexesNoCaps;
  888. }
  889. external = true;
  890. } else {
  891. // must draw everything
  892. numIndexes = tri->numIndexes;
  893. }
  894. // set depth bounds
  895. if( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
  896. qglDepthBoundsEXT( surf->scissorRect.zmin, surf->scissorRect.zmax );
  897. }
  898. // debug visualization
  899. if ( r_showShadows.GetInteger() ) {
  900. if ( r_showShadows.GetInteger() == 3 ) {
  901. if ( external ) {
  902. qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
  903. } else {
  904. // these are the surfaces that require the reverse
  905. qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright );
  906. }
  907. } else {
  908. // draw different color for turboshadows
  909. if ( surf->geo->shadowCapPlaneBits & SHADOW_CAP_INFINITE ) {
  910. if ( numIndexes == tri->numIndexes ) {
  911. qglColor3f( 1/backEnd.overBright, 0.1/backEnd.overBright, 0.1/backEnd.overBright );
  912. } else {
  913. qglColor3f( 1/backEnd.overBright, 0.4/backEnd.overBright, 0.1/backEnd.overBright );
  914. }
  915. } else {
  916. if ( numIndexes == tri->numIndexes ) {
  917. qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
  918. } else if ( numIndexes == tri->numShadowIndexesNoFrontCaps ) {
  919. qglColor3f( 0.1/backEnd.overBright, 1/backEnd.overBright, 0.6/backEnd.overBright );
  920. } else {
  921. qglColor3f( 0.6/backEnd.overBright, 1/backEnd.overBright, 0.1/backEnd.overBright );
  922. }
  923. }
  924. }
  925. qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  926. qglDisable( GL_STENCIL_TEST );
  927. GL_Cull( CT_TWO_SIDED );
  928. RB_DrawShadowElementsWithCounters( tri, numIndexes );
  929. GL_Cull( CT_FRONT_SIDED );
  930. qglEnable( GL_STENCIL_TEST );
  931. return;
  932. }
  933. // patent-free work around
  934. if ( !external ) {
  935. // "preload" the stencil buffer with the number of volumes
  936. // that get clipped by the near or far clip plane
  937. qglStencilOp( GL_KEEP, tr.stencilDecr, tr.stencilDecr );
  938. GL_Cull( CT_FRONT_SIDED );
  939. RB_DrawShadowElementsWithCounters( tri, numIndexes );
  940. qglStencilOp( GL_KEEP, tr.stencilIncr, tr.stencilIncr );
  941. GL_Cull( CT_BACK_SIDED );
  942. RB_DrawShadowElementsWithCounters( tri, numIndexes );
  943. }
  944. // traditional depth-pass stencil shadows
  945. qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilIncr );
  946. GL_Cull( CT_FRONT_SIDED );
  947. RB_DrawShadowElementsWithCounters( tri, numIndexes );
  948. qglStencilOp( GL_KEEP, GL_KEEP, tr.stencilDecr );
  949. GL_Cull( CT_BACK_SIDED );
  950. RB_DrawShadowElementsWithCounters( tri, numIndexes );
  951. }
  952. /*
  953. =====================
  954. RB_StencilShadowPass
  955. Stencil test should already be enabled, and the stencil buffer should have
  956. been set to 128 on any surfaces that might receive shadows
  957. =====================
  958. */
  959. void RB_StencilShadowPass( const drawSurf_t *drawSurfs ) {
  960. if ( !r_shadows.GetBool() ) {
  961. return;
  962. }
  963. if ( !drawSurfs ) {
  964. return;
  965. }
  966. RB_LogComment( "---------- RB_StencilShadowPass ----------\n" );
  967. globalImages->BindNull();
  968. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  969. // for visualizing the shadows
  970. if ( r_showShadows.GetInteger() ) {
  971. if ( r_showShadows.GetInteger() == 2 ) {
  972. // draw filled in
  973. GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_LESS );
  974. } else {
  975. // draw as lines, filling the depth buffer
  976. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO | GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS );
  977. }
  978. } else {
  979. // don't write to the color buffer, just the stencil buffer
  980. GL_State( GLS_DEPTHMASK | GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHFUNC_LESS );
  981. }
  982. if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) {
  983. qglPolygonOffset( r_shadowPolygonFactor.GetFloat(), -r_shadowPolygonOffset.GetFloat() );
  984. qglEnable( GL_POLYGON_OFFSET_FILL );
  985. }
  986. qglStencilFunc( GL_ALWAYS, 1, 255 );
  987. if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
  988. qglEnable( GL_DEPTH_BOUNDS_TEST_EXT );
  989. }
  990. RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_Shadow );
  991. GL_Cull( CT_FRONT_SIDED );
  992. if ( r_shadowPolygonFactor.GetFloat() || r_shadowPolygonOffset.GetFloat() ) {
  993. qglDisable( GL_POLYGON_OFFSET_FILL );
  994. }
  995. if ( glConfig.depthBoundsTestAvailable && r_useDepthBoundsTest.GetBool() ) {
  996. qglDisable( GL_DEPTH_BOUNDS_TEST_EXT );
  997. }
  998. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  999. qglStencilFunc( GL_GEQUAL, 128, 255 );
  1000. qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  1001. }
  1002. /*
  1003. =============================================================================================
  1004. BLEND LIGHT PROJECTION
  1005. =============================================================================================
  1006. */
  1007. /*
  1008. =====================
  1009. RB_T_BlendLight
  1010. =====================
  1011. */
  1012. static void RB_T_BlendLight( const drawSurf_t *surf ) {
  1013. const srfTriangles_t *tri;
  1014. tri = surf->geo;
  1015. if ( backEnd.currentSpace != surf->space ) {
  1016. idPlane lightProject[4];
  1017. int i;
  1018. for ( i = 0 ; i < 4 ; i++ ) {
  1019. R_GlobalPlaneToLocal( surf->space->modelMatrix, backEnd.vLight->lightProject[i], lightProject[i] );
  1020. }
  1021. GL_SelectTexture( 0 );
  1022. qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[0].ToFloatPtr() );
  1023. qglTexGenfv( GL_T, GL_OBJECT_PLANE, lightProject[1].ToFloatPtr() );
  1024. qglTexGenfv( GL_Q, GL_OBJECT_PLANE, lightProject[2].ToFloatPtr() );
  1025. GL_SelectTexture( 1 );
  1026. qglTexGenfv( GL_S, GL_OBJECT_PLANE, lightProject[3].ToFloatPtr() );
  1027. }
  1028. // this gets used for both blend lights and shadow draws
  1029. if ( tri->ambientCache ) {
  1030. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  1031. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  1032. } else if ( tri->shadowCache ) {
  1033. shadowCache_t *sc = (shadowCache_t *)vertexCache.Position( tri->shadowCache );
  1034. qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), sc->xyz.ToFloatPtr() );
  1035. }
  1036. RB_DrawElementsWithCounters( tri );
  1037. }
  1038. /*
  1039. =====================
  1040. RB_BlendLight
  1041. Dual texture together the falloff and projection texture with a blend
  1042. mode to the framebuffer, instead of interacting with the surface texture
  1043. =====================
  1044. */
  1045. static void RB_BlendLight( const drawSurf_t *drawSurfs, const drawSurf_t *drawSurfs2 ) {
  1046. const idMaterial *lightShader;
  1047. const shaderStage_t *stage;
  1048. int i;
  1049. const float *regs;
  1050. if ( !drawSurfs ) {
  1051. return;
  1052. }
  1053. if ( r_skipBlendLights.GetBool() ) {
  1054. return;
  1055. }
  1056. RB_LogComment( "---------- RB_BlendLight ----------\n" );
  1057. lightShader = backEnd.vLight->lightShader;
  1058. regs = backEnd.vLight->shaderRegisters;
  1059. // texture 1 will get the falloff texture
  1060. GL_SelectTexture( 1 );
  1061. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1062. qglEnable( GL_TEXTURE_GEN_S );
  1063. qglTexCoord2f( 0, 0.5 );
  1064. backEnd.vLight->falloffImage->Bind();
  1065. // texture 0 will get the projected texture
  1066. GL_SelectTexture( 0 );
  1067. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1068. qglEnable( GL_TEXTURE_GEN_S );
  1069. qglEnable( GL_TEXTURE_GEN_T );
  1070. qglEnable( GL_TEXTURE_GEN_Q );
  1071. for ( i = 0 ; i < lightShader->GetNumStages() ; i++ ) {
  1072. stage = lightShader->GetStage(i);
  1073. if ( !regs[ stage->conditionRegister ] ) {
  1074. continue;
  1075. }
  1076. GL_State( GLS_DEPTHMASK | stage->drawStateBits | GLS_DEPTHFUNC_EQUAL );
  1077. GL_SelectTexture( 0 );
  1078. stage->texture.image->Bind();
  1079. if ( stage->texture.hasMatrix ) {
  1080. RB_LoadShaderTextureMatrix( regs, &stage->texture );
  1081. }
  1082. // get the modulate values from the light, including alpha, unlike normal lights
  1083. backEnd.lightColor[0] = regs[ stage->color.registers[0] ];
  1084. backEnd.lightColor[1] = regs[ stage->color.registers[1] ];
  1085. backEnd.lightColor[2] = regs[ stage->color.registers[2] ];
  1086. backEnd.lightColor[3] = regs[ stage->color.registers[3] ];
  1087. qglColor4fv( backEnd.lightColor );
  1088. RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BlendLight );
  1089. RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BlendLight );
  1090. if ( stage->texture.hasMatrix ) {
  1091. GL_SelectTexture( 0 );
  1092. qglMatrixMode( GL_TEXTURE );
  1093. qglLoadIdentity();
  1094. qglMatrixMode( GL_MODELVIEW );
  1095. }
  1096. }
  1097. GL_SelectTexture( 1 );
  1098. qglDisable( GL_TEXTURE_GEN_S );
  1099. globalImages->BindNull();
  1100. GL_SelectTexture( 0 );
  1101. qglDisable( GL_TEXTURE_GEN_S );
  1102. qglDisable( GL_TEXTURE_GEN_T );
  1103. qglDisable( GL_TEXTURE_GEN_Q );
  1104. }
  1105. //========================================================================
  1106. static idPlane fogPlanes[4];
  1107. /*
  1108. =====================
  1109. RB_T_BasicFog
  1110. =====================
  1111. */
  1112. static void RB_T_BasicFog( const drawSurf_t *surf ) {
  1113. if ( backEnd.currentSpace != surf->space ) {
  1114. idPlane local;
  1115. GL_SelectTexture( 0 );
  1116. R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[0], local );
  1117. local[3] += 0.5;
  1118. qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() );
  1119. // R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[1], local );
  1120. // local[3] += 0.5;
  1121. local[0] = local[1] = local[2] = 0; local[3] = 0.5;
  1122. qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() );
  1123. GL_SelectTexture( 1 );
  1124. // GL_S is constant per viewer
  1125. R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[2], local );
  1126. local[3] += FOG_ENTER;
  1127. qglTexGenfv( GL_T, GL_OBJECT_PLANE, local.ToFloatPtr() );
  1128. R_GlobalPlaneToLocal( surf->space->modelMatrix, fogPlanes[3], local );
  1129. qglTexGenfv( GL_S, GL_OBJECT_PLANE, local.ToFloatPtr() );
  1130. }
  1131. RB_T_RenderTriangleSurface( surf );
  1132. }
  1133. /*
  1134. ==================
  1135. RB_FogPass
  1136. ==================
  1137. */
  1138. static void RB_FogPass( const drawSurf_t *drawSurfs, const drawSurf_t *drawSurfs2 ) {
  1139. const srfTriangles_t*frustumTris;
  1140. drawSurf_t ds;
  1141. const idMaterial *lightShader;
  1142. const shaderStage_t *stage;
  1143. const float *regs;
  1144. RB_LogComment( "---------- RB_FogPass ----------\n" );
  1145. // create a surface for the light frustom triangles, which are oriented drawn side out
  1146. frustumTris = backEnd.vLight->frustumTris;
  1147. // if we ran out of vertex cache memory, skip it
  1148. if ( !frustumTris->ambientCache ) {
  1149. return;
  1150. }
  1151. memset( &ds, 0, sizeof( ds ) );
  1152. ds.space = &backEnd.viewDef->worldSpace;
  1153. ds.geo = frustumTris;
  1154. ds.scissorRect = backEnd.viewDef->scissor;
  1155. // find the current color and density of the fog
  1156. lightShader = backEnd.vLight->lightShader;
  1157. regs = backEnd.vLight->shaderRegisters;
  1158. // assume fog shaders have only a single stage
  1159. stage = lightShader->GetStage(0);
  1160. backEnd.lightColor[0] = regs[ stage->color.registers[0] ];
  1161. backEnd.lightColor[1] = regs[ stage->color.registers[1] ];
  1162. backEnd.lightColor[2] = regs[ stage->color.registers[2] ];
  1163. backEnd.lightColor[3] = regs[ stage->color.registers[3] ];
  1164. qglColor3fv( backEnd.lightColor );
  1165. // calculate the falloff planes
  1166. float a;
  1167. // if they left the default value on, set a fog distance of 500
  1168. if ( backEnd.lightColor[3] <= 1.0 ) {
  1169. a = -0.5f / DEFAULT_FOG_DISTANCE;
  1170. } else {
  1171. // otherwise, distance = alpha color
  1172. a = -0.5f / backEnd.lightColor[3];
  1173. }
  1174. GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
  1175. // texture 0 is the falloff image
  1176. GL_SelectTexture( 0 );
  1177. globalImages->fogImage->Bind();
  1178. //GL_Bind( tr.whiteImage );
  1179. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1180. qglEnable( GL_TEXTURE_GEN_S );
  1181. qglEnable( GL_TEXTURE_GEN_T );
  1182. qglTexCoord2f( 0.5f, 0.5f ); // make sure Q is set
  1183. fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[2];
  1184. fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[6];
  1185. fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[10];
  1186. fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[14];
  1187. fogPlanes[1][0] = a * backEnd.viewDef->worldSpace.modelViewMatrix[0];
  1188. fogPlanes[1][1] = a * backEnd.viewDef->worldSpace.modelViewMatrix[4];
  1189. fogPlanes[1][2] = a * backEnd.viewDef->worldSpace.modelViewMatrix[8];
  1190. fogPlanes[1][3] = a * backEnd.viewDef->worldSpace.modelViewMatrix[12];
  1191. // texture 1 is the entering plane fade correction
  1192. GL_SelectTexture( 1 );
  1193. globalImages->fogEnterImage->Bind();
  1194. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1195. qglEnable( GL_TEXTURE_GEN_S );
  1196. qglEnable( GL_TEXTURE_GEN_T );
  1197. // T will get a texgen for the fade plane, which is always the "top" plane on unrotated lights
  1198. fogPlanes[2][0] = 0.001f * backEnd.vLight->fogPlane[0];
  1199. fogPlanes[2][1] = 0.001f * backEnd.vLight->fogPlane[1];
  1200. fogPlanes[2][2] = 0.001f * backEnd.vLight->fogPlane[2];
  1201. fogPlanes[2][3] = 0.001f * backEnd.vLight->fogPlane[3];
  1202. // S is based on the view origin
  1203. float s = backEnd.viewDef->renderView.vieworg * fogPlanes[2].Normal() + fogPlanes[2][3];
  1204. fogPlanes[3][0] = 0;
  1205. fogPlanes[3][1] = 0;
  1206. fogPlanes[3][2] = 0;
  1207. fogPlanes[3][3] = FOG_ENTER + s;
  1208. qglTexCoord2f( FOG_ENTER + s, FOG_ENTER );
  1209. // draw it
  1210. RB_RenderDrawSurfChainWithFunction( drawSurfs, RB_T_BasicFog );
  1211. RB_RenderDrawSurfChainWithFunction( drawSurfs2, RB_T_BasicFog );
  1212. // the light frustum bounding planes aren't in the depth buffer, so use depthfunc_less instead
  1213. // of depthfunc_equal
  1214. GL_State( GLS_DEPTHMASK | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_LESS );
  1215. GL_Cull( CT_BACK_SIDED );
  1216. RB_RenderDrawSurfChainWithFunction( &ds, RB_T_BasicFog );
  1217. GL_Cull( CT_FRONT_SIDED );
  1218. GL_SelectTexture( 1 );
  1219. qglDisable( GL_TEXTURE_GEN_S );
  1220. qglDisable( GL_TEXTURE_GEN_T );
  1221. globalImages->BindNull();
  1222. GL_SelectTexture( 0 );
  1223. qglDisable( GL_TEXTURE_GEN_S );
  1224. qglDisable( GL_TEXTURE_GEN_T );
  1225. }
  1226. /*
  1227. ==================
  1228. RB_STD_FogAllLights
  1229. ==================
  1230. */
  1231. void RB_STD_FogAllLights( void ) {
  1232. viewLight_t *vLight;
  1233. if ( r_skipFogLights.GetBool() || r_showOverDraw.GetInteger() != 0
  1234. || backEnd.viewDef->isXraySubview /* dont fog in xray mode*/
  1235. ) {
  1236. return;
  1237. }
  1238. RB_LogComment( "---------- RB_STD_FogAllLights ----------\n" );
  1239. qglDisable( GL_STENCIL_TEST );
  1240. for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  1241. backEnd.vLight = vLight;
  1242. if ( !vLight->lightShader->IsFogLight() && !vLight->lightShader->IsBlendLight() ) {
  1243. continue;
  1244. }
  1245. #if 0 // _D3XP disabled that
  1246. if ( r_ignore.GetInteger() ) {
  1247. // we use the stencil buffer to guarantee that no pixels will be
  1248. // double fogged, which happens in some areas that are thousands of
  1249. // units from the origin
  1250. backEnd.currentScissor = vLight->scissorRect;
  1251. if ( r_useScissor.GetBool() ) {
  1252. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  1253. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  1254. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  1255. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  1256. }
  1257. qglClear( GL_STENCIL_BUFFER_BIT );
  1258. qglEnable( GL_STENCIL_TEST );
  1259. // only pass on the cleared stencil values
  1260. qglStencilFunc( GL_EQUAL, 128, 255 );
  1261. // when we pass the stencil test and depth test and are going to draw,
  1262. // increment the stencil buffer so we don't ever draw on that pixel again
  1263. qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
  1264. }
  1265. #endif
  1266. if ( vLight->lightShader->IsFogLight() ) {
  1267. RB_FogPass( vLight->globalInteractions, vLight->localInteractions );
  1268. } else if ( vLight->lightShader->IsBlendLight() ) {
  1269. RB_BlendLight( vLight->globalInteractions, vLight->localInteractions );
  1270. }
  1271. qglDisable( GL_STENCIL_TEST );
  1272. }
  1273. qglEnable( GL_STENCIL_TEST );
  1274. }
  1275. //=========================================================================================
  1276. /*
  1277. ==================
  1278. RB_STD_LightScale
  1279. Perform extra blending passes to multiply the entire buffer by
  1280. a floating point value
  1281. ==================
  1282. */
  1283. void RB_STD_LightScale( void ) {
  1284. float v, f;
  1285. if ( backEnd.overBright == 1.0f ) {
  1286. return;
  1287. }
  1288. if ( r_skipLightScale.GetBool() ) {
  1289. return;
  1290. }
  1291. RB_LogComment( "---------- RB_STD_LightScale ----------\n" );
  1292. // the scissor may be smaller than the viewport for subviews
  1293. if ( r_useScissor.GetBool() ) {
  1294. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1,
  1295. backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1,
  1296. backEnd.viewDef->scissor.x2 - backEnd.viewDef->scissor.x1 + 1,
  1297. backEnd.viewDef->scissor.y2 - backEnd.viewDef->scissor.y1 + 1 );
  1298. backEnd.currentScissor = backEnd.viewDef->scissor;
  1299. }
  1300. // full screen blends
  1301. qglLoadIdentity();
  1302. qglMatrixMode( GL_PROJECTION );
  1303. qglPushMatrix();
  1304. qglLoadIdentity();
  1305. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1306. GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_SRC_COLOR );
  1307. GL_Cull( CT_TWO_SIDED ); // so mirror views also get it
  1308. globalImages->BindNull();
  1309. qglDisable( GL_DEPTH_TEST );
  1310. qglDisable( GL_STENCIL_TEST );
  1311. v = 1;
  1312. while ( idMath::Fabs( v - backEnd.overBright ) > 0.01 ) { // a little extra slop
  1313. f = backEnd.overBright / v;
  1314. f /= 2;
  1315. if ( f > 1 ) {
  1316. f = 1;
  1317. }
  1318. qglColor3f( f, f, f );
  1319. v = v * f * 2;
  1320. qglBegin( GL_QUADS );
  1321. qglVertex2f( 0,0 );
  1322. qglVertex2f( 0,1 );
  1323. qglVertex2f( 1,1 );
  1324. qglVertex2f( 1,0 );
  1325. qglEnd();
  1326. }
  1327. qglPopMatrix();
  1328. qglEnable( GL_DEPTH_TEST );
  1329. qglMatrixMode( GL_MODELVIEW );
  1330. GL_Cull( CT_FRONT_SIDED );
  1331. }
  1332. //=========================================================================================
  1333. /*
  1334. =============
  1335. RB_STD_DrawView
  1336. =============
  1337. */
  1338. void RB_STD_DrawView( void ) {
  1339. drawSurf_t **drawSurfs;
  1340. int numDrawSurfs;
  1341. RB_LogComment( "---------- RB_STD_DrawView ----------\n" );
  1342. backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
  1343. drawSurfs = (drawSurf_t **)&backEnd.viewDef->drawSurfs[0];
  1344. numDrawSurfs = backEnd.viewDef->numDrawSurfs;
  1345. // clear the z buffer, set the projection matrix, etc
  1346. RB_BeginDrawingView();
  1347. // decide how much overbrighting we are going to do
  1348. RB_DetermineLightScale();
  1349. // fill the depth buffer and clear color buffer to black except on
  1350. // subviews
  1351. RB_STD_FillDepthBuffer( drawSurfs, numDrawSurfs );
  1352. // main light renderer
  1353. switch( tr.backEndRenderer ) {
  1354. case BE_ARB:
  1355. RB_ARB_DrawInteractions();
  1356. break;
  1357. case BE_ARB2:
  1358. RB_ARB2_DrawInteractions();
  1359. break;
  1360. case BE_NV20:
  1361. RB_NV20_DrawInteractions();
  1362. break;
  1363. case BE_NV10:
  1364. RB_NV10_DrawInteractions();
  1365. break;
  1366. case BE_R200:
  1367. RB_R200_DrawInteractions();
  1368. break;
  1369. }
  1370. // disable stencil shadow test
  1371. qglStencilFunc( GL_ALWAYS, 128, 255 );
  1372. // uplight the entire screen to crutch up not having better blending range
  1373. RB_STD_LightScale();
  1374. // now draw any non-light dependent shading passes
  1375. int processed = RB_STD_DrawShaderPasses( drawSurfs, numDrawSurfs );
  1376. // fob and blend lights
  1377. RB_STD_FogAllLights();
  1378. // now draw any post-processing effects using _currentRender
  1379. if ( processed < numDrawSurfs ) {
  1380. RB_STD_DrawShaderPasses( drawSurfs+processed, numDrawSurfs-processed );
  1381. }
  1382. RB_RenderDebugTools( drawSurfs, numDrawSurfs );
  1383. }