tr_backend_rendertools.cpp 63 KB

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