tr_rendertools.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386
  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. #include "simplex.h" // line font definition
  24. #define MAX_DEBUG_LINES 16384
  25. typedef struct debugLine_s {
  26. idVec4 rgb;
  27. idVec3 start;
  28. idVec3 end;
  29. bool depthTest;
  30. int lifeTime;
  31. } debugLine_t;
  32. debugLine_t rb_debugLines[ MAX_DEBUG_LINES ];
  33. int rb_numDebugLines = 0;
  34. int rb_debugLineTime = 0;
  35. #define MAX_DEBUG_TEXT 512
  36. typedef struct debugText_s {
  37. idStr text;
  38. idVec3 origin;
  39. float scale;
  40. idVec4 color;
  41. idMat3 viewAxis;
  42. int align;
  43. int lifeTime;
  44. bool depthTest;
  45. } debugText_t;
  46. debugText_t rb_debugText[ MAX_DEBUG_TEXT ];
  47. int rb_numDebugText = 0;
  48. int rb_debugTextTime = 0;
  49. #define MAX_DEBUG_POLYGONS 8192
  50. typedef struct debugPolygon_s {
  51. idVec4 rgb;
  52. idWinding winding;
  53. bool depthTest;
  54. int lifeTime;
  55. } debugPolygon_t;
  56. debugPolygon_t rb_debugPolygons[ MAX_DEBUG_POLYGONS ];
  57. int rb_numDebugPolygons = 0;
  58. int rb_debugPolygonTime = 0;
  59. static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align );
  60. /*
  61. ================
  62. RB_DrawBounds
  63. ================
  64. */
  65. void RB_DrawBounds( const idBounds &bounds ) {
  66. if ( bounds.IsCleared() ) {
  67. return;
  68. }
  69. qglBegin( GL_LINE_LOOP );
  70. qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] );
  71. qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] );
  72. qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] );
  73. qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] );
  74. qglEnd();
  75. qglBegin( GL_LINE_LOOP );
  76. qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] );
  77. qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] );
  78. qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] );
  79. qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] );
  80. qglEnd();
  81. qglBegin( GL_LINES );
  82. qglVertex3f( bounds[0][0], bounds[0][1], bounds[0][2] );
  83. qglVertex3f( bounds[0][0], bounds[0][1], bounds[1][2] );
  84. qglVertex3f( bounds[0][0], bounds[1][1], bounds[0][2] );
  85. qglVertex3f( bounds[0][0], bounds[1][1], bounds[1][2] );
  86. qglVertex3f( bounds[1][0], bounds[0][1], bounds[0][2] );
  87. qglVertex3f( bounds[1][0], bounds[0][1], bounds[1][2] );
  88. qglVertex3f( bounds[1][0], bounds[1][1], bounds[0][2] );
  89. qglVertex3f( bounds[1][0], bounds[1][1], bounds[1][2] );
  90. qglEnd();
  91. }
  92. /*
  93. ================
  94. RB_SimpleSurfaceSetup
  95. ================
  96. */
  97. void RB_SimpleSurfaceSetup( const drawSurf_t *drawSurf ) {
  98. // change the matrix if needed
  99. if ( drawSurf->space != backEnd.currentSpace ) {
  100. qglLoadMatrixf( drawSurf->space->modelViewMatrix );
  101. backEnd.currentSpace = drawSurf->space;
  102. }
  103. // change the scissor if needed
  104. if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) {
  105. backEnd.currentScissor = drawSurf->scissorRect;
  106. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  107. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  108. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  109. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  110. }
  111. }
  112. /*
  113. ================
  114. RB_SimpleWorldSetup
  115. ================
  116. */
  117. void RB_SimpleWorldSetup( void ) {
  118. backEnd.currentSpace = &backEnd.viewDef->worldSpace;
  119. qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );
  120. backEnd.currentScissor = backEnd.viewDef->scissor;
  121. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  122. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  123. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  124. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  125. }
  126. /*
  127. =================
  128. RB_PolygonClear
  129. This will cover the entire screen with normal rasterization.
  130. Texturing is disabled, but the existing glColor, glDepthMask,
  131. glColorMask, and the enabled state of depth buffering and
  132. stenciling will matter.
  133. =================
  134. */
  135. void RB_PolygonClear( void ) {
  136. qglPushMatrix();
  137. qglPushAttrib( GL_ALL_ATTRIB_BITS );
  138. qglLoadIdentity();
  139. qglDisable( GL_TEXTURE_2D );
  140. qglDisable( GL_DEPTH_TEST );
  141. qglDisable( GL_CULL_FACE );
  142. qglDisable( GL_SCISSOR_TEST );
  143. qglBegin( GL_POLYGON );
  144. qglVertex3f( -20, -20, -10 );
  145. qglVertex3f( 20, -20, -10 );
  146. qglVertex3f( 20, 20, -10 );
  147. qglVertex3f( -20, 20, -10 );
  148. qglEnd();
  149. qglPopAttrib();
  150. qglPopMatrix();
  151. }
  152. /*
  153. ====================
  154. RB_ShowDestinationAlpha
  155. ====================
  156. */
  157. void RB_ShowDestinationAlpha( void ) {
  158. GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
  159. qglColor3f( 1, 1, 1 );
  160. RB_PolygonClear();
  161. }
  162. /*
  163. ===================
  164. RB_ScanStencilBuffer
  165. Debugging tool to see what values are in the stencil buffer
  166. ===================
  167. */
  168. void RB_ScanStencilBuffer( void ) {
  169. int counts[256];
  170. int i;
  171. byte *stencilReadback;
  172. memset( counts, 0, sizeof( counts ) );
  173. stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight );
  174. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback );
  175. for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) {
  176. counts[ stencilReadback[i] ]++;
  177. }
  178. R_StaticFree( stencilReadback );
  179. // print some stats (not supposed to do from back end in SMP...)
  180. common->Printf( "stencil values:\n" );
  181. for ( i = 0 ; i < 255 ; i++ ) {
  182. if ( counts[i] ) {
  183. common->Printf( "%i: %i\n", i, counts[i] );
  184. }
  185. }
  186. }
  187. /*
  188. ===================
  189. RB_CountStencilBuffer
  190. Print an overdraw count based on stencil index values
  191. ===================
  192. */
  193. void RB_CountStencilBuffer( void ) {
  194. int count;
  195. int i;
  196. byte *stencilReadback;
  197. stencilReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight );
  198. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback );
  199. count = 0;
  200. for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) {
  201. count += stencilReadback[i];
  202. }
  203. R_StaticFree( stencilReadback );
  204. // print some stats (not supposed to do from back end in SMP...)
  205. common->Printf( "overdraw: %5.1f\n", (float)count/(glConfig.vidWidth * glConfig.vidHeight) );
  206. }
  207. /*
  208. ===================
  209. R_ColorByStencilBuffer
  210. Sets the screen colors based on the contents of the
  211. stencil buffer. Stencil of 0 = black, 1 = red, 2 = green,
  212. 3 = blue, ..., 7+ = white
  213. ===================
  214. */
  215. static void R_ColorByStencilBuffer( void ) {
  216. int i;
  217. static float colors[8][3] = {
  218. {0,0,0},
  219. {1,0,0},
  220. {0,1,0},
  221. {0,0,1},
  222. {0,1,1},
  223. {1,0,1},
  224. {1,1,0},
  225. {1,1,1},
  226. };
  227. // clear color buffer to white (>6 passes)
  228. qglClearColor( 1, 1, 1, 1 );
  229. qglDisable( GL_SCISSOR_TEST );
  230. qglClear( GL_COLOR_BUFFER_BIT );
  231. // now draw color for each stencil value
  232. qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  233. for ( i = 0 ; i < 6 ; i++ ) {
  234. qglColor3fv( colors[i] );
  235. qglStencilFunc( GL_EQUAL, i, 255 );
  236. RB_PolygonClear();
  237. }
  238. qglStencilFunc( GL_ALWAYS, 0, 255 );
  239. }
  240. //======================================================================
  241. /*
  242. ==================
  243. RB_ShowOverdraw
  244. ==================
  245. */
  246. void RB_ShowOverdraw( void ) {
  247. const idMaterial * material;
  248. int i;
  249. drawSurf_t * * drawSurfs;
  250. const drawSurf_t * surf;
  251. int numDrawSurfs;
  252. viewLight_t * vLight;
  253. if ( r_showOverDraw.GetInteger() == 0 ) {
  254. return;
  255. }
  256. material = declManager->FindMaterial( "textures/common/overdrawtest", false );
  257. if ( material == NULL ) {
  258. return;
  259. }
  260. drawSurfs = backEnd.viewDef->drawSurfs;
  261. numDrawSurfs = backEnd.viewDef->numDrawSurfs;
  262. int interactions = 0;
  263. for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) {
  264. for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) {
  265. interactions++;
  266. }
  267. for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) {
  268. interactions++;
  269. }
  270. }
  271. drawSurf_t **newDrawSurfs = (drawSurf_t **)R_FrameAlloc( numDrawSurfs + interactions * sizeof( newDrawSurfs[0] ) );
  272. for ( i = 0; i < numDrawSurfs; i++ ) {
  273. surf = drawSurfs[i];
  274. if ( surf->material ) {
  275. const_cast<drawSurf_t *>(surf)->material = material;
  276. }
  277. newDrawSurfs[i] = const_cast<drawSurf_t *>(surf);
  278. }
  279. for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) {
  280. for ( surf = vLight->localInteractions; surf; surf = surf->nextOnLight ) {
  281. const_cast<drawSurf_t *>(surf)->material = material;
  282. newDrawSurfs[i++] = const_cast<drawSurf_t *>(surf);
  283. }
  284. for ( surf = vLight->globalInteractions; surf; surf = surf->nextOnLight ) {
  285. const_cast<drawSurf_t *>(surf)->material = material;
  286. newDrawSurfs[i++] = const_cast<drawSurf_t *>(surf);
  287. }
  288. vLight->localInteractions = NULL;
  289. vLight->globalInteractions = NULL;
  290. }
  291. switch( r_showOverDraw.GetInteger() ) {
  292. case 1: // geometry overdraw
  293. const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = newDrawSurfs;
  294. const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs = numDrawSurfs;
  295. break;
  296. case 2: // light interaction overdraw
  297. const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = &newDrawSurfs[numDrawSurfs];
  298. const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs = interactions;
  299. break;
  300. case 3: // geometry + light interaction overdraw
  301. const_cast<viewDef_t *>(backEnd.viewDef)->drawSurfs = newDrawSurfs;
  302. const_cast<viewDef_t *>(backEnd.viewDef)->numDrawSurfs += interactions;
  303. break;
  304. }
  305. }
  306. /*
  307. ===================
  308. RB_ShowIntensity
  309. Debugging tool to see how much dynamic range a scene is using.
  310. The greatest of the rgb values at each pixel will be used, with
  311. the resulting color shading from red at 0 to green at 128 to blue at 255
  312. ===================
  313. */
  314. void RB_ShowIntensity( void ) {
  315. byte *colorReadback;
  316. int i, j, c;
  317. if ( !r_showIntensity.GetBool() ) {
  318. return;
  319. }
  320. colorReadback = (byte *)R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight * 4 );
  321. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorReadback );
  322. c = glConfig.vidWidth * glConfig.vidHeight * 4;
  323. for ( i = 0; i < c ; i+=4 ) {
  324. j = colorReadback[i];
  325. if ( colorReadback[i+1] > j ) {
  326. j = colorReadback[i+1];
  327. }
  328. if ( colorReadback[i+2] > j ) {
  329. j = colorReadback[i+2];
  330. }
  331. if ( j < 128 ) {
  332. colorReadback[i+0] = 2*(128-j);
  333. colorReadback[i+1] = 2*j;
  334. colorReadback[i+2] = 0;
  335. } else {
  336. colorReadback[i+0] = 0;
  337. colorReadback[i+1] = 2*(255-j);
  338. colorReadback[i+2] = 2*(j-128);
  339. }
  340. }
  341. // draw it back to the screen
  342. qglLoadIdentity();
  343. qglMatrixMode( GL_PROJECTION );
  344. GL_State( GLS_DEPTHFUNC_ALWAYS );
  345. qglPushMatrix();
  346. qglLoadIdentity();
  347. qglOrtho( 0, 1, 0, 1, -1, 1 );
  348. qglRasterPos2f( 0, 0 );
  349. qglPopMatrix();
  350. qglColor3f( 1, 1, 1 );
  351. globalImages->BindNull();
  352. qglMatrixMode( GL_MODELVIEW );
  353. qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, colorReadback );
  354. R_StaticFree( colorReadback );
  355. }
  356. /*
  357. ===================
  358. RB_ShowDepthBuffer
  359. Draw the depth buffer as colors
  360. ===================
  361. */
  362. void RB_ShowDepthBuffer( void ) {
  363. void *depthReadback;
  364. if ( !r_showDepth.GetBool() ) {
  365. return;
  366. }
  367. qglPushMatrix();
  368. qglLoadIdentity();
  369. qglMatrixMode( GL_PROJECTION );
  370. qglPushMatrix();
  371. qglLoadIdentity();
  372. qglOrtho( 0, 1, 0, 1, -1, 1 );
  373. qglRasterPos2f( 0, 0 );
  374. qglPopMatrix();
  375. qglMatrixMode( GL_MODELVIEW );
  376. qglPopMatrix();
  377. GL_State( GLS_DEPTHFUNC_ALWAYS );
  378. qglColor3f( 1, 1, 1 );
  379. globalImages->BindNull();
  380. depthReadback = R_StaticAlloc( glConfig.vidWidth * glConfig.vidHeight*4 );
  381. memset( depthReadback, 0, glConfig.vidWidth * glConfig.vidHeight*4 );
  382. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_DEPTH_COMPONENT , GL_FLOAT, depthReadback );
  383. #if 0
  384. for ( i = 0 ; i < glConfig.vidWidth * glConfig.vidHeight ; i++ ) {
  385. ((byte *)depthReadback)[i*4] =
  386. ((byte *)depthReadback)[i*4+1] =
  387. ((byte *)depthReadback)[i*4+2] = 255 * ((float *)depthReadback)[i];
  388. ((byte *)depthReadback)[i*4+3] = 1;
  389. }
  390. #endif
  391. qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA , GL_UNSIGNED_BYTE, depthReadback );
  392. R_StaticFree( depthReadback );
  393. }
  394. /*
  395. =================
  396. RB_ShowLightCount
  397. This is a debugging tool that will draw each surface with a color
  398. based on how many lights are effecting it
  399. =================
  400. */
  401. void RB_ShowLightCount( void ) {
  402. int i;
  403. const drawSurf_t *surf;
  404. const viewLight_t *vLight;
  405. if ( !r_showLightCount.GetBool() ) {
  406. return;
  407. }
  408. GL_State( GLS_DEPTHFUNC_EQUAL );
  409. RB_SimpleWorldSetup();
  410. qglClearStencil( 0 );
  411. qglClear( GL_STENCIL_BUFFER_BIT );
  412. qglEnable( GL_STENCIL_TEST );
  413. // optionally count everything through walls
  414. if ( r_showLightCount.GetInteger() >= 2 ) {
  415. qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
  416. } else {
  417. qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
  418. }
  419. qglStencilFunc( GL_ALWAYS, 1, 255 );
  420. globalImages->defaultImage->Bind();
  421. for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  422. for ( i = 0 ; i < 2 ; i++ ) {
  423. for ( surf = i ? vLight->localInteractions: vLight->globalInteractions; surf; surf = (drawSurf_t *)surf->nextOnLight ) {
  424. RB_SimpleSurfaceSetup( surf );
  425. if ( !surf->geo->ambientCache ) {
  426. continue;
  427. }
  428. const idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
  429. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), &ac->xyz );
  430. RB_DrawElementsWithCounters( surf->geo );
  431. }
  432. }
  433. }
  434. // display the results
  435. R_ColorByStencilBuffer();
  436. if ( r_showLightCount.GetInteger() > 2 ) {
  437. RB_CountStencilBuffer();
  438. }
  439. }
  440. /*
  441. =================
  442. RB_ShowSilhouette
  443. Blacks out all edges, then adds color for each edge that a shadow
  444. plane extends from, allowing you to see doubled edges
  445. =================
  446. */
  447. void RB_ShowSilhouette( void ) {
  448. int i;
  449. const drawSurf_t *surf;
  450. const viewLight_t *vLight;
  451. if ( !r_showSilhouette.GetBool() ) {
  452. return;
  453. }
  454. //
  455. // clear all triangle edges to black
  456. //
  457. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  458. globalImages->BindNull();
  459. qglDisable( GL_TEXTURE_2D );
  460. qglDisable( GL_STENCIL_TEST );
  461. qglColor3f( 0, 0, 0 );
  462. GL_State( GLS_POLYMODE_LINE );
  463. GL_Cull( CT_TWO_SIDED );
  464. qglDisable( GL_DEPTH_TEST );
  465. RB_RenderDrawSurfListWithFunction( backEnd.viewDef->drawSurfs, backEnd.viewDef->numDrawSurfs,
  466. RB_T_RenderTriangleSurface );
  467. //
  468. // now blend in edges that cast silhouettes
  469. //
  470. RB_SimpleWorldSetup();
  471. qglColor3f( 0.5, 0, 0 );
  472. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
  473. for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  474. for ( i = 0 ; i < 2 ; i++ ) {
  475. for ( surf = i ? vLight->localShadows : vLight->globalShadows
  476. ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) {
  477. RB_SimpleSurfaceSetup( surf );
  478. const srfTriangles_t *tri = surf->geo;
  479. qglVertexPointer( 3, GL_FLOAT, sizeof( shadowCache_t ), vertexCache.Position( tri->shadowCache ) );
  480. qglBegin( GL_LINES );
  481. for ( int j = 0 ; j < tri->numIndexes ; j+=3 ) {
  482. int i1 = tri->indexes[j+0];
  483. int i2 = tri->indexes[j+1];
  484. int i3 = tri->indexes[j+2];
  485. if ( (i1 & 1) + (i2 & 1) + (i3 & 1) == 1 ) {
  486. if ( (i1 & 1) + (i2 & 1) == 0 ) {
  487. qglArrayElement( i1 );
  488. qglArrayElement( i2 );
  489. } else if ( (i1 & 1 ) + (i3 & 1) == 0 ) {
  490. qglArrayElement( i1 );
  491. qglArrayElement( i3 );
  492. }
  493. }
  494. }
  495. qglEnd();
  496. }
  497. }
  498. }
  499. qglEnable( GL_DEPTH_TEST );
  500. GL_State( GLS_DEFAULT );
  501. qglColor3f( 1,1,1 );
  502. GL_Cull( CT_FRONT_SIDED );
  503. }
  504. /*
  505. =================
  506. RB_ShowShadowCount
  507. This is a debugging tool that will draw only the shadow volumes
  508. and count up the total fill usage
  509. =================
  510. */
  511. static void RB_ShowShadowCount( void ) {
  512. int i;
  513. const drawSurf_t *surf;
  514. const viewLight_t *vLight;
  515. if ( !r_showShadowCount.GetBool() ) {
  516. return;
  517. }
  518. GL_State( GLS_DEFAULT );
  519. qglClearStencil( 0 );
  520. qglClear( GL_STENCIL_BUFFER_BIT );
  521. qglEnable( GL_STENCIL_TEST );
  522. qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
  523. qglStencilFunc( GL_ALWAYS, 1, 255 );
  524. globalImages->defaultImage->Bind();
  525. // draw both sides
  526. GL_Cull( CT_TWO_SIDED );
  527. for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  528. for ( i = 0 ; i < 2 ; i++ ) {
  529. for ( surf = i ? vLight->localShadows : vLight->globalShadows
  530. ; surf ; surf = (drawSurf_t *)surf->nextOnLight ) {
  531. RB_SimpleSurfaceSetup( surf );
  532. const srfTriangles_t *tri = surf->geo;
  533. if ( !tri->shadowCache ) {
  534. continue;
  535. }
  536. if ( r_showShadowCount.GetInteger() == 3 ) {
  537. // only show turboshadows
  538. if ( tri->numShadowIndexesNoCaps != tri->numIndexes ) {
  539. continue;
  540. }
  541. }
  542. if ( r_showShadowCount.GetInteger() == 4 ) {
  543. // only show static shadows
  544. if ( tri->numShadowIndexesNoCaps == tri->numIndexes ) {
  545. continue;
  546. }
  547. }
  548. shadowCache_t *cache = (shadowCache_t *)vertexCache.Position( tri->shadowCache );
  549. qglVertexPointer( 4, GL_FLOAT, sizeof( *cache ), &cache->xyz );
  550. RB_DrawElementsWithCounters( tri );
  551. }
  552. }
  553. }
  554. // display the results
  555. R_ColorByStencilBuffer();
  556. if ( r_showShadowCount.GetInteger() == 2 ) {
  557. common->Printf( "all shadows " );
  558. } else if ( r_showShadowCount.GetInteger() == 3 ) {
  559. common->Printf( "turboShadows " );
  560. } else if ( r_showShadowCount.GetInteger() == 4 ) {
  561. common->Printf( "static shadows " );
  562. }
  563. if ( r_showShadowCount.GetInteger() >= 2 ) {
  564. RB_CountStencilBuffer();
  565. }
  566. GL_Cull( CT_FRONT_SIDED );
  567. }
  568. /*
  569. ===============
  570. RB_T_RenderTriangleSurfaceAsLines
  571. ===============
  572. */
  573. void RB_T_RenderTriangleSurfaceAsLines( const drawSurf_t *surf ) {
  574. const srfTriangles_t *tri = surf->geo;
  575. if ( !tri->verts ) {
  576. return;
  577. }
  578. qglBegin( GL_LINES );
  579. for ( int i = 0 ; i < tri->numIndexes ; i+= 3 ) {
  580. for ( int j = 0 ; j < 3 ; j++ ) {
  581. int k = ( j + 1 ) % 3;
  582. qglVertex3fv( tri->verts[ tri->silIndexes[i+j] ].xyz.ToFloatPtr() );
  583. qglVertex3fv( tri->verts[ tri->silIndexes[i+k] ].xyz.ToFloatPtr() );
  584. }
  585. }
  586. qglEnd();
  587. }
  588. /*
  589. =====================
  590. RB_ShowTris
  591. Debugging tool
  592. =====================
  593. */
  594. static void RB_ShowTris( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  595. modelTrace_t mt;
  596. idVec3 end;
  597. if ( !r_showTris.GetInteger() ) {
  598. return;
  599. }
  600. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  601. globalImages->BindNull();
  602. qglDisable( GL_TEXTURE_2D );
  603. qglDisable( GL_STENCIL_TEST );
  604. qglColor3f( 1, 1, 1 );
  605. GL_State( GLS_POLYMODE_LINE );
  606. switch ( r_showTris.GetInteger() ) {
  607. case 1: // only draw visible ones
  608. qglPolygonOffset( -1, -2 );
  609. qglEnable( GL_POLYGON_OFFSET_LINE );
  610. break;
  611. default:
  612. case 2: // draw all front facing
  613. GL_Cull( CT_FRONT_SIDED );
  614. qglDisable( GL_DEPTH_TEST );
  615. break;
  616. case 3: // draw all
  617. GL_Cull( CT_TWO_SIDED );
  618. qglDisable( GL_DEPTH_TEST );
  619. break;
  620. }
  621. RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_T_RenderTriangleSurface );
  622. qglEnable( GL_DEPTH_TEST );
  623. qglDisable( GL_POLYGON_OFFSET_LINE );
  624. qglDepthRange( 0, 1 );
  625. GL_State( GLS_DEFAULT );
  626. GL_Cull( CT_FRONT_SIDED );
  627. }
  628. /*
  629. =====================
  630. RB_ShowSurfaceInfo
  631. Debugging tool
  632. =====================
  633. */
  634. static void RB_ShowSurfaceInfo( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  635. modelTrace_t mt;
  636. idVec3 start, end;
  637. if ( !r_showSurfaceInfo.GetBool() ) {
  638. return;
  639. }
  640. // start far enough away that we don't hit the player model
  641. start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16;
  642. end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f;
  643. if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) {
  644. return;
  645. }
  646. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  647. globalImages->BindNull();
  648. qglDisable( GL_TEXTURE_2D );
  649. qglDisable( GL_STENCIL_TEST );
  650. qglColor3f( 1, 1, 1 );
  651. GL_State( GLS_POLYMODE_LINE );
  652. qglPolygonOffset( -1, -2 );
  653. qglEnable( GL_POLYGON_OFFSET_LINE );
  654. idVec3 trans[3];
  655. float matrix[16];
  656. // transform the object verts into global space
  657. R_AxisToModelMatrix( mt.entity->axis, mt.entity->origin, matrix );
  658. tr.primaryWorld->DrawText( mt.entity->hModel->Name(), mt.point + tr.primaryView->renderView.viewaxis[2] * 12,
  659. 0.35f, colorRed, tr.primaryView->renderView.viewaxis );
  660. tr.primaryWorld->DrawText( mt.material->GetName(), mt.point,
  661. 0.35f, colorBlue, tr.primaryView->renderView.viewaxis );
  662. qglEnable( GL_DEPTH_TEST );
  663. qglDisable( GL_POLYGON_OFFSET_LINE );
  664. qglDepthRange( 0, 1 );
  665. GL_State( GLS_DEFAULT );
  666. GL_Cull( CT_FRONT_SIDED );
  667. }
  668. /*
  669. =====================
  670. RB_ShowViewEntitys
  671. Debugging tool
  672. =====================
  673. */
  674. static void RB_ShowViewEntitys( viewEntity_t *vModels ) {
  675. if ( !r_showViewEntitys.GetBool() ) {
  676. return;
  677. }
  678. if ( r_showViewEntitys.GetInteger() == 2 ) {
  679. common->Printf( "view entities: " );
  680. for ( ; vModels ; vModels = vModels->next ) {
  681. common->Printf( "%i ", vModels->entityDef->index );
  682. }
  683. common->Printf( "\n" );
  684. return;
  685. }
  686. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  687. globalImages->BindNull();
  688. qglDisable( GL_TEXTURE_2D );
  689. qglDisable( GL_STENCIL_TEST );
  690. qglColor3f( 1, 1, 1 );
  691. GL_State( GLS_POLYMODE_LINE );
  692. GL_Cull( CT_TWO_SIDED );
  693. qglDisable( GL_DEPTH_TEST );
  694. qglDisable( GL_SCISSOR_TEST );
  695. for ( ; vModels ; vModels = vModels->next ) {
  696. idBounds b;
  697. qglLoadMatrixf( vModels->modelViewMatrix );
  698. if ( !vModels->entityDef ) {
  699. continue;
  700. }
  701. // draw the reference bounds in yellow
  702. qglColor3f( 1, 1, 0 );
  703. RB_DrawBounds( vModels->entityDef->referenceBounds );
  704. // draw the model bounds in white
  705. qglColor3f( 1, 1, 1 );
  706. idRenderModel *model = R_EntityDefDynamicModel( vModels->entityDef );
  707. if ( !model ) {
  708. continue; // particles won't instantiate without a current view
  709. }
  710. b = model->Bounds( &vModels->entityDef->parms );
  711. RB_DrawBounds( b );
  712. }
  713. qglEnable( GL_DEPTH_TEST );
  714. qglDisable( GL_POLYGON_OFFSET_LINE );
  715. qglDepthRange( 0, 1 );
  716. GL_State( GLS_DEFAULT );
  717. GL_Cull( CT_FRONT_SIDED );
  718. }
  719. /*
  720. =====================
  721. RB_ShowTexturePolarity
  722. Shade triangle red if they have a positive texture area
  723. green if they have a negative texture area, or blue if degenerate area
  724. =====================
  725. */
  726. static void RB_ShowTexturePolarity( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  727. int i, j;
  728. drawSurf_t *drawSurf;
  729. const srfTriangles_t *tri;
  730. if ( !r_showTexturePolarity.GetBool() ) {
  731. return;
  732. }
  733. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  734. globalImages->BindNull();
  735. qglDisable( GL_STENCIL_TEST );
  736. GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
  737. qglColor3f( 1, 1, 1 );
  738. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  739. drawSurf = drawSurfs[i];
  740. tri = drawSurf->geo;
  741. if ( !tri->verts ) {
  742. continue;
  743. }
  744. RB_SimpleSurfaceSetup( drawSurf );
  745. qglBegin( GL_TRIANGLES );
  746. for ( j = 0 ; j < tri->numIndexes ; j+=3 ) {
  747. idDrawVert *a, *b, *c;
  748. float d0[5], d1[5];
  749. float area;
  750. a = tri->verts + tri->indexes[j];
  751. b = tri->verts + tri->indexes[j+1];
  752. c = tri->verts + tri->indexes[j+2];
  753. // VectorSubtract( b->xyz, a->xyz, d0 );
  754. d0[3] = b->st[0] - a->st[0];
  755. d0[4] = b->st[1] - a->st[1];
  756. // VectorSubtract( c->xyz, a->xyz, d1 );
  757. d1[3] = c->st[0] - a->st[0];
  758. d1[4] = c->st[1] - a->st[1];
  759. area = d0[3] * d1[4] - d0[4] * d1[3];
  760. if ( idMath::Fabs( area ) < 0.0001 ) {
  761. qglColor4f( 0, 0, 1, 0.5 );
  762. } else if ( area < 0 ) {
  763. qglColor4f( 1, 0, 0, 0.5 );
  764. } else {
  765. qglColor4f( 0, 1, 0, 0.5 );
  766. }
  767. qglVertex3fv( a->xyz.ToFloatPtr() );
  768. qglVertex3fv( b->xyz.ToFloatPtr() );
  769. qglVertex3fv( c->xyz.ToFloatPtr() );
  770. }
  771. qglEnd();
  772. }
  773. GL_State( GLS_DEFAULT );
  774. }
  775. /*
  776. =====================
  777. RB_ShowUnsmoothedTangents
  778. Shade materials that are using unsmoothed tangents
  779. =====================
  780. */
  781. static void RB_ShowUnsmoothedTangents( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  782. int i, j;
  783. drawSurf_t *drawSurf;
  784. const srfTriangles_t *tri;
  785. if ( !r_showUnsmoothedTangents.GetBool() ) {
  786. return;
  787. }
  788. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  789. globalImages->BindNull();
  790. qglDisable( GL_STENCIL_TEST );
  791. GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
  792. qglColor4f( 0, 1, 0, 0.5 );
  793. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  794. drawSurf = drawSurfs[i];
  795. if ( !drawSurf->material->UseUnsmoothedTangents() ) {
  796. continue;
  797. }
  798. RB_SimpleSurfaceSetup( drawSurf );
  799. tri = drawSurf->geo;
  800. qglBegin( GL_TRIANGLES );
  801. for ( j = 0 ; j < tri->numIndexes ; j+=3 ) {
  802. idDrawVert *a, *b, *c;
  803. a = tri->verts + tri->indexes[j];
  804. b = tri->verts + tri->indexes[j+1];
  805. c = tri->verts + tri->indexes[j+2];
  806. qglVertex3fv( a->xyz.ToFloatPtr() );
  807. qglVertex3fv( b->xyz.ToFloatPtr() );
  808. qglVertex3fv( c->xyz.ToFloatPtr() );
  809. }
  810. qglEnd();
  811. }
  812. GL_State( GLS_DEFAULT );
  813. }
  814. /*
  815. =====================
  816. RB_ShowTangentSpace
  817. Shade a triangle by the RGB colors of its tangent space
  818. 1 = tangents[0]
  819. 2 = tangents[1]
  820. 3 = normal
  821. =====================
  822. */
  823. static void RB_ShowTangentSpace( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  824. int i, j;
  825. drawSurf_t *drawSurf;
  826. const srfTriangles_t *tri;
  827. if ( !r_showTangentSpace.GetInteger() ) {
  828. return;
  829. }
  830. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  831. globalImages->BindNull();
  832. qglDisable( GL_STENCIL_TEST );
  833. GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
  834. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  835. drawSurf = drawSurfs[i];
  836. RB_SimpleSurfaceSetup( drawSurf );
  837. tri = drawSurf->geo;
  838. if ( !tri->verts ) {
  839. continue;
  840. }
  841. qglBegin( GL_TRIANGLES );
  842. for ( j = 0 ; j < tri->numIndexes ; j++ ) {
  843. const idDrawVert *v;
  844. v = &tri->verts[tri->indexes[j]];
  845. if ( r_showTangentSpace.GetInteger() == 1 ) {
  846. qglColor4f( 0.5 + 0.5 * v->tangents[0][0], 0.5 + 0.5 * v->tangents[0][1],
  847. 0.5 + 0.5 * v->tangents[0][2], 0.5 );
  848. } else if ( r_showTangentSpace.GetInteger() == 2 ) {
  849. qglColor4f( 0.5 + 0.5 * v->tangents[1][0], 0.5 + 0.5 * v->tangents[1][1],
  850. 0.5 + 0.5 * v->tangents[1][2], 0.5 );
  851. } else {
  852. qglColor4f( 0.5 + 0.5 * v->normal[0], 0.5 + 0.5 * v->normal[1],
  853. 0.5 + 0.5 * v->normal[2], 0.5 );
  854. }
  855. qglVertex3fv( v->xyz.ToFloatPtr() );
  856. }
  857. qglEnd();
  858. }
  859. GL_State( GLS_DEFAULT );
  860. }
  861. /*
  862. =====================
  863. RB_ShowVertexColor
  864. Draw each triangle with the solid vertex colors
  865. =====================
  866. */
  867. static void RB_ShowVertexColor( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  868. int i, j;
  869. drawSurf_t *drawSurf;
  870. const srfTriangles_t *tri;
  871. if ( !r_showVertexColor.GetBool() ) {
  872. return;
  873. }
  874. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  875. globalImages->BindNull();
  876. qglDisable( GL_STENCIL_TEST );
  877. GL_State( GLS_DEPTHFUNC_LESS );
  878. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  879. drawSurf = drawSurfs[i];
  880. RB_SimpleSurfaceSetup( drawSurf );
  881. tri = drawSurf->geo;
  882. if ( !tri->verts ) {
  883. continue;
  884. }
  885. qglBegin( GL_TRIANGLES );
  886. for ( j = 0 ; j < tri->numIndexes ; j++ ) {
  887. const idDrawVert *v;
  888. v = &tri->verts[tri->indexes[j]];
  889. qglColor4ubv( v->color );
  890. qglVertex3fv( v->xyz.ToFloatPtr() );
  891. }
  892. qglEnd();
  893. }
  894. GL_State( GLS_DEFAULT );
  895. }
  896. /*
  897. =====================
  898. RB_ShowNormals
  899. Debugging tool
  900. =====================
  901. */
  902. static void RB_ShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  903. int i, j;
  904. drawSurf_t *drawSurf;
  905. idVec3 end;
  906. const srfTriangles_t *tri;
  907. float size;
  908. bool showNumbers;
  909. idVec3 pos;
  910. if ( r_showNormals.GetFloat() == 0.0f ) {
  911. return;
  912. }
  913. GL_State( GLS_POLYMODE_LINE );
  914. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  915. globalImages->BindNull();
  916. qglDisable( GL_STENCIL_TEST );
  917. if ( !r_debugLineDepthTest.GetBool() ) {
  918. qglDisable( GL_DEPTH_TEST );
  919. } else {
  920. qglEnable( GL_DEPTH_TEST );
  921. }
  922. size = r_showNormals.GetFloat();
  923. if ( size < 0.0f ) {
  924. size = -size;
  925. showNumbers = true;
  926. } else {
  927. showNumbers = false;
  928. }
  929. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  930. drawSurf = drawSurfs[i];
  931. RB_SimpleSurfaceSetup( drawSurf );
  932. tri = drawSurf->geo;
  933. if ( !tri->verts ) {
  934. continue;
  935. }
  936. qglBegin( GL_LINES );
  937. for ( j = 0 ; j < tri->numVerts ; j++ ) {
  938. qglColor3f( 0, 0, 1 );
  939. qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
  940. VectorMA( tri->verts[j].xyz, size, tri->verts[j].normal, end );
  941. qglVertex3fv( end.ToFloatPtr() );
  942. qglColor3f( 1, 0, 0 );
  943. qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
  944. VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[0], end );
  945. qglVertex3fv( end.ToFloatPtr() );
  946. qglColor3f( 0, 1, 0 );
  947. qglVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
  948. VectorMA( tri->verts[j].xyz, size, tri->verts[j].tangents[1], end );
  949. qglVertex3fv( end.ToFloatPtr() );
  950. }
  951. qglEnd();
  952. }
  953. if ( showNumbers ) {
  954. RB_SimpleWorldSetup();
  955. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  956. drawSurf = drawSurfs[i];
  957. tri = drawSurf->geo;
  958. if ( !tri->verts ) {
  959. continue;
  960. }
  961. for ( j = 0 ; j < tri->numVerts ; j++ ) {
  962. R_LocalPointToGlobal( drawSurf->space->modelMatrix, tri->verts[j].xyz + tri->verts[j].tangents[0] + tri->verts[j].normal * 0.2f, pos );
  963. RB_DrawText( va( "%d", j ), pos, 0.01f, colorWhite, backEnd.viewDef->renderView.viewaxis, 1 );
  964. }
  965. for ( j = 0 ; j < tri->numIndexes; j += 3 ) {
  966. R_LocalPointToGlobal( drawSurf->space->modelMatrix, ( tri->verts[ tri->indexes[ j + 0 ] ].xyz + tri->verts[ tri->indexes[ j + 1 ] ].xyz + tri->verts[ tri->indexes[ j + 2 ] ].xyz ) * ( 1.0f / 3.0f ) + tri->verts[ tri->indexes[ j + 0 ] ].normal * 0.2f, pos );
  967. RB_DrawText( va( "%d", j / 3 ), pos, 0.01f, colorCyan, backEnd.viewDef->renderView.viewaxis, 1 );
  968. }
  969. }
  970. }
  971. qglEnable( GL_STENCIL_TEST );
  972. }
  973. /*
  974. =====================
  975. RB_ShowNormals
  976. Debugging tool
  977. =====================
  978. */
  979. static void RB_AltShowNormals( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  980. int i, j, k;
  981. drawSurf_t *drawSurf;
  982. idVec3 end;
  983. const srfTriangles_t *tri;
  984. if ( r_showNormals.GetFloat() == 0.0f ) {
  985. return;
  986. }
  987. GL_State( GLS_DEFAULT );
  988. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  989. globalImages->BindNull();
  990. qglDisable( GL_STENCIL_TEST );
  991. qglDisable( GL_DEPTH_TEST );
  992. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  993. drawSurf = drawSurfs[i];
  994. RB_SimpleSurfaceSetup( drawSurf );
  995. tri = drawSurf->geo;
  996. qglBegin( GL_LINES );
  997. for ( j = 0 ; j < tri->numIndexes ; j += 3 ) {
  998. const idDrawVert *v[3];
  999. idVec3 mid;
  1000. v[0] = &tri->verts[tri->indexes[j+0]];
  1001. v[1] = &tri->verts[tri->indexes[j+1]];
  1002. v[2] = &tri->verts[tri->indexes[j+2]];
  1003. // make the midpoint slightly above the triangle
  1004. mid = ( v[0]->xyz + v[1]->xyz + v[2]->xyz ) * ( 1.0f / 3.0f );
  1005. mid += 0.1f * tri->facePlanes[ j / 3 ].Normal();
  1006. for ( k = 0 ; k < 3 ; k++ ) {
  1007. idVec3 pos;
  1008. pos = ( mid + v[k]->xyz * 3.0f ) * 0.25f;
  1009. qglColor3f( 0, 0, 1 );
  1010. qglVertex3fv( pos.ToFloatPtr() );
  1011. VectorMA( pos, r_showNormals.GetFloat(), v[k]->normal, end );
  1012. qglVertex3fv( end.ToFloatPtr() );
  1013. qglColor3f( 1, 0, 0 );
  1014. qglVertex3fv( pos.ToFloatPtr() );
  1015. VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[0], end );
  1016. qglVertex3fv( end.ToFloatPtr() );
  1017. qglColor3f( 0, 1, 0 );
  1018. qglVertex3fv( pos.ToFloatPtr() );
  1019. VectorMA( pos, r_showNormals.GetFloat(), v[k]->tangents[1], end );
  1020. qglVertex3fv( end.ToFloatPtr() );
  1021. qglColor3f( 1, 1, 1 );
  1022. qglVertex3fv( pos.ToFloatPtr() );
  1023. qglVertex3fv( v[k]->xyz.ToFloatPtr() );
  1024. }
  1025. }
  1026. qglEnd();
  1027. }
  1028. qglEnable( GL_DEPTH_TEST );
  1029. qglEnable( GL_STENCIL_TEST );
  1030. }
  1031. /*
  1032. =====================
  1033. RB_ShowTextureVectors
  1034. Draw texture vectors in the center of each triangle
  1035. =====================
  1036. */
  1037. static void RB_ShowTextureVectors( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  1038. int i, j;
  1039. drawSurf_t *drawSurf;
  1040. const srfTriangles_t *tri;
  1041. if ( r_showTextureVectors.GetFloat() == 0.0f ) {
  1042. return;
  1043. }
  1044. GL_State( GLS_DEPTHFUNC_LESS );
  1045. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1046. globalImages->BindNull();
  1047. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  1048. drawSurf = drawSurfs[i];
  1049. tri = drawSurf->geo;
  1050. if ( !tri->verts ) {
  1051. continue;
  1052. }
  1053. if ( !tri->facePlanes ) {
  1054. continue;
  1055. }
  1056. RB_SimpleSurfaceSetup( drawSurf );
  1057. // draw non-shared edges in yellow
  1058. qglBegin( GL_LINES );
  1059. for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) {
  1060. const idDrawVert *a, *b, *c;
  1061. float area, inva;
  1062. idVec3 temp;
  1063. float d0[5], d1[5];
  1064. idVec3 mid;
  1065. idVec3 tangents[2];
  1066. a = &tri->verts[tri->indexes[j+0]];
  1067. b = &tri->verts[tri->indexes[j+1]];
  1068. c = &tri->verts[tri->indexes[j+2]];
  1069. // make the midpoint slightly above the triangle
  1070. mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f );
  1071. mid += 0.1f * tri->facePlanes[ j / 3 ].Normal();
  1072. // calculate the texture vectors
  1073. VectorSubtract( b->xyz, a->xyz, d0 );
  1074. d0[3] = b->st[0] - a->st[0];
  1075. d0[4] = b->st[1] - a->st[1];
  1076. VectorSubtract( c->xyz, a->xyz, d1 );
  1077. d1[3] = c->st[0] - a->st[0];
  1078. d1[4] = c->st[1] - a->st[1];
  1079. area = d0[3] * d1[4] - d0[4] * d1[3];
  1080. if ( area == 0 ) {
  1081. continue;
  1082. }
  1083. inva = 1.0 / area;
  1084. temp[0] = (d0[0] * d1[4] - d0[4] * d1[0]) * inva;
  1085. temp[1] = (d0[1] * d1[4] - d0[4] * d1[1]) * inva;
  1086. temp[2] = (d0[2] * d1[4] - d0[4] * d1[2]) * inva;
  1087. temp.Normalize();
  1088. tangents[0] = temp;
  1089. temp[0] = (d0[3] * d1[0] - d0[0] * d1[3]) * inva;
  1090. temp[1] = (d0[3] * d1[1] - d0[1] * d1[3]) * inva;
  1091. temp[2] = (d0[3] * d1[2] - d0[2] * d1[3]) * inva;
  1092. temp.Normalize();
  1093. tangents[1] = temp;
  1094. // draw the tangents
  1095. tangents[0] = mid + tangents[0] * r_showTextureVectors.GetFloat();
  1096. tangents[1] = mid + tangents[1] * r_showTextureVectors.GetFloat();
  1097. qglColor3f( 1, 0, 0 );
  1098. qglVertex3fv( mid.ToFloatPtr() );
  1099. qglVertex3fv( tangents[0].ToFloatPtr() );
  1100. qglColor3f( 0, 1, 0 );
  1101. qglVertex3fv( mid.ToFloatPtr() );
  1102. qglVertex3fv( tangents[1].ToFloatPtr() );
  1103. }
  1104. qglEnd();
  1105. }
  1106. }
  1107. /*
  1108. =====================
  1109. RB_ShowDominantTris
  1110. Draw lines from each vertex to the dominant triangle center
  1111. =====================
  1112. */
  1113. static void RB_ShowDominantTris( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  1114. int i, j;
  1115. drawSurf_t *drawSurf;
  1116. const srfTriangles_t *tri;
  1117. if ( !r_showDominantTri.GetBool() ) {
  1118. return;
  1119. }
  1120. GL_State( GLS_DEPTHFUNC_LESS );
  1121. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1122. qglPolygonOffset( -1, -2 );
  1123. qglEnable( GL_POLYGON_OFFSET_LINE );
  1124. globalImages->BindNull();
  1125. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  1126. drawSurf = drawSurfs[i];
  1127. tri = drawSurf->geo;
  1128. if ( !tri->verts ) {
  1129. continue;
  1130. }
  1131. if ( !tri->dominantTris ) {
  1132. continue;
  1133. }
  1134. RB_SimpleSurfaceSetup( drawSurf );
  1135. qglColor3f( 1, 1, 0 );
  1136. qglBegin( GL_LINES );
  1137. for ( j = 0 ; j < tri->numVerts ; j++ ) {
  1138. const idDrawVert *a, *b, *c;
  1139. idVec3 mid;
  1140. // find the midpoint of the dominant tri
  1141. a = &tri->verts[j];
  1142. b = &tri->verts[tri->dominantTris[j].v2];
  1143. c = &tri->verts[tri->dominantTris[j].v3];
  1144. mid = ( a->xyz + b->xyz + c->xyz ) * ( 1.0f / 3.0f );
  1145. qglVertex3fv( mid.ToFloatPtr() );
  1146. qglVertex3fv( a->xyz.ToFloatPtr() );
  1147. }
  1148. qglEnd();
  1149. }
  1150. qglDisable( GL_POLYGON_OFFSET_LINE );
  1151. }
  1152. /*
  1153. =====================
  1154. RB_ShowEdges
  1155. Debugging tool
  1156. =====================
  1157. */
  1158. static void RB_ShowEdges( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  1159. int i, j, k, m, n, o;
  1160. drawSurf_t *drawSurf;
  1161. const srfTriangles_t *tri;
  1162. const silEdge_t *edge;
  1163. int danglePlane;
  1164. if ( !r_showEdges.GetBool() ) {
  1165. return;
  1166. }
  1167. GL_State( GLS_DEFAULT );
  1168. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1169. globalImages->BindNull();
  1170. qglDisable( GL_DEPTH_TEST );
  1171. for ( i = 0 ; i < numDrawSurfs ; i++ ) {
  1172. drawSurf = drawSurfs[i];
  1173. tri = drawSurf->geo;
  1174. idDrawVert *ac = (idDrawVert *)tri->verts;
  1175. if ( !ac ) {
  1176. continue;
  1177. }
  1178. RB_SimpleSurfaceSetup( drawSurf );
  1179. // draw non-shared edges in yellow
  1180. qglColor3f( 1, 1, 0 );
  1181. qglBegin( GL_LINES );
  1182. for ( j = 0 ; j < tri->numIndexes ; j+= 3 ) {
  1183. for ( k = 0 ; k < 3 ; k++ ) {
  1184. int l, i1, i2;
  1185. l = ( k == 2 ) ? 0 : k + 1;
  1186. i1 = tri->indexes[j+k];
  1187. i2 = tri->indexes[j+l];
  1188. // if these are used backwards, the edge is shared
  1189. for ( m = 0 ; m < tri->numIndexes ; m += 3 ) {
  1190. for ( n = 0 ; n < 3 ; n++ ) {
  1191. o = ( n == 2 ) ? 0 : n + 1;
  1192. if ( tri->indexes[m+n] == i2 && tri->indexes[m+o] == i1 ) {
  1193. break;
  1194. }
  1195. }
  1196. if ( n != 3 ) {
  1197. break;
  1198. }
  1199. }
  1200. // if we didn't find a backwards listing, draw it in yellow
  1201. if ( m == tri->numIndexes ) {
  1202. qglVertex3fv( ac[ i1 ].xyz.ToFloatPtr() );
  1203. qglVertex3fv( ac[ i2 ].xyz.ToFloatPtr() );
  1204. }
  1205. }
  1206. }
  1207. qglEnd();
  1208. // draw dangling sil edges in red
  1209. if ( !tri->silEdges ) {
  1210. continue;
  1211. }
  1212. // the plane number after all real planes
  1213. // is the dangling edge
  1214. danglePlane = tri->numIndexes / 3;
  1215. qglColor3f( 1, 0, 0 );
  1216. qglBegin( GL_LINES );
  1217. for ( j = 0 ; j < tri->numSilEdges ; j++ ) {
  1218. edge = tri->silEdges + j;
  1219. if ( edge->p1 != danglePlane && edge->p2 != danglePlane ) {
  1220. continue;
  1221. }
  1222. qglVertex3fv( ac[ edge->v1 ].xyz.ToFloatPtr() );
  1223. qglVertex3fv( ac[ edge->v2 ].xyz.ToFloatPtr() );
  1224. }
  1225. qglEnd();
  1226. }
  1227. qglEnable( GL_DEPTH_TEST );
  1228. }
  1229. /*
  1230. ==============
  1231. RB_ShowLights
  1232. Visualize all light volumes used in the current scene
  1233. r_showLights 1 : just print volumes numbers, highlighting ones covering the view
  1234. r_showLights 2 : also draw planes of each volume
  1235. r_showLights 3 : also draw edges of each volume
  1236. ==============
  1237. */
  1238. void RB_ShowLights( void ) {
  1239. const idRenderLightLocal *light;
  1240. int count;
  1241. srfTriangles_t *tri;
  1242. viewLight_t *vLight;
  1243. if ( !r_showLights.GetInteger() ) {
  1244. return;
  1245. }
  1246. // all volumes are expressed in world coordinates
  1247. RB_SimpleWorldSetup();
  1248. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1249. globalImages->BindNull();
  1250. qglDisable( GL_STENCIL_TEST );
  1251. GL_Cull( CT_TWO_SIDED );
  1252. qglDisable( GL_DEPTH_TEST );
  1253. common->Printf( "volumes: " ); // FIXME: not in back end!
  1254. count = 0;
  1255. for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  1256. light = vLight->lightDef;
  1257. count++;
  1258. tri = light->frustumTris;
  1259. // depth buffered planes
  1260. if ( r_showLights.GetInteger() >= 2 ) {
  1261. GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK );
  1262. qglColor4f( 0, 0, 1, 0.25 );
  1263. qglEnable( GL_DEPTH_TEST );
  1264. RB_RenderTriangleSurface( tri );
  1265. }
  1266. // non-hidden lines
  1267. if ( r_showLights.GetInteger() >= 3 ) {
  1268. GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK );
  1269. qglDisable( GL_DEPTH_TEST );
  1270. qglColor3f( 1, 1, 1 );
  1271. RB_RenderTriangleSurface( tri );
  1272. }
  1273. int index;
  1274. index = backEnd.viewDef->renderWorld->lightDefs.FindIndex( vLight->lightDef );
  1275. if ( vLight->viewInsideLight ) {
  1276. // view is in this volume
  1277. common->Printf( "[%i] ", index );
  1278. } else {
  1279. common->Printf( "%i ", index );
  1280. }
  1281. }
  1282. qglEnable( GL_DEPTH_TEST );
  1283. qglDisable( GL_POLYGON_OFFSET_LINE );
  1284. qglDepthRange( 0, 1 );
  1285. GL_State( GLS_DEFAULT );
  1286. GL_Cull( CT_FRONT_SIDED );
  1287. common->Printf( " = %i total\n", count );
  1288. }
  1289. /*
  1290. =====================
  1291. RB_ShowPortals
  1292. Debugging tool, won't work correctly with SMP or when mirrors are present
  1293. =====================
  1294. */
  1295. void RB_ShowPortals( void ) {
  1296. if ( !r_showPortals.GetBool() ) {
  1297. return;
  1298. }
  1299. // all portals are expressed in world coordinates
  1300. RB_SimpleWorldSetup();
  1301. globalImages->BindNull();
  1302. qglDisable( GL_DEPTH_TEST );
  1303. GL_State( GLS_DEFAULT );
  1304. ((idRenderWorldLocal *)backEnd.viewDef->renderWorld)->ShowPortals();
  1305. qglEnable( GL_DEPTH_TEST );
  1306. }
  1307. /*
  1308. ================
  1309. RB_ClearDebugText
  1310. ================
  1311. */
  1312. void RB_ClearDebugText( int time ) {
  1313. int i;
  1314. int num;
  1315. debugText_t *text;
  1316. rb_debugTextTime = time;
  1317. if ( !time ) {
  1318. // free up our strings
  1319. text = rb_debugText;
  1320. for ( i = 0 ; i < MAX_DEBUG_TEXT; i++, text++ ) {
  1321. text->text.Clear();
  1322. }
  1323. rb_numDebugText = 0;
  1324. return;
  1325. }
  1326. // copy any text that still needs to be drawn
  1327. num = 0;
  1328. text = rb_debugText;
  1329. for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
  1330. if ( text->lifeTime > time ) {
  1331. if ( num != i ) {
  1332. rb_debugText[ num ] = *text;
  1333. }
  1334. num++;
  1335. }
  1336. }
  1337. rb_numDebugText = num;
  1338. }
  1339. /*
  1340. ================
  1341. RB_AddDebugText
  1342. ================
  1343. */
  1344. void RB_AddDebugText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ) {
  1345. debugText_t *debugText;
  1346. if ( rb_numDebugText < MAX_DEBUG_TEXT ) {
  1347. debugText = &rb_debugText[ rb_numDebugText++ ];
  1348. debugText->text = text;
  1349. debugText->origin = origin;
  1350. debugText->scale = scale;
  1351. debugText->color = color;
  1352. debugText->viewAxis = viewAxis;
  1353. debugText->align = align;
  1354. debugText->lifeTime = rb_debugTextTime + lifetime;
  1355. debugText->depthTest = depthTest;
  1356. }
  1357. }
  1358. /*
  1359. ================
  1360. RB_DrawTextLength
  1361. returns the length of the given text
  1362. ================
  1363. */
  1364. float RB_DrawTextLength( const char *text, float scale, int len ) {
  1365. int i, num, index, charIndex;
  1366. float spacing, textLen = 0.0f;
  1367. if ( text && *text ) {
  1368. if ( !len ) {
  1369. len = strlen(text);
  1370. }
  1371. for ( i = 0; i < len; i++ ) {
  1372. charIndex = text[i] - 32;
  1373. if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) {
  1374. continue;
  1375. }
  1376. num = simplex[charIndex][0] * 2;
  1377. spacing = simplex[charIndex][1];
  1378. index = 2;
  1379. while( index - 2 < num ) {
  1380. if ( simplex[charIndex][index] < 0) {
  1381. index++;
  1382. continue;
  1383. }
  1384. index += 2;
  1385. if ( simplex[charIndex][index] < 0) {
  1386. index++;
  1387. continue;
  1388. }
  1389. }
  1390. textLen += spacing * scale;
  1391. }
  1392. }
  1393. return textLen;
  1394. }
  1395. /*
  1396. ================
  1397. RB_DrawText
  1398. oriented on the viewaxis
  1399. align can be 0-left, 1-center (default), 2-right
  1400. ================
  1401. */
  1402. static void RB_DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align ) {
  1403. int i, j, len, num, index, charIndex, line;
  1404. float textLen, spacing;
  1405. idVec3 org, p1, p2;
  1406. if ( text && *text ) {
  1407. qglBegin( GL_LINES );
  1408. qglColor3fv( color.ToFloatPtr() );
  1409. if ( text[0] == '\n' ) {
  1410. line = 1;
  1411. } else {
  1412. line = 0;
  1413. }
  1414. len = strlen( text );
  1415. for ( i = 0; i < len; i++ ) {
  1416. if ( i == 0 || text[i] == '\n' ) {
  1417. org = origin - viewAxis[2] * ( line * 36.0f * scale );
  1418. if ( align != 0 ) {
  1419. for ( j = 1; i+j <= len; j++ ) {
  1420. if ( i+j == len || text[i+j] == '\n' ) {
  1421. textLen = RB_DrawTextLength( text+i, scale, j );
  1422. break;
  1423. }
  1424. }
  1425. if ( align == 2 ) {
  1426. // right
  1427. org += viewAxis[1] * textLen;
  1428. } else {
  1429. // center
  1430. org += viewAxis[1] * ( textLen * 0.5f );
  1431. }
  1432. }
  1433. line++;
  1434. }
  1435. charIndex = text[i] - 32;
  1436. if ( charIndex < 0 || charIndex > NUM_SIMPLEX_CHARS ) {
  1437. continue;
  1438. }
  1439. num = simplex[charIndex][0] * 2;
  1440. spacing = simplex[charIndex][1];
  1441. index = 2;
  1442. while( index - 2 < num ) {
  1443. if ( simplex[charIndex][index] < 0) {
  1444. index++;
  1445. continue;
  1446. }
  1447. p1 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2];
  1448. index += 2;
  1449. if ( simplex[charIndex][index] < 0) {
  1450. index++;
  1451. continue;
  1452. }
  1453. p2 = org + scale * simplex[charIndex][index] * -viewAxis[1] + scale * simplex[charIndex][index+1] * viewAxis[2];
  1454. qglVertex3fv( p1.ToFloatPtr() );
  1455. qglVertex3fv( p2.ToFloatPtr() );
  1456. }
  1457. org -= viewAxis[1] * ( spacing * scale );
  1458. }
  1459. qglEnd();
  1460. }
  1461. }
  1462. /*
  1463. ================
  1464. RB_ShowDebugText
  1465. ================
  1466. */
  1467. void RB_ShowDebugText( void ) {
  1468. int i;
  1469. int width;
  1470. debugText_t *text;
  1471. if ( !rb_numDebugText ) {
  1472. return;
  1473. }
  1474. // all lines are expressed in world coordinates
  1475. RB_SimpleWorldSetup();
  1476. globalImages->BindNull();
  1477. width = r_debugLineWidth.GetInteger();
  1478. if ( width < 1 ) {
  1479. width = 1;
  1480. } else if ( width > 10 ) {
  1481. width = 10;
  1482. }
  1483. // draw lines
  1484. GL_State( GLS_POLYMODE_LINE );
  1485. qglLineWidth( width );
  1486. if ( !r_debugLineDepthTest.GetBool() ) {
  1487. qglDisable( GL_DEPTH_TEST );
  1488. }
  1489. text = rb_debugText;
  1490. for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
  1491. if ( !text->depthTest ) {
  1492. RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align );
  1493. }
  1494. }
  1495. if ( !r_debugLineDepthTest.GetBool() ) {
  1496. qglEnable( GL_DEPTH_TEST );
  1497. }
  1498. text = rb_debugText;
  1499. for ( i = 0 ; i < rb_numDebugText; i++, text++ ) {
  1500. if ( text->depthTest ) {
  1501. RB_DrawText( text->text, text->origin, text->scale, text->color, text->viewAxis, text->align );
  1502. }
  1503. }
  1504. qglLineWidth( 1 );
  1505. GL_State( GLS_DEFAULT );
  1506. }
  1507. /*
  1508. ================
  1509. RB_ClearDebugLines
  1510. ================
  1511. */
  1512. void RB_ClearDebugLines( int time ) {
  1513. int i;
  1514. int num;
  1515. debugLine_t *line;
  1516. rb_debugLineTime = time;
  1517. if ( !time ) {
  1518. rb_numDebugLines = 0;
  1519. return;
  1520. }
  1521. // copy any lines that still need to be drawn
  1522. num = 0;
  1523. line = rb_debugLines;
  1524. for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
  1525. if ( line->lifeTime > time ) {
  1526. if ( num != i ) {
  1527. rb_debugLines[ num ] = *line;
  1528. }
  1529. num++;
  1530. }
  1531. }
  1532. rb_numDebugLines = num;
  1533. }
  1534. /*
  1535. ================
  1536. RB_AddDebugLine
  1537. ================
  1538. */
  1539. void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest ) {
  1540. debugLine_t *line;
  1541. if ( rb_numDebugLines < MAX_DEBUG_LINES ) {
  1542. line = &rb_debugLines[ rb_numDebugLines++ ];
  1543. line->rgb = color;
  1544. line->start = start;
  1545. line->end = end;
  1546. line->depthTest = depthTest;
  1547. line->lifeTime = rb_debugLineTime + lifeTime;
  1548. }
  1549. }
  1550. /*
  1551. ================
  1552. RB_ShowDebugLines
  1553. ================
  1554. */
  1555. void RB_ShowDebugLines( void ) {
  1556. int i;
  1557. int width;
  1558. debugLine_t *line;
  1559. if ( !rb_numDebugLines ) {
  1560. return;
  1561. }
  1562. // all lines are expressed in world coordinates
  1563. RB_SimpleWorldSetup();
  1564. globalImages->BindNull();
  1565. width = r_debugLineWidth.GetInteger();
  1566. if ( width < 1 ) {
  1567. width = 1;
  1568. } else if ( width > 10 ) {
  1569. width = 10;
  1570. }
  1571. // draw lines
  1572. GL_State( GLS_POLYMODE_LINE );//| GLS_DEPTHMASK ); //| GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
  1573. qglLineWidth( width );
  1574. if ( !r_debugLineDepthTest.GetBool() ) {
  1575. qglDisable( GL_DEPTH_TEST );
  1576. }
  1577. qglBegin( GL_LINES );
  1578. line = rb_debugLines;
  1579. for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
  1580. if ( !line->depthTest ) {
  1581. qglColor3fv( line->rgb.ToFloatPtr() );
  1582. qglVertex3fv( line->start.ToFloatPtr() );
  1583. qglVertex3fv( line->end.ToFloatPtr() );
  1584. }
  1585. }
  1586. qglEnd();
  1587. if ( !r_debugLineDepthTest.GetBool() ) {
  1588. qglEnable( GL_DEPTH_TEST );
  1589. }
  1590. qglBegin( GL_LINES );
  1591. line = rb_debugLines;
  1592. for ( i = 0 ; i < rb_numDebugLines; i++, line++ ) {
  1593. if ( line->depthTest ) {
  1594. qglColor4fv( line->rgb.ToFloatPtr() );
  1595. qglVertex3fv( line->start.ToFloatPtr() );
  1596. qglVertex3fv( line->end.ToFloatPtr() );
  1597. }
  1598. }
  1599. qglEnd();
  1600. qglLineWidth( 1 );
  1601. GL_State( GLS_DEFAULT );
  1602. }
  1603. /*
  1604. ================
  1605. RB_ClearDebugPolygons
  1606. ================
  1607. */
  1608. void RB_ClearDebugPolygons( int time ) {
  1609. int i;
  1610. int num;
  1611. debugPolygon_t *poly;
  1612. rb_debugPolygonTime = time;
  1613. if ( !time ) {
  1614. rb_numDebugPolygons = 0;
  1615. return;
  1616. }
  1617. // copy any polygons that still need to be drawn
  1618. num = 0;
  1619. poly = rb_debugPolygons;
  1620. for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) {
  1621. if ( poly->lifeTime > time ) {
  1622. if ( num != i ) {
  1623. rb_debugPolygons[ num ] = *poly;
  1624. }
  1625. num++;
  1626. }
  1627. }
  1628. rb_numDebugPolygons = num;
  1629. }
  1630. /*
  1631. ================
  1632. RB_AddDebugPolygon
  1633. ================
  1634. */
  1635. void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ) {
  1636. debugPolygon_t *poly;
  1637. if ( rb_numDebugPolygons < MAX_DEBUG_POLYGONS ) {
  1638. poly = &rb_debugPolygons[ rb_numDebugPolygons++ ];
  1639. poly->rgb = color;
  1640. poly->winding = winding;
  1641. poly->depthTest = depthTest;
  1642. poly->lifeTime = rb_debugPolygonTime + lifeTime;
  1643. }
  1644. }
  1645. /*
  1646. ================
  1647. RB_ShowDebugPolygons
  1648. ================
  1649. */
  1650. void RB_ShowDebugPolygons( void ) {
  1651. int i, j;
  1652. debugPolygon_t *poly;
  1653. if ( !rb_numDebugPolygons ) {
  1654. return;
  1655. }
  1656. // all lines are expressed in world coordinates
  1657. RB_SimpleWorldSetup();
  1658. globalImages->BindNull();
  1659. qglDisable( GL_TEXTURE_2D );
  1660. qglDisable( GL_STENCIL_TEST );
  1661. qglEnable( GL_DEPTH_TEST );
  1662. if ( r_debugPolygonFilled.GetBool() ) {
  1663. GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK );
  1664. qglPolygonOffset( -1, -2 );
  1665. qglEnable( GL_POLYGON_OFFSET_FILL );
  1666. } else {
  1667. GL_State( GLS_POLYMODE_LINE );
  1668. qglPolygonOffset( -1, -2 );
  1669. qglEnable( GL_POLYGON_OFFSET_LINE );
  1670. }
  1671. poly = rb_debugPolygons;
  1672. for ( i = 0 ; i < rb_numDebugPolygons; i++, poly++ ) {
  1673. // if ( !poly->depthTest ) {
  1674. qglColor4fv( poly->rgb.ToFloatPtr() );
  1675. qglBegin( GL_POLYGON );
  1676. for ( j = 0; j < poly->winding.GetNumPoints(); j++) {
  1677. qglVertex3fv( poly->winding[j].ToFloatPtr() );
  1678. }
  1679. qglEnd();
  1680. // }
  1681. }
  1682. GL_State( GLS_DEFAULT );
  1683. if ( r_debugPolygonFilled.GetBool() ) {
  1684. qglDisable( GL_POLYGON_OFFSET_FILL );
  1685. } else {
  1686. qglDisable( GL_POLYGON_OFFSET_LINE );
  1687. }
  1688. qglDepthRange( 0, 1 );
  1689. GL_State( GLS_DEFAULT );
  1690. }
  1691. /*
  1692. ================
  1693. RB_TestGamma
  1694. ================
  1695. */
  1696. #define G_WIDTH 512
  1697. #define G_HEIGHT 512
  1698. #define BAR_HEIGHT 64
  1699. void RB_TestGamma( void ) {
  1700. byte image[G_HEIGHT][G_WIDTH][4];
  1701. int i, j;
  1702. int c, comp;
  1703. int v, dither;
  1704. int mask, y;
  1705. if ( r_testGamma.GetInteger() <= 0 ) {
  1706. return;
  1707. }
  1708. v = r_testGamma.GetInteger();
  1709. if ( v <= 1 || v >= 196 ) {
  1710. v = 128;
  1711. }
  1712. memset( image, 0, sizeof( image ) );
  1713. for ( mask = 0 ; mask < 8 ; mask++ ) {
  1714. y = mask * BAR_HEIGHT;
  1715. for ( c = 0 ; c < 4 ; c++ ) {
  1716. v = c * 64 + 32;
  1717. // solid color
  1718. for ( i = 0 ; i < BAR_HEIGHT/2 ; i++ ) {
  1719. for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
  1720. for ( comp = 0 ; comp < 3 ; comp++ ) {
  1721. if ( mask & ( 1 << comp ) ) {
  1722. image[y+i][c*G_WIDTH/4+j][comp] = v;
  1723. }
  1724. }
  1725. }
  1726. // dithered color
  1727. for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
  1728. if ( ( i ^ j ) & 1 ) {
  1729. dither = c * 64;
  1730. } else {
  1731. dither = c * 64 + 63;
  1732. }
  1733. for ( comp = 0 ; comp < 3 ; comp++ ) {
  1734. if ( mask & ( 1 << comp ) ) {
  1735. image[y+BAR_HEIGHT/2+i][c*G_WIDTH/4+j][comp] = dither;
  1736. }
  1737. }
  1738. }
  1739. }
  1740. }
  1741. }
  1742. // draw geometrically increasing steps in the bottom row
  1743. y = 0 * BAR_HEIGHT;
  1744. float scale = 1;
  1745. for ( c = 0 ; c < 4 ; c++ ) {
  1746. v = (int)(64 * scale);
  1747. if ( v < 0 ) {
  1748. v = 0;
  1749. } else if ( v > 255 ) {
  1750. v = 255;
  1751. }
  1752. scale = scale * 1.5;
  1753. for ( i = 0 ; i < BAR_HEIGHT ; i++ ) {
  1754. for ( j = 0 ; j < G_WIDTH/4 ; j++ ) {
  1755. image[y+i][c*G_WIDTH/4+j][0] = v;
  1756. image[y+i][c*G_WIDTH/4+j][1] = v;
  1757. image[y+i][c*G_WIDTH/4+j][2] = v;
  1758. }
  1759. }
  1760. }
  1761. qglLoadIdentity();
  1762. qglMatrixMode( GL_PROJECTION );
  1763. GL_State( GLS_DEPTHFUNC_ALWAYS );
  1764. qglColor3f( 1, 1, 1 );
  1765. qglPushMatrix();
  1766. qglLoadIdentity();
  1767. qglDisable( GL_TEXTURE_2D );
  1768. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1769. qglRasterPos2f( 0.01f, 0.01f );
  1770. qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image );
  1771. qglPopMatrix();
  1772. qglEnable( GL_TEXTURE_2D );
  1773. qglMatrixMode( GL_MODELVIEW );
  1774. }
  1775. /*
  1776. ==================
  1777. RB_TestGammaBias
  1778. ==================
  1779. */
  1780. static void RB_TestGammaBias( void ) {
  1781. byte image[G_HEIGHT][G_WIDTH][4];
  1782. if ( r_testGammaBias.GetInteger() <= 0 ) {
  1783. return;
  1784. }
  1785. int y = 0;
  1786. for ( int bias = -40 ; bias < 40 ; bias+=10, y += BAR_HEIGHT ) {
  1787. float scale = 1;
  1788. for ( int c = 0 ; c < 4 ; c++ ) {
  1789. int v = (int)(64 * scale + bias);
  1790. scale = scale * 1.5;
  1791. if ( v < 0 ) {
  1792. v = 0;
  1793. } else if ( v > 255 ) {
  1794. v = 255;
  1795. }
  1796. for ( int i = 0 ; i < BAR_HEIGHT ; i++ ) {
  1797. for ( int j = 0 ; j < G_WIDTH/4 ; j++ ) {
  1798. image[y+i][c*G_WIDTH/4+j][0] = v;
  1799. image[y+i][c*G_WIDTH/4+j][1] = v;
  1800. image[y+i][c*G_WIDTH/4+j][2] = v;
  1801. }
  1802. }
  1803. }
  1804. }
  1805. qglLoadIdentity();
  1806. qglMatrixMode( GL_PROJECTION );
  1807. GL_State( GLS_DEPTHFUNC_ALWAYS );
  1808. qglColor3f( 1, 1, 1 );
  1809. qglPushMatrix();
  1810. qglLoadIdentity();
  1811. qglDisable( GL_TEXTURE_2D );
  1812. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1813. qglRasterPos2f( 0.01f, 0.01f );
  1814. qglDrawPixels( G_WIDTH, G_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, image );
  1815. qglPopMatrix();
  1816. qglEnable( GL_TEXTURE_2D );
  1817. qglMatrixMode( GL_MODELVIEW );
  1818. }
  1819. /*
  1820. ================
  1821. RB_TestImage
  1822. Display a single image over most of the screen
  1823. ================
  1824. */
  1825. void RB_TestImage( void ) {
  1826. idImage *image;
  1827. int max;
  1828. float w, h;
  1829. image = tr.testImage;
  1830. if ( !image ) {
  1831. return;
  1832. }
  1833. if ( tr.testVideo ) {
  1834. cinData_t cin;
  1835. cin = tr.testVideo->ImageForTime( (int)(1000 * ( backEnd.viewDef->floatTime - tr.testVideoStartTime ) ) );
  1836. if ( cin.image ) {
  1837. image->UploadScratch( cin.image, cin.imageWidth, cin.imageHeight );
  1838. } else {
  1839. tr.testImage = NULL;
  1840. return;
  1841. }
  1842. w = 0.25;
  1843. h = 0.25;
  1844. } else {
  1845. max = image->uploadWidth > image->uploadHeight ? image->uploadWidth : image->uploadHeight;
  1846. w = 0.25 * image->uploadWidth / max;
  1847. h = 0.25 * image->uploadHeight / max;
  1848. w *= (float)glConfig.vidHeight / glConfig.vidWidth;
  1849. }
  1850. qglLoadIdentity();
  1851. qglMatrixMode( GL_PROJECTION );
  1852. GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
  1853. qglColor3f( 1, 1, 1 );
  1854. qglPushMatrix();
  1855. qglLoadIdentity();
  1856. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1857. tr.testImage->Bind();
  1858. qglBegin( GL_QUADS );
  1859. qglTexCoord2f( 0, 1 );
  1860. qglVertex2f( 0.5 - w, 0 );
  1861. qglTexCoord2f( 0, 0 );
  1862. qglVertex2f( 0.5 - w, h*2 );
  1863. qglTexCoord2f( 1, 0 );
  1864. qglVertex2f( 0.5 + w, h*2 );
  1865. qglTexCoord2f( 1, 1 );
  1866. qglVertex2f( 0.5 + w, 0 );
  1867. qglEnd();
  1868. qglPopMatrix();
  1869. qglMatrixMode( GL_MODELVIEW );
  1870. }
  1871. /*
  1872. =================
  1873. RB_RenderDebugTools
  1874. =================
  1875. */
  1876. void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs ) {
  1877. // don't do anything if this was a 2D rendering
  1878. if ( !backEnd.viewDef->viewEntitys ) {
  1879. return;
  1880. }
  1881. RB_LogComment( "---------- RB_RenderDebugTools ----------\n" );
  1882. GL_State( GLS_DEFAULT );
  1883. backEnd.currentScissor = backEnd.viewDef->scissor;
  1884. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  1885. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  1886. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  1887. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  1888. RB_ShowLightCount();
  1889. RB_ShowShadowCount();
  1890. RB_ShowTexturePolarity( drawSurfs, numDrawSurfs );
  1891. RB_ShowTangentSpace( drawSurfs, numDrawSurfs );
  1892. RB_ShowVertexColor( drawSurfs, numDrawSurfs );
  1893. RB_ShowTris( drawSurfs, numDrawSurfs );
  1894. RB_ShowUnsmoothedTangents( drawSurfs, numDrawSurfs );
  1895. RB_ShowSurfaceInfo( drawSurfs, numDrawSurfs );
  1896. RB_ShowEdges( drawSurfs, numDrawSurfs );
  1897. RB_ShowNormals( drawSurfs, numDrawSurfs );
  1898. RB_ShowViewEntitys( backEnd.viewDef->viewEntitys );
  1899. RB_ShowLights();
  1900. RB_ShowTextureVectors( drawSurfs, numDrawSurfs );
  1901. RB_ShowDominantTris( drawSurfs, numDrawSurfs );
  1902. if ( r_testGamma.GetInteger() > 0 ) { // test here so stack check isn't so damn slow on debug builds
  1903. RB_TestGamma();
  1904. }
  1905. if ( r_testGammaBias.GetInteger() > 0 ) {
  1906. RB_TestGammaBias();
  1907. }
  1908. RB_TestImage();
  1909. RB_ShowPortals();
  1910. RB_ShowSilhouette();
  1911. RB_ShowDepthBuffer();
  1912. RB_ShowIntensity();
  1913. RB_ShowDebugLines();
  1914. RB_ShowDebugText();
  1915. RB_ShowDebugPolygons();
  1916. RB_ShowTrace( drawSurfs, numDrawSurfs );
  1917. }
  1918. /*
  1919. =================
  1920. RB_ShutdownDebugTools
  1921. =================
  1922. */
  1923. void RB_ShutdownDebugTools( void ) {
  1924. for ( int i = 0; i < MAX_DEBUG_POLYGONS; i++ ) {
  1925. rb_debugPolygons[i].winding.Clear();
  1926. }
  1927. }