draw_exp.cpp 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619
  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 "../sys/win32/win_local.h"
  24. /*
  25. strictly experimental / research codepaths
  26. !!!if we use front facing occluders, we can portal flow from light centers
  27. try depth_component_16 rendering
  28. do we care about portals from light perspective? back / front face issues.
  29. how do we do weapon depth hacks with shadow buffers?
  30. distort their world space vertexes instead of offsetting their depth?
  31. jittering off the side of a projection will give wrong shadows
  32. really huge lights, like sunlight, are going to be problematic with fixed projections
  33. we could tile the projections and let the auto-resize cut them down as necessary
  34. It sucks that depth buffers are non-linear, because the bias and compares change with distance
  35. polygon offset factor causes occasional texture holes from highly angled textures
  36. */
  37. static bool initialized;
  38. static int lightBufferSize = 1024;
  39. static int maxLightBufferSize = 1024;
  40. static float lightBufferSizeFraction = 0.5;
  41. static int viewBufferSize = 1024;
  42. static int viewBufferHeight = 768;
  43. static int maxViewBufferSize = 1024;
  44. static float viewBufferSizeFraction = 0.5;
  45. static float viewBufferHeightFraction = 0.5;
  46. static bool nativeViewBuffer = false; // true if viewBufferSize is the viewport width
  47. static HPBUFFERARB floatPbuffer;
  48. static HDC floatPbufferDC;
  49. static idImage *floatPbufferImage;
  50. static HPBUFFERARB floatPbuffer2;
  51. static HDC floatPbuffer2DC;
  52. static idImage *floatPbuffer2Image;
  53. static HPBUFFERARB floatPbufferQuarter;
  54. static HDC floatPbufferQuarterDC;
  55. static idImage *floatPbufferQuarterImage;
  56. static HGLRC floatContext;
  57. static HPBUFFERARB shadowPbuffer;
  58. static HDC shadowPbufferDC;
  59. static HPBUFFERARB viewPbuffer;
  60. static HDC viewPbufferDC;
  61. static idImage *shadowImage[3];
  62. static idImage *viewDepthImage;
  63. static idImage *viewAlphaImage;
  64. static idImage *viewShadowImage;
  65. static idImage *jitterImage16;
  66. static idImage *jitterImage4;
  67. static idImage *jitterImage1;
  68. static idImage *random256Image;
  69. static int shadowVertexProgram;
  70. static int shadowFragmentProgram16;
  71. static int shadowFragmentProgram4;
  72. static int shadowFragmentProgram1;
  73. static int shadowFragmentProgram0;
  74. static int screenSpaceShadowVertexProgram;
  75. static int screenSpaceShadowFragmentProgram16;
  76. static int screenSpaceShadowFragmentProgram4;
  77. static int screenSpaceShadowFragmentProgram1;
  78. static int screenSpaceShadowFragmentProgram0;
  79. static int depthMidpointVertexProgram;
  80. static int depthMidpointFragmentProgram;
  81. static int shadowResampleVertexProgram;
  82. static int shadowResampleFragmentProgram;
  83. static int gammaDitherVertexProgram;
  84. static int gammaDitherFragmentProgram;
  85. static int downSampleVertexProgram;
  86. static int downSampleFragmentProgram;
  87. static int bloomVertexProgram;
  88. static int bloomFragmentProgram;
  89. static float viewLightAxialSize;
  90. idCVar r_sb_lightResolution( "r_sb_lightResolution", "1024", CVAR_RENDERER | CVAR_INTEGER, "Pixel dimensions for each shadow buffer, 64 - 2048" );
  91. idCVar r_sb_viewResolution( "r_sb_viewResolution", "1024", CVAR_RENDERER | CVAR_INTEGER, "Width of screen space shadow sampling" );
  92. idCVar r_sb_noShadows( "r_sb_noShadows", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw any occluders" );
  93. idCVar r_sb_usePbuffer( "r_sb_usePbuffer", "1", CVAR_RENDERER | CVAR_BOOL, "draw offscreen" );
  94. idCVar r_sb_jitterScale( "r_sb_jitterScale", "0.006", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter offset" );
  95. idCVar r_sb_biasScale( "r_sb_biasScale", "0.0001", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter bias" );
  96. idCVar r_sb_samples( "r_sb_samples", "4", CVAR_RENDERER | CVAR_INTEGER, "0, 1, 4, or 16" );
  97. idCVar r_sb_randomize( "r_sb_randomize", "1", CVAR_RENDERER | CVAR_BOOL, "randomly offset jitter texture each draw" );
  98. // polyOfsFactor causes holes in low res images
  99. idCVar r_sb_polyOfsFactor( "r_sb_polyOfsFactor", "2", CVAR_RENDERER | CVAR_FLOAT, "polygonOffset factor for drawing shadow buffer" );
  100. idCVar r_sb_polyOfsUnits( "r_sb_polyOfsUnits", "3000", CVAR_RENDERER | CVAR_FLOAT, "polygonOffset units for drawing shadow buffer" );
  101. idCVar r_sb_occluderFacing( "r_sb_occluderFacing", "0", CVAR_RENDERER | CVAR_INTEGER, "0 = front faces, 1 = back faces, 2 = midway between" );
  102. // r_sb_randomizeBufferOrientation?
  103. idCVar r_sb_frustomFOV( "r_sb_frustomFOV", "92", CVAR_RENDERER | CVAR_FLOAT, "oversize FOV for point light side matching" );
  104. idCVar r_sb_showFrustumPixels( "r_sb_showFrustumPixels", "0", CVAR_RENDERER | CVAR_BOOL, "color the pixels contained in the frustum" );
  105. idCVar r_sb_singleSide( "r_sb_singleSide", "-1", CVAR_RENDERER | CVAR_INTEGER, "only draw a single side (0-5) of point lights" );
  106. idCVar r_sb_useCulling( "r_sb_useCulling", "1", CVAR_RENDERER | CVAR_BOOL, "cull geometry to individual side frustums" );
  107. idCVar r_sb_linearFilter( "r_sb_linearFilter", "1", CVAR_RENDERER | CVAR_BOOL, "use GL_LINEAR instead of GL_NEAREST on shadow maps" );
  108. idCVar r_sb_screenSpaceShadow( "r_sb_screenSpaceShadow", "1", CVAR_RENDERER | CVAR_BOOL, "build shadows in screen space instead of on surfaces" );
  109. idCVar r_hdr_useFloats( "r_hdr_useFloats", "0", CVAR_RENDERER | CVAR_BOOL, "use a floating point rendering buffer" );
  110. idCVar r_hdr_exposure( "r_hdr_exposure", "1.0", CVAR_RENDERER | CVAR_FLOAT, "maximum light scale" );
  111. idCVar r_hdr_bloomFraction( "r_hdr_bloomFraction", "0.1", CVAR_RENDERER | CVAR_FLOAT, "fraction to smear across neighbors" );
  112. idCVar r_hdr_gamma( "r_hdr_gamma", "1", CVAR_RENDERER | CVAR_FLOAT, "monitor gamma power" );
  113. idCVar r_hdr_monitorDither( "r_hdr_monitorDither", "0.01", CVAR_RENDERER | CVAR_FLOAT, "random dither in monitor space" );
  114. // from world space to light origin, looking down the X axis
  115. static float unflippedLightMatrix[16];
  116. // from world space to OpenGL view space, looking down the negative Z axis
  117. static float lightMatrix[16];
  118. // from OpenGL view space to OpenGL NDC ( -1 : 1 in XYZ )
  119. static float lightProjectionMatrix[16];
  120. void RB_ARB2_DrawInteraction( const drawInteraction_t *din );
  121. typedef struct {
  122. const char *name;
  123. int num;
  124. } wglString_t;
  125. wglString_t wglString[] = {
  126. { "WGL_NUMBER_PIXEL_FORMATS_ARB", 0x2000 },
  127. { "WGL_DRAW_TO_WINDOW_ARB", 0x2001 },
  128. { "WGL_DRAW_TO_BITMAP_ARB", 0x2002 },
  129. { "WGL_ACCELERATION_ARB", 0x2003 },
  130. { "WGL_NEED_PALETTE_ARB", 0x2004 },
  131. { "WGL_NEED_SYSTEM_PALETTE_ARB", 0x2005 },
  132. { "WGL_SWAP_LAYER_BUFFERS_ARB", 0x2006 },
  133. { "WGL_SWAP_METHOD_ARB", 0x2007 },
  134. { "WGL_NUMBER_OVERLAYS_ARB", 0x2008 },
  135. { "WGL_NUMBER_UNDERLAYS_ARB", 0x2009 },
  136. { "WGL_TRANSPARENT_ARB", 0x200A },
  137. { "WGL_TRANSPARENT_RED_VALUE_ARB", 0x2037 },
  138. { "WGL_TRANSPARENT_GREEN_VALUE_ARB", 0x2038 },
  139. { "WGL_TRANSPARENT_BLUE_VALUE_ARB", 0x2039 },
  140. { "WGL_TRANSPARENT_ALPHA_VALUE_ARB", 0x203A },
  141. { "WGL_TRANSPARENT_INDEX_VALUE_ARB", 0x203B },
  142. { "WGL_SHARE_DEPTH_ARB", 0x200C },
  143. { "WGL_SHARE_STENCIL_ARB", 0x200D },
  144. { "WGL_SHARE_ACCUM_ARB", 0x200E },
  145. { "WGL_SUPPORT_GDI_ARB", 0x200F },
  146. { "WGL_SUPPORT_OPENGL_ARB", 0x2010 },
  147. { "WGL_DOUBLE_BUFFER_ARB", 0x2011 },
  148. { "WGL_STEREO_ARB", 0x2012 },
  149. { "WGL_PIXEL_TYPE_ARB", 0x2013 },
  150. { "WGL_COLOR_BITS_ARB", 0x2014 },
  151. { "WGL_RED_BITS_ARB", 0x2015 },
  152. { "WGL_RED_SHIFT_ARB", 0x2016 },
  153. { "WGL_GREEN_BITS_ARB", 0x2017 },
  154. { "WGL_GREEN_SHIFT_ARB", 0x2018 },
  155. { "WGL_BLUE_BITS_ARB", 0x2019 },
  156. { "WGL_BLUE_SHIFT_ARB", 0x201A },
  157. { "WGL_ALPHA_BITS_ARB", 0x201B },
  158. { "WGL_ALPHA_SHIFT_ARB", 0x201C },
  159. { "WGL_ACCUM_BITS_ARB", 0x201D },
  160. { "WGL_ACCUM_RED_BITS_ARB", 0x201E },
  161. { "WGL_ACCUM_GREEN_BITS_ARB", 0x201F },
  162. { "WGL_ACCUM_BLUE_BITS_ARB", 0x2020 },
  163. { "WGL_ACCUM_ALPHA_BITS_ARB", 0x2021 },
  164. { "WGL_DEPTH_BITS_ARB", 0x2022 },
  165. { "WGL_STENCIL_BITS_ARB", 0x2023 },
  166. { "WGL_AUX_BUFFERS_ARB", 0x2024 },
  167. { "WGL_NO_ACCELERATION_ARB", 0x2025 },
  168. { "WGL_GENERIC_ACCELERATION_ARB", 0x2026 },
  169. { "WGL_FULL_ACCELERATION_ARB", 0x2027 },
  170. { "WGL_SWAP_EXCHANGE_ARB", 0x2028 },
  171. { "WGL_SWAP_COPY_ARB", 0x2029 },
  172. { "WGL_SWAP_UNDEFINED_ARB", 0x202A },
  173. { "WGL_TYPE_RGBA_ARB", 0x202B },
  174. { "WGL_TYPE_COLORINDEX_ARB", 0x202C },
  175. };
  176. static const int NUM_WGL_STRINGS = sizeof( wglString ) / sizeof( wglString[0] );
  177. static void R_CheckWglErrors( void ) {
  178. int err = GetLastError();
  179. char *name;
  180. #if 0
  181. LPVOID lpMsgBuf;
  182. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  183. NULL,
  184. err,
  185. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  186. (LPTSTR) &lpMsgBuf,
  187. 0,
  188. NULL
  189. );
  190. #endif
  191. err &= 0xffff;
  192. switch ( err ) {
  193. case 13: name = "ERROR_INVALID_DATA"; break;
  194. case 6: name = "ERROR_INVALID_HANDLE"; break;
  195. case 4317: name = "ERROR_INVALID_OPERATION"; break;
  196. default: name = va( "code %i", err ); break;
  197. }
  198. common->Printf( "GetLastError: %s\n", name );
  199. }
  200. static void R_MakeCurrent( HDC dc, HGLRC context, HPBUFFERARB pbuffer ) {
  201. if ( pbuffer ) {
  202. if ( !wglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) {
  203. R_CheckWglErrors();
  204. common->Error( "wglReleaseTexImageARB failed" );
  205. }
  206. }
  207. if ( !qwglMakeCurrent( dc, context ) ) {
  208. R_CheckWglErrors();
  209. common->FatalError( "qwglMakeCurrent failed" );
  210. }
  211. }
  212. static void R_BindTexImage( HPBUFFERARB pbuffer ) {
  213. if ( !wglReleaseTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) {
  214. R_CheckWglErrors();
  215. common->Error( "wglReleaseTexImageARB failed" );
  216. }
  217. if ( !wglBindTexImageARB( pbuffer, WGL_FRONT_LEFT_ARB ) ) {
  218. R_CheckWglErrors();
  219. common->Error( "failed wglBindTexImageARB" );
  220. }
  221. }
  222. static void R_ReportTextureParms( void ) {
  223. int parms[8];
  224. // q glGetTexParameteriv( GL_TEXTURE_RECTANGLE_NV,
  225. qglGetIntegerv( GL_TEXTURE_BINDING_RECTANGLE_NV, parms );
  226. }
  227. /*
  228. ====================
  229. RB_CreateBloomTable
  230. ====================
  231. */
  232. static const int BLOOM_RADIUS = 8;
  233. static void RB_CreateBloomTable( void ) {
  234. float bloom[BLOOM_RADIUS];
  235. float total = 0;
  236. // gaussian
  237. float stdDev = 2.0;
  238. for ( int i = 0 ; i < BLOOM_RADIUS ; i++ ) {
  239. float f = (float)i / stdDev;
  240. bloom[i] = exp( -0.5 * f * f );
  241. total += bloom[i];
  242. }
  243. total = ( total - bloom[0] ) * 2 + bloom[0];
  244. // normalize to 1.0 contribution, so a full row or column will equal 1.0
  245. for ( int i = 0 ; i < BLOOM_RADIUS ; i++ ) {
  246. bloom[i] *= 1.0 / total;
  247. common->Printf( "PARAM bloom%i = { %f };\n", i, bloom[i] );
  248. }
  249. }
  250. /*
  251. ====================
  252. GL_SelectTextureNoClient
  253. ====================
  254. */
  255. static void GL_SelectTextureNoClient( int unit ) {
  256. backEnd.glState.currenttmu = unit;
  257. qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
  258. RB_LogComment( "glActiveTextureARB( %i )\n", unit );
  259. }
  260. /*
  261. ================
  262. R_CreateShadowBufferImage
  263. ================
  264. */
  265. static void R_CreateShadowBufferImage( idImage *image ) {
  266. byte *data = (byte *)Mem_Alloc( lightBufferSize*lightBufferSize );
  267. memset( data, 0, lightBufferSize*lightBufferSize );
  268. image->GenerateImage( (byte *)data, 4, 4,
  269. TF_LINEAR, false, TR_CLAMP_TO_BORDER, TD_HIGH_QUALITY );
  270. // now reset it to a shadow depth image
  271. GL_CheckErrors();
  272. image->uploadWidth = image->uploadHeight = lightBufferSize;
  273. qglTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, lightBufferSize, lightBufferSize,
  274. 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, data );
  275. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE );
  276. // qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  277. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
  278. // explicit zero depth border
  279. float color[4];
  280. color[0] = color[1] = color[2] = color[3] = 0;
  281. qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color );
  282. GL_CheckErrors();
  283. Mem_Free( data );
  284. }
  285. static void R_CreateViewAlphaImage( idImage *image ) {
  286. int c = viewBufferSize*viewBufferSize*4;
  287. byte *data = (byte *)Mem_Alloc( c );
  288. // don't let it pick an intensity format
  289. for ( int i = 0 ; i < c ; i++ ) {
  290. data[i] = i;
  291. }
  292. memset( data, 0, viewBufferSize*viewBufferSize );
  293. image->GenerateImage( (byte *)data, viewBufferSize, viewBufferSize,
  294. TF_LINEAR, false, TR_CLAMP, TD_HIGH_QUALITY );
  295. }
  296. static void R_CreateStubImage( idImage *image ) {
  297. float data[3][4][4];
  298. // generate the texture number
  299. qglGenTextures( 1, &image->texnum );
  300. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, image->texnum );
  301. memset( data, 0, sizeof( data ) );
  302. glTexImage2D( GL_TEXTURE_RECTANGLE_NV, 0, GL_FLOAT_RGBA16_NV, 4, 3, 0, GL_RGBA, GL_FLOAT, &data );
  303. }
  304. /*
  305. ================
  306. R_CreateJitterImage
  307. ================
  308. */
  309. const static int JITTER_SIZE = 128;
  310. static void R_CreateJitterImage16( idImage *image ) {
  311. byte data[JITTER_SIZE][JITTER_SIZE*16][4];
  312. for ( int i = 0 ; i < JITTER_SIZE ; i++ ) {
  313. for ( int s = 0 ; s < 16 ; s++ ) {
  314. int sOfs = 64 * ( s & 3 );
  315. int tOfs = 64 * ( ( s >> 2 ) & 3 );
  316. for ( int j = 0 ; j < JITTER_SIZE ; j++ ) {
  317. data[i][s*JITTER_SIZE+j][0] = (rand() & 63 ) | sOfs;
  318. data[i][s*JITTER_SIZE+j][1] = (rand() & 63 ) | tOfs;
  319. data[i][s*JITTER_SIZE+j][2] = rand();
  320. data[i][s*JITTER_SIZE+j][3] = 0;
  321. }
  322. }
  323. }
  324. image->GenerateImage( (byte *)data, JITTER_SIZE*16, JITTER_SIZE,
  325. TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY );
  326. }
  327. static void R_CreateJitterImage4( idImage *image ) {
  328. byte data[JITTER_SIZE][JITTER_SIZE*4][4];
  329. for ( int i = 0 ; i < JITTER_SIZE ; i++ ) {
  330. for ( int s = 0 ; s < 4 ; s++ ) {
  331. int sOfs = 128 * ( s & 1 );
  332. int tOfs = 128 * ( ( s >> 1 ) & 1 );
  333. for ( int j = 0 ; j < JITTER_SIZE ; j++ ) {
  334. data[i][s*JITTER_SIZE+j][0] = (rand() & 127 ) | sOfs;
  335. data[i][s*JITTER_SIZE+j][1] = (rand() & 127 ) | tOfs;
  336. data[i][s*JITTER_SIZE+j][2] = rand();
  337. data[i][s*JITTER_SIZE+j][3] = 0;
  338. }
  339. }
  340. }
  341. image->GenerateImage( (byte *)data, JITTER_SIZE*4, JITTER_SIZE,
  342. TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY );
  343. }
  344. static void R_CreateJitterImage1( idImage *image ) {
  345. byte data[JITTER_SIZE][JITTER_SIZE][4];
  346. for ( int i = 0 ; i < JITTER_SIZE ; i++ ) {
  347. for ( int j = 0 ; j < JITTER_SIZE ; j++ ) {
  348. data[i][j][0] = rand();
  349. data[i][j][1] = rand();
  350. data[i][j][2] = rand();
  351. data[i][j][3] = 0;
  352. }
  353. }
  354. image->GenerateImage( (byte *)data, JITTER_SIZE, JITTER_SIZE,
  355. TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY );
  356. }
  357. static void R_CreateRandom256Image( idImage *image ) {
  358. byte data[256][256][4];
  359. for ( int i = 0 ; i < 256 ; i++ ) {
  360. for ( int j = 0 ; j < 256 ; j++ ) {
  361. data[i][j][0] = rand();
  362. data[i][j][1] = rand();
  363. data[i][j][2] = rand();
  364. data[i][j][3] = rand();
  365. }
  366. }
  367. image->GenerateImage( (byte *)data, 256, 256,
  368. TF_NEAREST, false, TR_REPEAT, TD_HIGH_QUALITY );
  369. }
  370. /*
  371. ==================
  372. R_PrintPixelFormat
  373. ==================
  374. */
  375. void R_PrintPixelFormat( int pixelFormat ) {
  376. int res;
  377. int iAttribute;
  378. int iValue;
  379. common->Printf( "----- pixelFormat %i -----\n", pixelFormat );
  380. for ( int i = 1 ; i < NUM_WGL_STRINGS ; i++ ) {
  381. iAttribute = wglString[i].num;
  382. res = wglGetPixelFormatAttribivARB( win32.hDC, pixelFormat, 0, 1, &iAttribute, &iValue );
  383. if ( res && iValue ) {
  384. common->Printf( "%s : %i\n", wglString[i].name, iValue );
  385. }
  386. }
  387. }
  388. /*
  389. ==================
  390. R_Exp_Allocate
  391. ==================
  392. */
  393. void R_Exp_Allocate( void ) {
  394. // find a pixel format for our floating point pbuffer
  395. int iAttributes[NUM_WGL_STRINGS*2], *atr_p;
  396. FLOAT fAttributes[] = {0, 0};
  397. UINT numFormats;
  398. int pixelformats[1024];
  399. int ret;
  400. int pbiAttributes[] = {0, 0};
  401. initialized = true;
  402. #if 1
  403. //
  404. // allocate the floating point rendering buffer
  405. //
  406. atr_p = iAttributes;
  407. *atr_p++ = WGL_DRAW_TO_PBUFFER_ARB;
  408. *atr_p++ = TRUE;
  409. *atr_p++ = WGL_FLOAT_COMPONENTS_NV;
  410. *atr_p++ = TRUE;
  411. *atr_p++ = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV;
  412. *atr_p++ = TRUE;
  413. // *atr_p++ = WGL_BIND_TO_TEXTURE_RGBA_ARB;
  414. // *atr_p++ = TRUE;
  415. *atr_p++ = WGL_DEPTH_BITS_ARB;
  416. *atr_p++ = 24;
  417. *atr_p++ = WGL_STENCIL_BITS_ARB;
  418. *atr_p++ = 8;
  419. *atr_p++ = 0;
  420. *atr_p++ = 0;
  421. ret = wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes,
  422. sizeof( pixelformats ) / sizeof( pixelformats[0] ), pixelformats, &numFormats );
  423. #if 0
  424. for ( int i = 0 ; i < (int)numFormats ; i++ ) {
  425. R_PrintPixelFormat( pixelformats[i] );
  426. }
  427. #endif
  428. common->Printf( "\nfloatPbuffer:\n" );
  429. R_PrintPixelFormat( pixelformats[0] );
  430. // allocate a pbuffer with this pixel format
  431. int pbiAttributesTexture[] = {
  432. WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_FLOAT_RGBA_NV,
  433. WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_RECTANGLE_NV, // WGL_TEXTURE_2D_ARB,
  434. 0, 0};
  435. floatPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth,
  436. glConfig.vidHeight, pbiAttributesTexture );
  437. if ( !floatPbuffer ) {
  438. common->Printf( "failed to create floatPbuffer.\n" );
  439. GL_CheckErrors();
  440. }
  441. floatPbufferDC = wglGetPbufferDCARB( floatPbuffer );
  442. floatPbufferImage = globalImages->ImageFromFunction( "_floatPbuffer", R_CreateStubImage );
  443. // create a second buffer for ping-pong operations
  444. floatPbuffer2 = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth,
  445. glConfig.vidHeight, pbiAttributesTexture );
  446. if ( !floatPbuffer2 ) {
  447. common->Printf( "failed to create floatPbuffer.\n" );
  448. GL_CheckErrors();
  449. }
  450. floatPbuffer2DC = wglGetPbufferDCARB( floatPbuffer2 );
  451. floatPbuffer2Image = globalImages->ImageFromFunction( "_floatPbuffer2", R_CreateStubImage );
  452. // create a third buffer for down sampling operations
  453. floatPbufferQuarter = wglCreatePbufferARB( win32.hDC, pixelformats[0], glConfig.vidWidth / 4,
  454. glConfig.vidHeight / 4, pbiAttributesTexture );
  455. if ( !floatPbufferQuarter ) {
  456. common->Printf( "failed to create floatPbuffer.\n" );
  457. GL_CheckErrors();
  458. }
  459. floatPbufferQuarterDC = wglGetPbufferDCARB( floatPbufferQuarter );
  460. floatPbufferQuarterImage = globalImages->ImageFromFunction( "floatPbufferQuarter", R_CreateStubImage );
  461. // create a new GL context for this pixel format and share textures
  462. floatContext = wglCreateContext( floatPbufferDC );
  463. if ( !floatContext ) {
  464. common->Printf( "failed to create context for floatPbufferDC.\n" );
  465. GL_CheckErrors();
  466. }
  467. if ( !wglShareLists( floatContext, win32.hGLRC ) ) {
  468. common->Printf( "failed to share lists.\n" );
  469. }
  470. // create a rendering context for this pixel format and share textures
  471. // allocate a texture for the rendering
  472. #endif
  473. //=================================================================================
  474. //
  475. // allocate the shadow pbuffer
  476. //
  477. atr_p = iAttributes;
  478. *atr_p++ = WGL_DRAW_TO_PBUFFER_ARB;
  479. *atr_p++ = TRUE;
  480. *atr_p++ = WGL_RED_BITS_ARB;
  481. *atr_p++ = 8;
  482. *atr_p++ = WGL_GREEN_BITS_ARB;
  483. *atr_p++ = 8;
  484. *atr_p++ = WGL_BLUE_BITS_ARB;
  485. *atr_p++ = 8;
  486. *atr_p++ = WGL_ALPHA_BITS_ARB;
  487. *atr_p++ = 8;
  488. *atr_p++ = WGL_DEPTH_BITS_ARB;
  489. *atr_p++ = 24;
  490. *atr_p++ = WGL_STENCIL_BITS_ARB;
  491. *atr_p++ = 8;
  492. *atr_p++ = 0;
  493. *atr_p++ = 0;
  494. ret = wglChoosePixelFormatARB( win32.hDC, iAttributes, fAttributes,
  495. sizeof( pixelformats ) / sizeof( pixelformats[0] ), pixelformats, &numFormats );
  496. #if 0
  497. for ( int i = 0 ; i < (int)numFormats ; i++ ) {
  498. R_PrintPixelFormat( pixelformats[i] );
  499. }
  500. #endif
  501. common->Printf( "\nshadowPbuffer:\n" );
  502. R_PrintPixelFormat( pixelformats[0] );
  503. pixelformats[0] = win32.pixelformat; // forced to do this by wgl...
  504. //-----------------------------------
  505. lightBufferSize = maxLightBufferSize;
  506. // allocate a pbuffer with this pixel format
  507. shadowPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], lightBufferSize,
  508. lightBufferSize, pbiAttributes );
  509. // allocate a rendering context for the pbuffer
  510. shadowPbufferDC = wglGetPbufferDCARB( shadowPbuffer );
  511. // generate the texture number
  512. shadowImage[0] = globalImages->ImageFromFunction( va("_shadowBuffer%i_0",lightBufferSize), R_CreateShadowBufferImage );
  513. shadowImage[1] = globalImages->ImageFromFunction( va("_shadowBuffer%i_1",lightBufferSize), R_CreateShadowBufferImage );
  514. shadowImage[2] = globalImages->ImageFromFunction( va("_shadowBuffer%i_2",lightBufferSize), R_CreateShadowBufferImage );
  515. //-----------------------------------
  516. lightBufferSize = maxViewBufferSize;
  517. // allocate a pbuffer with this pixel format
  518. viewPbuffer = wglCreatePbufferARB( win32.hDC, pixelformats[0], maxViewBufferSize,
  519. maxViewBufferSize, pbiAttributes );
  520. // allocate a rendering context for the pbuffer
  521. viewPbufferDC = wglGetPbufferDCARB( viewPbuffer );
  522. // create the image space depth buffer for image-space shadow trnasforms
  523. viewDepthImage = globalImages->ImageFromFunction("_viewDepth", R_CreateShadowBufferImage );
  524. // create the image space shadow alpha buffer for subsampling the shadow calculation
  525. viewAlphaImage = globalImages->ImageFromFunction("_viewAlpha", R_CreateViewAlphaImage );
  526. //-----------------------------------
  527. // generate the jitter image
  528. jitterImage16 = globalImages->ImageFromFunction( "_jitter16", R_CreateJitterImage16 );
  529. jitterImage4 = globalImages->ImageFromFunction( "_jitter4", R_CreateJitterImage4 );
  530. jitterImage1 = globalImages->ImageFromFunction( "_jitter1", R_CreateJitterImage1 );
  531. depthMidpointVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "depthMidpoint.vfp" );
  532. depthMidpointFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "depthMidpoint.vfp" );
  533. shadowResampleVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "shadowResample.vfp" );
  534. shadowResampleFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowResample.vfp" );
  535. screenSpaceShadowVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "screenSpaceShadow1.vfp" );
  536. screenSpaceShadowFragmentProgram0 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow0.vfp" );
  537. screenSpaceShadowFragmentProgram1 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow1.vfp" );
  538. screenSpaceShadowFragmentProgram4 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow4.vfp" );
  539. screenSpaceShadowFragmentProgram16 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "screenSpaceShadow16.vfp" );
  540. shadowVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "shadowBufferInteraction1.vfp" );
  541. shadowFragmentProgram0 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction0.vfp" );
  542. shadowFragmentProgram1 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction1.vfp" );
  543. shadowFragmentProgram4 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction4.vfp" );
  544. shadowFragmentProgram16 = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "shadowBufferInteraction16.vfp" );
  545. gammaDitherVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "gammaDither.vfp" );
  546. gammaDitherFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "gammaDither.vfp" );
  547. downSampleVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "downSample.vfp" );
  548. downSampleFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "downSample.vfp" );
  549. bloomVertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "bloom.vfp" );
  550. bloomFragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "bloom.vfp" );
  551. random256Image = globalImages->ImageFromFunction( "_random256", R_CreateRandom256Image );
  552. }
  553. //===========================================================================================
  554. static const int CULL_RECEIVER = 1; // still draw occluder, but it is out of the view
  555. static const int CULL_OCCLUDER_AND_RECEIVER = 2; // the surface doesn't effect the view at all
  556. /*
  557. ==================
  558. RB_EXP_CullInteractions
  559. Sets surfaceInteraction_t->cullBits
  560. ==================
  561. */
  562. void RB_EXP_CullInteractions( viewLight_t *vLight, idPlane frustumPlanes[6] ) {
  563. for ( idInteraction *inter = vLight->lightDef->firstInteraction ; inter ; inter = inter->lightNext ) {
  564. const idRenderEntityLocal *entityDef = inter->entityDef;
  565. if ( !entityDef ) {
  566. continue;
  567. }
  568. if ( inter->numSurfaces < 1 ) {
  569. continue;
  570. }
  571. int culled = 0;
  572. if ( r_sb_useCulling.GetBool() ) {
  573. // transform light frustum into object space, positive side points outside the light
  574. idPlane localPlanes[6];
  575. int plane;
  576. for ( plane = 0 ; plane < 6 ; plane++ ) {
  577. R_GlobalPlaneToLocal( entityDef->modelMatrix, frustumPlanes[plane], localPlanes[plane] );
  578. }
  579. // cull the entire entity bounding box
  580. // has referenceBounds been tightened to the actual model bounds?
  581. idVec3 corners[8];
  582. for ( int i = 0 ; i < 8 ; i++ ) {
  583. corners[i][0] = entityDef->referenceBounds[i&1][0];
  584. corners[i][1] = entityDef->referenceBounds[(i>>1)&1][1];
  585. corners[i][2] = entityDef->referenceBounds[(i>>2)&1][2];
  586. }
  587. for ( plane = 0 ; plane < 6 ; plane++ ) {
  588. int j;
  589. for ( j = 0 ; j < 8 ; j++ ) {
  590. // if a corner is on the negative side (inside) of the frustum, the surface is not culled
  591. // by this plane
  592. if ( corners[j] * localPlanes[plane].ToVec4().ToVec3() + localPlanes[plane][3] < 0 ) {
  593. break;
  594. }
  595. }
  596. if ( j == 8 ) {
  597. break; // all points outside the light
  598. }
  599. }
  600. if ( plane < 6 ) {
  601. culled = CULL_OCCLUDER_AND_RECEIVER;
  602. }
  603. }
  604. for ( int i = 0 ; i < inter->numSurfaces ; i++ ) {
  605. surfaceInteraction_t *surfInt = &inter->surfaces[i];
  606. if ( !surfInt->ambientTris ) {
  607. continue;
  608. }
  609. surfInt->expCulled = culled;
  610. }
  611. }
  612. }
  613. /*
  614. ==================
  615. RB_EXP_RenderOccluders
  616. ==================
  617. */
  618. void RB_EXP_RenderOccluders( viewLight_t *vLight ) {
  619. for ( idInteraction *inter = vLight->lightDef->firstInteraction ; inter ; inter = inter->lightNext ) {
  620. const idRenderEntityLocal *entityDef = inter->entityDef;
  621. if ( !entityDef ) {
  622. continue;
  623. }
  624. if ( inter->numSurfaces < 1 ) {
  625. continue;
  626. }
  627. // no need to check for current on this, because each interaction is always
  628. // a different space
  629. float matrix[16];
  630. myGlMultMatrix( inter->entityDef->modelMatrix, lightMatrix, matrix );
  631. qglLoadMatrixf( matrix );
  632. // draw each surface
  633. for ( int i = 0 ; i < inter->numSurfaces ; i++ ) {
  634. surfaceInteraction_t *surfInt = &inter->surfaces[i];
  635. if ( !surfInt->ambientTris ) {
  636. continue;
  637. }
  638. if ( surfInt->shader && !surfInt->shader->SurfaceCastsShadow() ) {
  639. continue;
  640. }
  641. // cull it
  642. if ( surfInt->expCulled == CULL_OCCLUDER_AND_RECEIVER ) {
  643. continue;
  644. }
  645. // render it
  646. const srfTriangles_t *tri = surfInt->ambientTris;
  647. if ( !tri->ambientCache ) {
  648. R_CreateAmbientCache( const_cast<srfTriangles_t *>(tri), false );
  649. }
  650. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  651. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  652. qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
  653. if ( surfInt->shader ) {
  654. surfInt->shader->GetEditorImage()->Bind();
  655. }
  656. RB_DrawElementsWithCounters( tri );
  657. }
  658. }
  659. }
  660. /*
  661. ==================
  662. RB_RenderShadowBuffer
  663. ==================
  664. */
  665. void RB_RenderShadowBuffer( viewLight_t *vLight, int side ) {
  666. float xmin, xmax, ymin, ymax;
  667. float width, height;
  668. float zNear;
  669. float fov = r_sb_frustomFOV.GetFloat();
  670. //
  671. // set up 90 degree projection matrix
  672. //
  673. zNear = 4;
  674. ymax = zNear * tan( fov * idMath::PI / 360.0f );
  675. ymin = -ymax;
  676. xmax = zNear * tan( fov * idMath::PI / 360.0f );
  677. xmin = -xmax;
  678. width = xmax - xmin;
  679. height = ymax - ymin;
  680. lightProjectionMatrix[0] = 2 * zNear / width;
  681. lightProjectionMatrix[4] = 0;
  682. lightProjectionMatrix[8] = 0;
  683. lightProjectionMatrix[12] = 0;
  684. lightProjectionMatrix[1] = 0;
  685. lightProjectionMatrix[5] = 2 * zNear / height;
  686. lightProjectionMatrix[9] = 0;
  687. lightProjectionMatrix[13] = 0;
  688. // this is the far-plane-at-infinity formulation, and
  689. // crunches the Z range slightly so w=0 vertexes do not
  690. // rasterize right at the wraparound point
  691. lightProjectionMatrix[2] = 0;
  692. lightProjectionMatrix[6] = 0;
  693. lightProjectionMatrix[10] = -0.999f;
  694. lightProjectionMatrix[14] = -2.0f * zNear;
  695. lightProjectionMatrix[3] = 0;
  696. lightProjectionMatrix[7] = 0;
  697. lightProjectionMatrix[11] = -1;
  698. lightProjectionMatrix[15] = 0;
  699. if ( r_sb_usePbuffer.GetBool() ) {
  700. // set the current openGL drawable to the shadow buffer
  701. R_MakeCurrent( shadowPbufferDC, win32.hGLRC, NULL /* !@# shadowPbuffer */ );
  702. }
  703. qglMatrixMode( GL_PROJECTION );
  704. qglLoadMatrixf( lightProjectionMatrix );
  705. qglMatrixMode( GL_MODELVIEW );
  706. qglViewport( 0, 0, lightBufferSize, lightBufferSize );
  707. qglScissor( 0, 0, lightBufferSize, lightBufferSize );
  708. qglStencilFunc( GL_ALWAYS, 0, 255 );
  709. qglClearColor( 0, 1, 0, 0 );
  710. GL_State( GLS_DEPTHFUNC_LESS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); // make sure depth mask is off before clear
  711. qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  712. // draw all the occluders
  713. qglColor3f( 1, 1, 1 );
  714. GL_SelectTexture( 0 );
  715. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  716. backEnd.currentSpace = NULL;
  717. static float s_flipMatrix[16] = {
  718. // convert from our coordinate system (looking down X)
  719. // to OpenGL's coordinate system (looking down -Z)
  720. 0, 0, -1, 0,
  721. -1, 0, 0, 0,
  722. 0, 1, 0, 0,
  723. 0, 0, 0, 1
  724. };
  725. float viewMatrix[16];
  726. idVec3 vec;
  727. idVec3 origin = vLight->lightDef->globalLightOrigin;
  728. if ( side == -1 ) {
  729. // projected light
  730. vec = vLight->lightDef->parms.target;
  731. vec.Normalize();
  732. viewMatrix[0] = vec[0];
  733. viewMatrix[4] = vec[1];
  734. viewMatrix[8] = vec[2];
  735. vec = vLight->lightDef->parms.right;
  736. vec.Normalize();
  737. viewMatrix[1] = -vec[0];
  738. viewMatrix[5] = -vec[1];
  739. viewMatrix[9] = -vec[2];
  740. vec = vLight->lightDef->parms.up;
  741. vec.Normalize();
  742. viewMatrix[2] = vec[0];
  743. viewMatrix[6] = vec[1];
  744. viewMatrix[10] = vec[2];
  745. } else {
  746. // side of a point light
  747. memset( viewMatrix, 0, sizeof( viewMatrix ) );
  748. switch ( side ) {
  749. case 0:
  750. viewMatrix[0] = 1;
  751. viewMatrix[9] = 1;
  752. viewMatrix[6] = -1;
  753. break;
  754. case 1:
  755. viewMatrix[0] = -1;
  756. viewMatrix[9] = -1;
  757. viewMatrix[6] = -1;
  758. break;
  759. case 2:
  760. viewMatrix[4] = 1;
  761. viewMatrix[1] = -1;
  762. viewMatrix[10] = 1;
  763. break;
  764. case 3:
  765. viewMatrix[4] = -1;
  766. viewMatrix[1] = -1;
  767. viewMatrix[10] = -1;
  768. break;
  769. case 4:
  770. viewMatrix[8] = 1;
  771. viewMatrix[1] = -1;
  772. viewMatrix[6] = -1;
  773. break;
  774. case 5:
  775. viewMatrix[8] = -1;
  776. viewMatrix[1] = 1;
  777. viewMatrix[6] = -1;
  778. break;
  779. }
  780. }
  781. viewMatrix[12] = -origin[0] * viewMatrix[0] + -origin[1] * viewMatrix[4] + -origin[2] * viewMatrix[8];
  782. viewMatrix[13] = -origin[0] * viewMatrix[1] + -origin[1] * viewMatrix[5] + -origin[2] * viewMatrix[9];
  783. viewMatrix[14] = -origin[0] * viewMatrix[2] + -origin[1] * viewMatrix[6] + -origin[2] * viewMatrix[10];
  784. viewMatrix[3] = 0;
  785. viewMatrix[7] = 0;
  786. viewMatrix[11] = 0;
  787. viewMatrix[15] = 1;
  788. memcpy( unflippedLightMatrix, viewMatrix, sizeof( unflippedLightMatrix ) );
  789. myGlMultMatrix( viewMatrix, s_flipMatrix,lightMatrix);
  790. // create frustum planes
  791. idPlane globalFrustum[6];
  792. // near clip
  793. globalFrustum[0][0] = -viewMatrix[0];
  794. globalFrustum[0][1] = -viewMatrix[4];
  795. globalFrustum[0][2] = -viewMatrix[8];
  796. globalFrustum[0][3] = -(origin[0] * globalFrustum[0][0] + origin[1] * globalFrustum[0][1] + origin[2] * globalFrustum[0][2]);
  797. // far clip
  798. globalFrustum[1][0] = viewMatrix[0];
  799. globalFrustum[1][1] = viewMatrix[4];
  800. globalFrustum[1][2] = viewMatrix[8];
  801. globalFrustum[1][3] = -globalFrustum[0][3] - viewLightAxialSize;
  802. // side clips
  803. globalFrustum[2][0] = -viewMatrix[0] + viewMatrix[1];
  804. globalFrustum[2][1] = -viewMatrix[4] + viewMatrix[5];
  805. globalFrustum[2][2] = -viewMatrix[8] + viewMatrix[9];
  806. globalFrustum[3][0] = -viewMatrix[0] - viewMatrix[1];
  807. globalFrustum[3][1] = -viewMatrix[4] - viewMatrix[5];
  808. globalFrustum[3][2] = -viewMatrix[8] - viewMatrix[9];
  809. globalFrustum[4][0] = -viewMatrix[0] + viewMatrix[2];
  810. globalFrustum[4][1] = -viewMatrix[4] + viewMatrix[6];
  811. globalFrustum[4][2] = -viewMatrix[8] + viewMatrix[10];
  812. globalFrustum[5][0] = -viewMatrix[0] - viewMatrix[2];
  813. globalFrustum[5][1] = -viewMatrix[4] - viewMatrix[6];
  814. globalFrustum[5][2] = -viewMatrix[8] - viewMatrix[10];
  815. // is this nromalization necessary?
  816. for ( int i = 0 ; i < 6 ; i++ ) {
  817. globalFrustum[i].ToVec4().ToVec3().Normalize();
  818. }
  819. for ( int i = 2 ; i < 6 ; i++ ) {
  820. globalFrustum[i][3] = - (origin * globalFrustum[i].ToVec4().ToVec3() );
  821. }
  822. RB_EXP_CullInteractions( vLight, globalFrustum );
  823. // FIXME: we want to skip the sampling as well as the generation when not casting shadows
  824. if ( !r_sb_noShadows.GetBool() && vLight->lightShader->LightCastsShadows() ) {
  825. //
  826. // set polygon offset for the rendering
  827. //
  828. switch ( r_sb_occluderFacing.GetInteger() ) {
  829. case 0: // front sides
  830. qglPolygonOffset( r_sb_polyOfsFactor.GetFloat(), r_sb_polyOfsUnits.GetFloat() );
  831. qglEnable( GL_POLYGON_OFFSET_FILL );
  832. RB_EXP_RenderOccluders( vLight );
  833. qglDisable( GL_POLYGON_OFFSET_FILL );
  834. break;
  835. case 1: // back sides
  836. qglPolygonOffset( -r_sb_polyOfsFactor.GetFloat(), -r_sb_polyOfsUnits.GetFloat() );
  837. qglEnable( GL_POLYGON_OFFSET_FILL );
  838. GL_Cull( CT_BACK_SIDED );
  839. RB_EXP_RenderOccluders( vLight );
  840. GL_Cull( CT_FRONT_SIDED );
  841. qglDisable( GL_POLYGON_OFFSET_FILL );
  842. break;
  843. case 2: // both sides
  844. GL_Cull( CT_BACK_SIDED );
  845. RB_EXP_RenderOccluders( vLight );
  846. GL_Cull( CT_FRONT_SIDED );
  847. shadowImage[2]->Bind();
  848. qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize );
  849. RB_EXP_RenderOccluders( vLight );
  850. shadowImage[1]->Bind();
  851. qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize );
  852. // fragment program to combine the two depth images
  853. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, depthMidpointVertexProgram );
  854. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, depthMidpointFragmentProgram );
  855. qglEnable(GL_VERTEX_PROGRAM_ARB);
  856. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  857. GL_SelectTextureNoClient( 1 );
  858. shadowImage[1]->Bind();
  859. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  860. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  861. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  862. GL_SelectTextureNoClient( 0 );
  863. shadowImage[2]->Bind();
  864. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  865. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  866. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  867. // draw a full screen quad
  868. qglMatrixMode( GL_PROJECTION );
  869. qglLoadIdentity();
  870. qglOrtho( 0, 1, 0, 1, -1, 1 );
  871. qglMatrixMode( GL_MODELVIEW );
  872. qglLoadIdentity();
  873. GL_State( GLS_DEPTHFUNC_ALWAYS );
  874. qglBegin( GL_TRIANGLE_FAN );
  875. qglTexCoord2f( 0, 0 );
  876. qglVertex2f( 0, 0 );
  877. qglTexCoord2f( 0, lightBufferSizeFraction );
  878. qglVertex2f( 0, 1 );
  879. qglTexCoord2f( lightBufferSizeFraction, lightBufferSizeFraction );
  880. qglVertex2f( 1, 1 );
  881. qglTexCoord2f( lightBufferSizeFraction, 0 );
  882. qglVertex2f( 1, 0 );
  883. qglEnd();
  884. qglDisable( GL_VERTEX_PROGRAM_ARB );
  885. qglDisable( GL_FRAGMENT_PROGRAM_ARB );
  886. break;
  887. }
  888. }
  889. // copy to the texture
  890. shadowImage[0]->Bind();
  891. qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, lightBufferSize, lightBufferSize );
  892. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  893. // reset the normal view matrix
  894. qglMatrixMode( GL_PROJECTION );
  895. qglLoadMatrixf( backEnd.viewDef->projectionMatrix );
  896. qglMatrixMode( GL_MODELVIEW );
  897. // the current modelView matrix is not valid
  898. backEnd.currentSpace = NULL;
  899. }
  900. /*
  901. ==================
  902. RB_EXP_DrawInteraction
  903. ==================
  904. */
  905. void RB_EXP_DrawInteraction( const drawInteraction_t *din ) {
  906. // load all the vertex program parameters
  907. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() );
  908. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() );
  909. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() );
  910. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() );
  911. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() );
  912. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() );
  913. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
  914. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
  915. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
  916. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
  917. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() );
  918. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() );
  919. // calculate depth projection for shadow buffer
  920. float sRow[4];
  921. float tRow[4];
  922. float rRow[4];
  923. float qRow[4];
  924. float matrix[16];
  925. float matrix2[16];
  926. myGlMultMatrix( din->surf->space->modelMatrix, lightMatrix, matrix );
  927. myGlMultMatrix( matrix, lightProjectionMatrix, matrix2 );
  928. // the final values need to be in 0.0 : 1.0 range instead of -1 : 1
  929. sRow[0] = 0.5 * lightBufferSizeFraction * ( matrix2[0] + matrix2[3] );
  930. sRow[1] = 0.5 * lightBufferSizeFraction * ( matrix2[4] + matrix2[7] );
  931. sRow[2] = 0.5 * lightBufferSizeFraction * ( matrix2[8] + matrix2[11] );
  932. sRow[3] = 0.5 * lightBufferSizeFraction * ( matrix2[12] + matrix2[15] );
  933. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 18, sRow );
  934. tRow[0] = 0.5 * lightBufferSizeFraction * ( matrix2[1] + matrix2[3] );
  935. tRow[1] = 0.5 * lightBufferSizeFraction * ( matrix2[5] + matrix2[7] );
  936. tRow[2] = 0.5 * lightBufferSizeFraction * ( matrix2[9] + matrix2[11] );
  937. tRow[3] = 0.5 * lightBufferSizeFraction * ( matrix2[13] + matrix2[15] );
  938. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 19, tRow );
  939. rRow[0] = 0.5 * ( matrix2[2] + matrix2[3] );
  940. rRow[1] = 0.5 * ( matrix2[6] + matrix2[7] );
  941. rRow[2] = 0.5 * ( matrix2[10] + matrix2[11] );
  942. rRow[3] = 0.5 * ( matrix2[14] + matrix2[15] );
  943. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 20, rRow );
  944. qRow[0] = matrix2[3];
  945. qRow[1] = matrix2[7];
  946. qRow[2] = matrix2[11];
  947. qRow[3] = matrix2[15];
  948. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 21, qRow );
  949. // testing fragment based normal mapping
  950. if ( r_testARBProgram.GetBool() ) {
  951. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr() );
  952. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.ToFloatPtr() );
  953. }
  954. static const float zero[4] = { 0, 0, 0, 0 };
  955. static const float one[4] = { 1, 1, 1, 1 };
  956. static const float negOne[4] = { -1, -1, -1, -1 };
  957. switch ( din->vertexColor ) {
  958. case SVC_IGNORE:
  959. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero );
  960. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
  961. break;
  962. case SVC_MODULATE:
  963. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one );
  964. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero );
  965. break;
  966. case SVC_INVERSE_MODULATE:
  967. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne );
  968. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
  969. break;
  970. }
  971. // set the constant colors
  972. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr() );
  973. qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr() );
  974. //-----------------------------------------------------
  975. // screen power of two correction factor
  976. float parm[4];
  977. parm[0] = 1.0 / ( JITTER_SIZE * r_sb_samples.GetInteger() ) ;
  978. parm[1] = 1.0 / JITTER_SIZE;
  979. parm[2] = 0;
  980. parm[3] = 1;
  981. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm );
  982. // jitter tex scale
  983. parm[0] =
  984. parm[1] = r_sb_jitterScale.GetFloat() * lightBufferSizeFraction;
  985. parm[2] = -r_sb_biasScale.GetFloat();
  986. parm[3] = 0;
  987. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, parm );
  988. // jitter tex offset
  989. if ( r_sb_randomize.GetBool() ) {
  990. parm[0] = (rand()&255) / 255.0;
  991. parm[1] = (rand()&255) / 255.0;
  992. } else {
  993. parm[0] = parm[1] = 0;
  994. }
  995. parm[2] = 0;
  996. parm[3] = 0;
  997. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, parm );
  998. //-----------------------------------------------------
  999. // set the textures
  1000. // texture 1 will be the per-surface bump map
  1001. GL_SelectTextureNoClient( 1 );
  1002. din->bumpImage->Bind();
  1003. // texture 2 will be the light falloff texture
  1004. GL_SelectTextureNoClient( 2 );
  1005. din->lightFalloffImage->Bind();
  1006. // texture 3 will be the light projection texture
  1007. GL_SelectTextureNoClient( 3 );
  1008. din->lightImage->Bind();
  1009. // texture 4 is the per-surface diffuse map
  1010. GL_SelectTextureNoClient( 4 );
  1011. din->diffuseImage->Bind();
  1012. // texture 5 is the per-surface specular map
  1013. GL_SelectTextureNoClient( 5 );
  1014. din->specularImage->Bind();
  1015. // draw it
  1016. RB_DrawElementsWithCounters( din->surf->geo );
  1017. }
  1018. /*
  1019. =============
  1020. RB_EXP_CreateDrawInteractions
  1021. =============
  1022. */
  1023. void RB_EXP_CreateDrawInteractions( const drawSurf_t *surf ) {
  1024. if ( !surf ) {
  1025. return;
  1026. }
  1027. if ( r_sb_screenSpaceShadow.GetBool() ) {
  1028. // perform setup here that will be constant for all interactions
  1029. GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );
  1030. if ( r_testARBProgram.GetBool() ) {
  1031. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST );
  1032. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST );
  1033. } else {
  1034. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION );
  1035. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION );
  1036. }
  1037. } else {
  1038. // perform setup here that will be constant for all interactions
  1039. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );
  1040. GL_State( GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );//!@#
  1041. // bind the vertex program
  1042. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, shadowVertexProgram );
  1043. if ( r_sb_samples.GetInteger() == 16 ) {
  1044. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram16 );
  1045. } else if ( r_sb_samples.GetInteger() == 4 ) {
  1046. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram4 );
  1047. } else if ( r_sb_samples.GetInteger() == 1 ) {
  1048. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram1 );
  1049. } else {
  1050. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowFragmentProgram0 );
  1051. }
  1052. }
  1053. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1054. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1055. // enable the vertex arrays
  1056. qglEnableVertexAttribArrayARB( 8 );
  1057. qglEnableVertexAttribArrayARB( 9 );
  1058. qglEnableVertexAttribArrayARB( 10 );
  1059. qglEnableVertexAttribArrayARB( 11 );
  1060. qglEnableClientState( GL_COLOR_ARRAY );
  1061. // texture 0 is the normalization cube map for the vector towards the light
  1062. GL_SelectTextureNoClient( 0 );
  1063. if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
  1064. globalImages->normalCubeMapImage->Bind();
  1065. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT);
  1066. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT);
  1067. } else {
  1068. globalImages->normalCubeMapImage->Bind();
  1069. }
  1070. // texture 6 is the specular lookup table
  1071. GL_SelectTextureNoClient( 6 );
  1072. if ( r_testARBProgram.GetBool() ) {
  1073. globalImages->specular2DTableImage->Bind(); // variable specularity in alpha channel
  1074. } else {
  1075. globalImages->specularTableImage->Bind();
  1076. }
  1077. for ( ; surf ; surf=surf->nextOnLight ) {
  1078. // perform setup here that will not change over multiple interaction passes
  1079. if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
  1080. float parm[4];
  1081. parm[0] = surf->space->modelMatrix[0];
  1082. parm[1] = surf->space->modelMatrix[4];
  1083. parm[2] = surf->space->modelMatrix[8];
  1084. parm[3] = 0;
  1085. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 20, parm );
  1086. parm[0] = surf->space->modelMatrix[1];
  1087. parm[1] = surf->space->modelMatrix[5];
  1088. parm[2] = surf->space->modelMatrix[9];
  1089. parm[3] = 0;
  1090. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 21, parm );
  1091. parm[0] = surf->space->modelMatrix[2];
  1092. parm[1] = surf->space->modelMatrix[6];
  1093. parm[2] = surf->space->modelMatrix[10];
  1094. parm[3] = 0;
  1095. qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, 22, parm );
  1096. GL_SelectTextureNoClient( 0 );
  1097. const shaderStage_t *stage = backEnd.vLight->lightShader->GetStage( 0 );
  1098. if ( stage->newStage ) {
  1099. stage->newStage->fragmentProgramImages[7]->BindFragment();
  1100. }
  1101. }
  1102. // set the vertex pointers
  1103. idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
  1104. qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color );
  1105. qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
  1106. qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
  1107. qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
  1108. qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
  1109. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  1110. // this may cause RB_ARB2_DrawInteraction to be exacuted multiple
  1111. // times with different colors and images if the surface or light have multiple layers
  1112. if ( r_sb_screenSpaceShadow.GetBool() ) {
  1113. RB_CreateSingleDrawInteractions( surf, RB_ARB2_DrawInteraction );
  1114. } else {
  1115. RB_CreateSingleDrawInteractions( surf, RB_EXP_DrawInteraction );
  1116. }
  1117. }
  1118. qglDisableVertexAttribArrayARB( 8 );
  1119. qglDisableVertexAttribArrayARB( 9 );
  1120. qglDisableVertexAttribArrayARB( 10 );
  1121. qglDisableVertexAttribArrayARB( 11 );
  1122. qglDisableClientState( GL_COLOR_ARRAY );
  1123. // disable features
  1124. GL_SelectTextureNoClient( 6 );
  1125. globalImages->BindNull();
  1126. GL_SelectTextureNoClient( 5 );
  1127. globalImages->BindNull();
  1128. GL_SelectTextureNoClient( 4 );
  1129. globalImages->BindNull();
  1130. GL_SelectTextureNoClient( 3 );
  1131. globalImages->BindNull();
  1132. GL_SelectTextureNoClient( 2 );
  1133. globalImages->BindNull();
  1134. GL_SelectTextureNoClient( 1 );
  1135. globalImages->BindNull();
  1136. backEnd.glState.currenttmu = -1;
  1137. GL_SelectTexture( 0 );
  1138. qglDisable(GL_VERTEX_PROGRAM_ARB);
  1139. qglDisable(GL_FRAGMENT_PROGRAM_ARB);
  1140. }
  1141. void InvertByTranspose( const float a[16], float r[16] ) {
  1142. r[ 0] = a[ 0];
  1143. r[ 1] = a[ 4];
  1144. r[ 2] = a[ 8];
  1145. r[ 3] = 0;
  1146. r[ 4] = a[ 1];
  1147. r[ 5] = a[ 5];
  1148. r[ 6] = a[ 9];
  1149. r[ 7] = 0;
  1150. r[ 8] = a[ 2];
  1151. r[ 9] = a[ 6];
  1152. r[10] = a[10];
  1153. r[11] = 0;
  1154. r[12] = -(r[ 0]*a[12] + r[ 4]*a[13] + r[ 8]*a[14]);
  1155. r[13] = -(r[ 1]*a[12] + r[ 5]*a[13] + r[ 9]*a[14]);
  1156. r[14] = -(r[ 2]*a[12] + r[ 6]*a[13] + r[10]*a[14]);
  1157. r[15] = 1;
  1158. }
  1159. void FullInvert( const float a[16], float r[16] ) {
  1160. idMat4 am;
  1161. for ( int i = 0 ; i < 4 ; i++ ) {
  1162. for ( int j = 0 ; j < 4 ; j++ ) {
  1163. am[i][j] = a[j*4+i];
  1164. }
  1165. }
  1166. // idVec4 test( 100, 100, 100, 1 );
  1167. // idVec4 transformed, inverted;
  1168. // transformed = test * am;
  1169. if ( !am.InverseSelf() ) {
  1170. common->Error( "Invert failed" );
  1171. }
  1172. // inverted = transformed * am;
  1173. for ( int i = 0 ; i < 4 ; i++ ) {
  1174. for ( int j = 0 ; j < 4 ; j++ ) {
  1175. r[j*4+i] = am[i][j];
  1176. }
  1177. }
  1178. }
  1179. /*
  1180. ==================
  1181. RB_Exp_TrianglesForFrustum
  1182. ==================
  1183. */
  1184. const srfTriangles_t *RB_Exp_TrianglesForFrustum( viewLight_t *vLight, int side ) {
  1185. const srfTriangles_t *tri;
  1186. static srfTriangles_t frustumTri;
  1187. static idDrawVert verts[5];
  1188. static glIndex_t indexes[18] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 2, 1, 4, 2, 4, 3 };
  1189. if ( side == -1 ) {
  1190. tri = vLight->frustumTris;
  1191. } else {
  1192. memset( verts, 0, sizeof( verts ) );
  1193. for ( int i = 0 ; i < 5 ; i++ ) {
  1194. verts[i].xyz = vLight->globalLightOrigin;
  1195. }
  1196. memset( &frustumTri, 0, sizeof( frustumTri ) );
  1197. frustumTri.indexes = indexes;
  1198. frustumTri.verts = verts;
  1199. frustumTri.numIndexes = 18;
  1200. frustumTri.numVerts = 5;
  1201. tri = &frustumTri;
  1202. float size = viewLightAxialSize;
  1203. switch ( side ) {
  1204. case 0:
  1205. verts[1].xyz[0] += size;
  1206. verts[2].xyz[0] += size;
  1207. verts[3].xyz[0] += size;
  1208. verts[4].xyz[0] += size;
  1209. verts[1].xyz[1] += size;
  1210. verts[1].xyz[2] += size;
  1211. verts[2].xyz[1] -= size;
  1212. verts[2].xyz[2] += size;
  1213. verts[3].xyz[1] -= size;
  1214. verts[3].xyz[2] -= size;
  1215. verts[4].xyz[1] += size;
  1216. verts[4].xyz[2] -= size;
  1217. break;
  1218. case 1:
  1219. verts[1].xyz[0] -= size;
  1220. verts[2].xyz[0] -= size;
  1221. verts[3].xyz[0] -= size;
  1222. verts[4].xyz[0] -= size;
  1223. verts[1].xyz[1] -= size;
  1224. verts[1].xyz[2] += size;
  1225. verts[2].xyz[1] += size;
  1226. verts[2].xyz[2] += size;
  1227. verts[3].xyz[1] += size;
  1228. verts[3].xyz[2] -= size;
  1229. verts[4].xyz[1] -= size;
  1230. verts[4].xyz[2] -= size;
  1231. break;
  1232. case 2:
  1233. verts[1].xyz[1] += size;
  1234. verts[2].xyz[1] += size;
  1235. verts[3].xyz[1] += size;
  1236. verts[4].xyz[1] += size;
  1237. verts[1].xyz[0] -= size;
  1238. verts[1].xyz[2] += size;
  1239. verts[2].xyz[0] += size;
  1240. verts[2].xyz[2] += size;
  1241. verts[3].xyz[0] += size;
  1242. verts[3].xyz[2] -= size;
  1243. verts[4].xyz[0] -= size;
  1244. verts[4].xyz[2] -= size;
  1245. break;
  1246. case 3:
  1247. verts[1].xyz[1] -= size;
  1248. verts[2].xyz[1] -= size;
  1249. verts[3].xyz[1] -= size;
  1250. verts[4].xyz[1] -= size;
  1251. verts[1].xyz[0] += size;
  1252. verts[1].xyz[2] += size;
  1253. verts[2].xyz[0] -= size;
  1254. verts[2].xyz[2] += size;
  1255. verts[3].xyz[0] -= size;
  1256. verts[3].xyz[2] -= size;
  1257. verts[4].xyz[0] += size;
  1258. verts[4].xyz[2] -= size;
  1259. break;
  1260. case 4:
  1261. verts[1].xyz[2] += size;
  1262. verts[2].xyz[2] += size;
  1263. verts[3].xyz[2] += size;
  1264. verts[4].xyz[2] += size;
  1265. verts[1].xyz[0] += size;
  1266. verts[1].xyz[1] += size;
  1267. verts[2].xyz[0] -= size;
  1268. verts[2].xyz[1] += size;
  1269. verts[3].xyz[0] -= size;
  1270. verts[3].xyz[1] -= size;
  1271. verts[4].xyz[0] += size;
  1272. verts[4].xyz[1] -= size;
  1273. break;
  1274. case 5:
  1275. verts[1].xyz[2] -= size;
  1276. verts[2].xyz[2] -= size;
  1277. verts[3].xyz[2] -= size;
  1278. verts[4].xyz[2] -= size;
  1279. verts[1].xyz[0] -= size;
  1280. verts[1].xyz[1] += size;
  1281. verts[2].xyz[0] += size;
  1282. verts[2].xyz[1] += size;
  1283. verts[3].xyz[0] += size;
  1284. verts[3].xyz[1] -= size;
  1285. verts[4].xyz[0] -= size;
  1286. verts[4].xyz[1] -= size;
  1287. break;
  1288. }
  1289. frustumTri.ambientCache = vertexCache.AllocFrameTemp( verts, sizeof( verts ) );
  1290. }
  1291. return tri;
  1292. }
  1293. /*
  1294. ==================
  1295. RB_Exp_SelectFrustum
  1296. ==================
  1297. */
  1298. void RB_Exp_SelectFrustum( viewLight_t *vLight, int side ) {
  1299. qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );
  1300. const srfTriangles_t *tri = RB_Exp_TrianglesForFrustum( vLight, side );
  1301. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  1302. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  1303. qglDisable( GL_TEXTURE_2D );
  1304. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1305. // clear stencil buffer
  1306. qglEnable( GL_SCISSOR_TEST );
  1307. qglEnable( GL_STENCIL_TEST );
  1308. qglClearStencil( 1 );
  1309. qglClear( GL_STENCIL_BUFFER_BIT );
  1310. // draw front faces of the light frustum, incrementing the stencil buffer on depth fail
  1311. // so we can't draw on those pixels
  1312. GL_State( GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1313. qglStencilFunc( GL_ALWAYS, 0, 255 );
  1314. qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
  1315. GL_Cull( CT_FRONT_SIDED );
  1316. RB_DrawElementsWithCounters( tri );
  1317. // draw back faces of the light frustum with
  1318. // depth test greater
  1319. // stencil test of equal 1
  1320. // zero stencil stencil when depth test passes, so subsequent surface drawing
  1321. // can occur on those pixels
  1322. // this pass does all the shadow filtering
  1323. qglStencilFunc( GL_EQUAL, 1, 255 );
  1324. qglStencilOp( GL_KEEP, GL_KEEP, GL_ZERO );
  1325. GL_Cull( CT_BACK_SIDED );
  1326. qglDepthFunc( GL_GREATER );
  1327. // write to destination alpha
  1328. if ( r_sb_showFrustumPixels.GetBool() ) {
  1329. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1330. qglDisable( GL_TEXTURE_2D );
  1331. qglColor4f( 0, 0.25, 0, 1 );
  1332. } else {
  1333. GL_State( GLS_COLORMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1334. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1335. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1336. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, screenSpaceShadowVertexProgram );
  1337. switch ( r_sb_samples.GetInteger() ) {
  1338. case 0:
  1339. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram0 );
  1340. break;
  1341. case 1:
  1342. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram1 );
  1343. break;
  1344. case 4:
  1345. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram4 );
  1346. break;
  1347. case 16:
  1348. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, screenSpaceShadowFragmentProgram16 );
  1349. break;
  1350. }
  1351. }
  1352. /*
  1353. texture[0] = view depth texture
  1354. texture[1] = jitter texture
  1355. texture[2] = light depth texture
  1356. */
  1357. GL_SelectTextureNoClient( 2 );
  1358. shadowImage[0]->Bind();
  1359. GL_SelectTextureNoClient( 1 );
  1360. if ( r_sb_samples.GetInteger() == 16 ) {
  1361. jitterImage16->Bind();
  1362. } else if ( r_sb_samples.GetInteger() == 4 ) {
  1363. jitterImage4->Bind();
  1364. } else {
  1365. jitterImage1->Bind();
  1366. }
  1367. GL_SelectTextureNoClient( 0 );
  1368. viewDepthImage->Bind();
  1369. /*
  1370. PARAM positionToDepthTexScale = program.local[0]; # fragment.position to screen depth texture transformation
  1371. PARAM zProject = program.local[1]; # projection[10], projection[14], 0, 0
  1372. PARAM positionToViewSpace = program.local[2]; # X add, Y add, X mul, Y mul
  1373. PARAM viewToLightS = program.local[3];
  1374. PARAM viewToLightT = program.local[4];
  1375. PARAM viewToLightR = program.local[5];
  1376. PARAM viewToLightQ = program.local[6];
  1377. PARAM positionToJitterTexScale = program.local[7]; # fragment.position to jitter texture
  1378. PARAM jitterTexScale = program.local[8];
  1379. PARAM jitterTexOffset = program.local[9];
  1380. */
  1381. float parm[4];
  1382. int pot;
  1383. // calculate depth projection for shadow buffer
  1384. float sRow[4];
  1385. float tRow[4];
  1386. float rRow[4];
  1387. float qRow[4];
  1388. float invertedView[16];
  1389. float invertedProjection[16];
  1390. float matrix[16];
  1391. float matrix2[16];
  1392. // we need the inverse of the projection matrix to go from NDC to view
  1393. FullInvert( backEnd.viewDef->projectionMatrix, invertedProjection );
  1394. /*
  1395. from window to NDC:
  1396. ( x - xMid ) * 1.0 / xMid
  1397. ( y - yMid ) * 1.0 / yMid
  1398. ( z - 0.5 ) * 2
  1399. from NDC to clip coordinates:
  1400. rcp(1/w)
  1401. */
  1402. // we need the inverse of the viewMatrix to go from view (looking down negative Z) to world
  1403. InvertByTranspose( backEnd.viewDef->worldSpace.modelViewMatrix, invertedView );
  1404. // then we go from world to light view space (looking down negative Z)
  1405. myGlMultMatrix( invertedView, lightMatrix, matrix );
  1406. // then to light projection, giving X/w, Y/w, Z/w in the -1 : 1 range
  1407. myGlMultMatrix( matrix, lightProjectionMatrix, matrix2 );
  1408. // the final values need to be in 0.0 : 1.0 range instead of -1 : 1
  1409. sRow[0] = 0.5 * ( matrix2[0] + matrix2[3] ) * lightBufferSizeFraction;
  1410. sRow[1] = 0.5 * ( matrix2[4] + matrix2[7] ) * lightBufferSizeFraction;
  1411. sRow[2] = 0.5 * ( matrix2[8] + matrix2[11] ) * lightBufferSizeFraction;
  1412. sRow[3] = 0.5 * ( matrix2[12] + matrix2[15] ) * lightBufferSizeFraction;
  1413. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, sRow );
  1414. tRow[0] = 0.5 * ( matrix2[1] + matrix2[3] ) * lightBufferSizeFraction;
  1415. tRow[1] = 0.5 * ( matrix2[5] + matrix2[7] ) * lightBufferSizeFraction;
  1416. tRow[2] = 0.5 * ( matrix2[9] + matrix2[11] ) * lightBufferSizeFraction;
  1417. tRow[3] = 0.5 * ( matrix2[13] + matrix2[15] ) * lightBufferSizeFraction;
  1418. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, tRow );
  1419. rRow[0] = 0.5 * ( matrix2[2] + matrix2[3] );
  1420. rRow[1] = 0.5 * ( matrix2[6] + matrix2[7] );
  1421. rRow[2] = 0.5 * ( matrix2[10] + matrix2[11] );
  1422. rRow[3] = 0.5 * ( matrix2[14] + matrix2[15] );
  1423. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 5, rRow );
  1424. qRow[0] = matrix2[3];
  1425. qRow[1] = matrix2[7];
  1426. qRow[2] = matrix2[11];
  1427. qRow[3] = matrix2[15];
  1428. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 6, qRow );
  1429. //-----------------------------------------------------
  1430. // these should be constant for the entire frame
  1431. // convert 0..viewport-1 sizes to fractions inside the POT screen depth texture
  1432. int w = viewBufferSize;
  1433. pot = MakePowerOfTwo( w );
  1434. parm[0] = 1.0 / maxViewBufferSize; // * ( (float)viewBufferSize / w );
  1435. int h = viewBufferHeight;
  1436. pot = MakePowerOfTwo( h );
  1437. parm[1] = parm[0]; // 1.0 / pot;
  1438. parm[2] = 0;
  1439. parm[3] = 1;
  1440. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  1441. // zProject values
  1442. parm[0] = backEnd.viewDef->projectionMatrix[10];
  1443. parm[1] = backEnd.viewDef->projectionMatrix[14];
  1444. parm[2] = 0;
  1445. parm[3] = 0;
  1446. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm );
  1447. // positionToViewSpace
  1448. parm[0] = -1.0 / backEnd.viewDef->projectionMatrix[0];
  1449. parm[1] = -1.0 / backEnd.viewDef->projectionMatrix[5];
  1450. parm[2] = 2.0/viewBufferSize;
  1451. parm[3] = 2.0/viewBufferSize;
  1452. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm );
  1453. // positionToJitterTexScale
  1454. parm[0] = 1.0 / ( JITTER_SIZE * r_sb_samples.GetInteger() ) ;
  1455. parm[1] = 1.0 / JITTER_SIZE;
  1456. parm[2] = 0;
  1457. parm[3] = 1;
  1458. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 7, parm );
  1459. // jitter tex scale
  1460. parm[0] =
  1461. parm[1] = r_sb_jitterScale.GetFloat() * lightBufferSizeFraction;
  1462. parm[2] = -r_sb_biasScale.GetFloat();
  1463. parm[3] = 0;
  1464. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 8, parm );
  1465. // jitter tex offset
  1466. if ( r_sb_randomize.GetBool() ) {
  1467. parm[0] = (rand()&255) / 255.0;
  1468. parm[1] = (rand()&255) / 255.0;
  1469. } else {
  1470. parm[0] = parm[1] = 0;
  1471. }
  1472. parm[2] = 0;
  1473. parm[3] = 0;
  1474. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 9, parm );
  1475. //-----------------------------------------------------
  1476. RB_DrawElementsWithCounters( tri );
  1477. qglDisable(GL_VERTEX_PROGRAM_ARB);
  1478. qglDisable(GL_FRAGMENT_PROGRAM_ARB);
  1479. GL_Cull( CT_FRONT_SIDED );
  1480. // qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  1481. qglDepthFunc( GL_LEQUAL );
  1482. if ( r_sb_showFrustumPixels.GetBool() ) {
  1483. qglEnable( GL_TEXTURE_2D );
  1484. qglColor3f( 1, 1, 1 );
  1485. }
  1486. // after all the frustums have been drawn, the surfaces that have been drawn on will get interactions
  1487. // scissor may still be a win even with the stencil test for very fast rejects
  1488. qglStencilFunc( GL_EQUAL, 0, 255 );
  1489. qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  1490. // we can avoid clearing the stencil buffer by changing the hasLight value for each light
  1491. }
  1492. /*
  1493. ==================
  1494. R_EXP_CalcLightAxialSize
  1495. all light side projections must currently match, so non-centered
  1496. and non-cubic lights must take the largest length
  1497. ==================
  1498. */
  1499. float R_EXP_CalcLightAxialSize( viewLight_t *vLight ) {
  1500. float max = 0;
  1501. if ( !vLight->lightDef->parms.pointLight ) {
  1502. idVec3 dir = vLight->lightDef->parms.target - vLight->lightDef->parms.origin;
  1503. max = dir.Length();
  1504. return max;
  1505. }
  1506. for ( int i = 0 ; i < 3 ; i++ ) {
  1507. float dist = fabs(vLight->lightDef->parms.lightCenter[i] );
  1508. dist += vLight->lightDef->parms.lightRadius[i];
  1509. if ( dist > max ) {
  1510. max = dist;
  1511. }
  1512. }
  1513. return max;
  1514. }
  1515. /*
  1516. ==================
  1517. R_EXP_RenderViewDepthImage
  1518. This could be avoided by drop sampling the native view depth buffer with render to texture
  1519. Bilerp might even be aprorpiate, although it would cause issues at edges
  1520. ==================
  1521. */
  1522. void RB_T_FillDepthBuffer( const drawSurf_t *surf );
  1523. void R_EXP_RenderViewDepthImage( void ) {
  1524. if ( !r_sb_screenSpaceShadow.GetBool() ) {
  1525. return;
  1526. }
  1527. // if the screen resolution is exactly the window width, we can
  1528. // use the depth buffer we already have
  1529. if ( 0 ) { // nativeViewBuffer ) {
  1530. viewDepthImage->CopyDepthbuffer( backEnd.viewDef->viewport.x1,
  1531. backEnd.viewDef->viewport.y1, backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1,
  1532. backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1 );
  1533. } else {
  1534. RB_LogComment( "---------- R_EXP_RenderViewDepthImage ----------\n" );
  1535. if ( r_sb_usePbuffer.GetBool() ) {
  1536. GL_CheckErrors();
  1537. // set the current openGL drawable to the shadow buffer
  1538. R_MakeCurrent( viewPbufferDC, win32.hGLRC, NULL /* !@# viewPbuffer */ );
  1539. }
  1540. // render the depth to the new size
  1541. qglViewport( 0, 0, viewBufferSize, viewBufferHeight );
  1542. qglScissor( 0, 0, viewBufferSize, viewBufferHeight );
  1543. qglClear( GL_DEPTH_BUFFER_BIT );
  1544. qglStencilFunc( GL_ALWAYS, 0, 255 );
  1545. // the first texture will be used for alpha tested surfaces
  1546. GL_SelectTexture( 0 );
  1547. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  1548. GL_State( GLS_DEPTHFUNC_LESS );
  1549. RB_RenderDrawSurfListWithFunction( backEnd.viewDef->drawSurfs, backEnd.viewDef->numDrawSurfs, RB_T_FillDepthBuffer );
  1550. //
  1551. // copy it to a texture
  1552. //
  1553. viewDepthImage->Bind();
  1554. qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, viewBufferSize, viewBufferHeight );
  1555. if ( r_sb_usePbuffer.GetBool() ) {
  1556. // set the normal screen drawable current
  1557. R_MakeCurrent( win32.hDC, win32.hGLRC, NULL );
  1558. }
  1559. // reset the window clipping
  1560. qglMatrixMode( GL_PROJECTION );
  1561. qglLoadMatrixf( backEnd.viewDef->projectionMatrix );
  1562. qglMatrixMode( GL_MODELVIEW );
  1563. qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1,
  1564. tr.viewportOffset[1] + backEnd.viewDef->viewport.y1,
  1565. backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1,
  1566. backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 );
  1567. qglScissor( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1,
  1568. tr.viewportOffset[1] + backEnd.viewDef->viewport.y1,
  1569. backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1,
  1570. backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 );
  1571. // the current modelView matrix is not valid
  1572. backEnd.currentSpace = NULL;
  1573. }
  1574. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  1575. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  1576. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  1577. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  1578. }
  1579. /*
  1580. ==================
  1581. RB_EXP_SetNativeBuffer
  1582. This is always the back buffer, and scissor is set full screen
  1583. ==================
  1584. */
  1585. void RB_EXP_SetNativeBuffer( void ) {
  1586. // set the normal screen drawable current
  1587. R_MakeCurrent( win32.hDC, win32.hGLRC, NULL );
  1588. qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1,
  1589. tr.viewportOffset[1] + backEnd.viewDef->viewport.y1,
  1590. backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1,
  1591. backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 );
  1592. backEnd.currentScissor = backEnd.viewDef->viewport;
  1593. if ( r_useScissor.GetBool() ) {
  1594. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  1595. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  1596. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  1597. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  1598. }
  1599. }
  1600. /*
  1601. ==================
  1602. RB_EXP_SetRenderBuffer
  1603. This may be to a float pBuffer, and scissor is set to cover only the light
  1604. ==================
  1605. */
  1606. void RB_EXP_SetRenderBuffer( viewLight_t *vLight ) {
  1607. if ( r_hdr_useFloats.GetBool() ) {
  1608. R_MakeCurrent( floatPbufferDC, floatContext, floatPbuffer );
  1609. } else {
  1610. if ( !qwglMakeCurrent( win32.hDC, win32.hGLRC ) ) {
  1611. GL_CheckErrors();
  1612. common->FatalError( "Couldn't return to normal drawing context" );
  1613. }
  1614. }
  1615. qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1,
  1616. tr.viewportOffset[1] + backEnd.viewDef->viewport.y1,
  1617. backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1,
  1618. backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 );
  1619. if ( !vLight ) {
  1620. backEnd.currentScissor = backEnd.viewDef->viewport;
  1621. } else {
  1622. backEnd.currentScissor = vLight->scissorRect;
  1623. }
  1624. if ( r_useScissor.GetBool() ) {
  1625. qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
  1626. backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
  1627. backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
  1628. backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
  1629. }
  1630. }
  1631. /*
  1632. ==================
  1633. RB_shadowResampleAlpha
  1634. ==================
  1635. */
  1636. void RB_shadowResampleAlpha( void ) {
  1637. viewAlphaImage->Bind();
  1638. // we could make this a subimage, but it isn't relevent once we have render-to-texture
  1639. qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, viewBufferSize, viewBufferHeight );
  1640. RB_EXP_SetRenderBuffer( backEnd.vLight );
  1641. //=====================
  1642. qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );
  1643. // this uses the full light, not side frustums
  1644. const srfTriangles_t *tri = backEnd.vLight->frustumTris;
  1645. idDrawVert *ac = (idDrawVert *)vertexCache.Position( tri->ambientCache );
  1646. qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
  1647. // clear stencil buffer
  1648. qglEnable( GL_SCISSOR_TEST );
  1649. qglEnable( GL_STENCIL_TEST );
  1650. qglClearStencil( 1 );
  1651. qglClear( GL_STENCIL_BUFFER_BIT );
  1652. // draw front faces of the light frustum, incrementing the stencil buffer on depth fail
  1653. // so we can't draw on those pixels
  1654. GL_State( GLS_COLORMASK | GLS_ALPHAMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1655. qglStencilFunc( GL_ALWAYS, 0, 255 );
  1656. qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
  1657. GL_Cull( CT_FRONT_SIDED );
  1658. // set fragment / vertex program?
  1659. RB_DrawElementsWithCounters( tri );
  1660. // draw back faces of the light frustum with
  1661. // depth test greater
  1662. // stencil test of equal 1
  1663. // zero stencil stencil when depth test passes, so subsequent interaction drawing
  1664. // can occur on those pixels
  1665. // this pass does all the shadow filtering
  1666. qglStencilFunc( GL_EQUAL, 1, 255 );
  1667. qglStencilOp( GL_KEEP, GL_KEEP, GL_ZERO );
  1668. // write to destination alpha
  1669. if ( r_sb_showFrustumPixels.GetBool() ) {
  1670. GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1671. qglDisable( GL_TEXTURE_2D );
  1672. qglColor4f( 0, 0.25, 0, 1 );
  1673. } else {
  1674. GL_State( GLS_COLORMASK | GLS_DEPTHMASK | GLS_DEPTHFUNC_LESS );
  1675. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1676. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1677. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, shadowResampleVertexProgram );
  1678. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, shadowResampleFragmentProgram );
  1679. // convert 0..viewport-1 sizes to fractions inside the POT screen depth texture
  1680. // shrink by one unit for bilerp
  1681. float parm[4];
  1682. parm[0] = 1.0 / (maxViewBufferSize+1) * viewBufferSize / maxViewBufferSize;
  1683. parm[1] = parm[0];
  1684. parm[2] = 0;
  1685. parm[3] = 1;
  1686. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  1687. }
  1688. GL_Cull( CT_BACK_SIDED );
  1689. qglDepthFunc( GL_GREATER );
  1690. RB_DrawElementsWithCounters( tri );
  1691. qglDisable(GL_VERTEX_PROGRAM_ARB);
  1692. qglDisable(GL_FRAGMENT_PROGRAM_ARB);
  1693. GL_Cull( CT_FRONT_SIDED );
  1694. qglDepthFunc( GL_LEQUAL );
  1695. if ( r_sb_showFrustumPixels.GetBool() ) {
  1696. qglEnable( GL_TEXTURE_2D );
  1697. qglColor3f( 1, 1, 1 );
  1698. }
  1699. // after all the frustums have been drawn, the surfaces that have been drawn on will get interactions
  1700. // scissor may still be a win even with the stencil test for very fast rejects
  1701. qglStencilFunc( GL_EQUAL, 0, 255 );
  1702. qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  1703. }
  1704. /*
  1705. ==================
  1706. RB_EXP_CoverScreen
  1707. ==================
  1708. */
  1709. void RB_EXP_CoverScreen( void ) {
  1710. // draw a full screen quad
  1711. qglMatrixMode( GL_PROJECTION );
  1712. qglLoadIdentity();
  1713. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1714. qglMatrixMode( GL_MODELVIEW );
  1715. qglLoadIdentity();
  1716. qglBegin( GL_TRIANGLE_FAN );
  1717. qglVertex2f( 0, 0 );
  1718. qglVertex2f( 0, 1 );
  1719. qglVertex2f( 1, 1 );
  1720. qglVertex2f( 1, 0 );
  1721. qglEnd();
  1722. }
  1723. /*
  1724. ==================
  1725. RB_EXP_ReadFloatBuffer
  1726. ==================
  1727. */
  1728. void RB_EXP_ReadFloatBuffer( void ) {
  1729. int pixels = glConfig.vidWidth * glConfig.vidHeight;
  1730. float *buf = (float *)R_StaticAlloc( pixels * 4 * sizeof( float ) );
  1731. qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_FLOAT, buf );
  1732. float mins[4] = { 9999, 9999, 9999, 9999 };
  1733. float maxs[4] = { -9999, -9999, -9999, -9999 };
  1734. for ( int i = 0 ; i < pixels ; i++ ) {
  1735. for ( int j = 0 ; j < 4 ; j++ ) {
  1736. float v = buf[ i*4 + j ];
  1737. if ( v < mins[j] ) {
  1738. mins[j] = v;
  1739. }
  1740. if ( v > maxs[j] ) {
  1741. maxs[j] = v;
  1742. }
  1743. }
  1744. }
  1745. RB_EXP_SetNativeBuffer();
  1746. qglLoadIdentity();
  1747. qglMatrixMode( GL_PROJECTION );
  1748. GL_State( GLS_DEPTHFUNC_ALWAYS );
  1749. qglColor3f( 1, 1, 1 );
  1750. qglPushMatrix();
  1751. qglLoadIdentity();
  1752. qglDisable( GL_TEXTURE_2D );
  1753. qglOrtho( 0, 1, 0, 1, -1, 1 );
  1754. qglRasterPos2f( 0.01f, 0.01f );
  1755. qglDrawPixels( glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_FLOAT, buf );
  1756. qglPopMatrix();
  1757. qglEnable( GL_TEXTURE_2D );
  1758. qglMatrixMode( GL_MODELVIEW );
  1759. R_StaticFree( buf );
  1760. }
  1761. void RB_TestGamma( void );
  1762. /*
  1763. ==================
  1764. RB_EXP_GammaDither
  1765. ==================
  1766. */
  1767. void RB_EXP_GammaDither( void ) {
  1768. if ( !r_hdr_useFloats.GetBool() ) {
  1769. return;
  1770. }
  1771. #if 0
  1772. r_testGamma.SetBool( true );
  1773. RB_TestGamma();
  1774. r_testGamma.SetBool( false );
  1775. #endif
  1776. RB_EXP_SetNativeBuffer();
  1777. /*
  1778. # texture 0 is the high dynamic range buffer
  1779. # texture 1 is the random dither texture
  1780. # texture 2 is the light bloom texture
  1781. # writes result.color as the 32 bit dithered and gamma corrected values
  1782. PARAM exposure = program.local[0]; # multiply HDR value by this to get screen pixels
  1783. PARAM gammaPower = program.local[1];
  1784. PARAM monitorDither = program.local[2];
  1785. PARAM positionToDitherScale = program.local[3];
  1786. PARAM bloomFraction = program.local[4];
  1787. PARAM positionToBloomScale = program.local[5];
  1788. */
  1789. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB,gammaDitherVertexProgram );
  1790. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, gammaDitherFragmentProgram );
  1791. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1792. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1793. qglActiveTextureARB( GL_TEXTURE2_ARB );
  1794. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferQuarterImage->texnum );
  1795. R_BindTexImage( floatPbufferQuarter );
  1796. qglActiveTextureARB( GL_TEXTURE1_ARB );
  1797. random256Image->BindFragment();
  1798. qglActiveTextureARB( GL_TEXTURE0_ARB );
  1799. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferImage->texnum );
  1800. R_BindTexImage( floatPbuffer );
  1801. float parm[4];
  1802. parm[0] = r_hdr_exposure.GetFloat();
  1803. parm[1] = 0;
  1804. parm[2] = 0;
  1805. parm[3] = 0;
  1806. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  1807. parm[0] = r_hdr_gamma.GetFloat();
  1808. parm[1] = 0;
  1809. parm[2] = 0;
  1810. parm[3] = 0;
  1811. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, parm );
  1812. parm[0] = r_hdr_monitorDither.GetFloat();
  1813. parm[1] = 0;
  1814. parm[2] = 0;
  1815. parm[3] = 0;
  1816. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, parm );
  1817. parm[0] = 1.0 / 256;
  1818. parm[1] = parm[0];
  1819. parm[2] = rand()/65535.0;
  1820. parm[3] = rand()/65535.0;
  1821. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, parm );
  1822. parm[0] = 1.0 - r_hdr_bloomFraction.GetFloat();
  1823. parm[1] = r_hdr_bloomFraction.GetFloat();
  1824. parm[2] = 0;
  1825. parm[3] = 0;
  1826. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 4, parm );
  1827. parm[0] = 0.25;
  1828. parm[1] = 0.25;
  1829. parm[2] = 0;
  1830. parm[3] = 0;
  1831. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 5, parm );
  1832. qglDisable( GL_STENCIL_TEST );
  1833. qglDisable( GL_SCISSOR_TEST );
  1834. qglDisable( GL_DEPTH_TEST );
  1835. RB_EXP_CoverScreen();
  1836. qglEnable( GL_DEPTH_TEST );
  1837. qglDisable(GL_VERTEX_PROGRAM_ARB);
  1838. qglDisable(GL_FRAGMENT_PROGRAM_ARB);
  1839. }
  1840. /*
  1841. ==================
  1842. RB_EXP_Bloom
  1843. ==================
  1844. */
  1845. void RB_EXP_Bloom( void ) {
  1846. if ( !r_hdr_useFloats.GetBool() ) {
  1847. return;
  1848. }
  1849. if ( r_hdr_bloomFraction.GetFloat() == 0 ) {
  1850. return;
  1851. }
  1852. GL_CheckErrors();
  1853. //
  1854. // mip map
  1855. //
  1856. // draw to the second floatPbuffer
  1857. R_MakeCurrent( floatPbuffer2DC, floatContext, floatPbuffer2 );
  1858. GL_State( 0 );
  1859. qglDisable( GL_DEPTH_TEST );
  1860. qglDisable( GL_SCISSOR_TEST );
  1861. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1862. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1863. qglClearColor( 1.0, 0.5, 0, 0 );
  1864. qglClear( GL_COLOR_BUFFER_BIT );
  1865. qglViewport( 0, 0, glConfig.vidWidth>>1, glConfig.vidHeight>>1 );
  1866. // read from the original floatPbuffer
  1867. qglActiveTextureARB( GL_TEXTURE0_ARB );
  1868. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferImage->texnum );
  1869. R_BindTexImage( floatPbuffer );
  1870. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, downSampleVertexProgram );
  1871. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, downSampleFragmentProgram );
  1872. RB_EXP_CoverScreen();
  1873. //
  1874. // mip map again
  1875. //
  1876. qglViewport( 0, 0, glConfig.vidWidth>>2, glConfig.vidHeight>>2 );
  1877. // draw to the second floatPbuffer
  1878. R_MakeCurrent( floatPbufferQuarterDC, floatContext, floatPbufferQuarter );
  1879. // read from the original floatPbuffer
  1880. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbuffer2Image->texnum );
  1881. R_BindTexImage( floatPbuffer2 );
  1882. RB_EXP_CoverScreen();
  1883. //
  1884. // blur horizontally
  1885. //
  1886. /*
  1887. # texture 0 is the high dynamic range buffer
  1888. # writes result.color as the fp16 result of a smeared bloom
  1889. PARAM step = program.local[0]; # { 1, 0 } or { 0, 1 } for horizontal / vertical separation
  1890. */
  1891. // draw to the second floatPbuffer
  1892. R_MakeCurrent( floatPbuffer2DC, floatContext, floatPbuffer2 );
  1893. qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, bloomVertexProgram );
  1894. qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, bloomFragmentProgram );
  1895. qglEnable(GL_VERTEX_PROGRAM_ARB);
  1896. qglEnable(GL_FRAGMENT_PROGRAM_ARB);
  1897. GL_SelectTextureNoClient( 0 );
  1898. // blur horizontally first to the second floatPbuffer
  1899. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbufferQuarterImage->texnum );
  1900. R_BindTexImage( floatPbufferQuarter );
  1901. float parm[4];
  1902. parm[0] = 1;
  1903. parm[1] = 0;
  1904. parm[2] = 0;
  1905. parm[3] = 0;
  1906. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  1907. RB_EXP_CoverScreen();
  1908. //
  1909. // now blur vertically back to the quarter pbuffer
  1910. //
  1911. R_MakeCurrent( floatPbufferQuarterDC, floatContext, floatPbufferQuarter );
  1912. qglBindTexture( GL_TEXTURE_RECTANGLE_NV, floatPbuffer2Image->texnum );
  1913. R_BindTexImage( floatPbuffer2 );
  1914. parm[0] = 0;
  1915. parm[1] = 1;
  1916. parm[2] = 0;
  1917. parm[3] = 0;
  1918. qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, parm );
  1919. RB_EXP_CoverScreen();
  1920. //========================
  1921. qglEnable( GL_DEPTH_TEST );
  1922. qglEnable( GL_SCISSOR_TEST );
  1923. qglDisable(GL_VERTEX_PROGRAM_ARB);
  1924. qglDisable(GL_FRAGMENT_PROGRAM_ARB);
  1925. GL_CheckErrors();
  1926. }
  1927. /*
  1928. ==================
  1929. RB_Exp_DrawInteractions
  1930. ==================
  1931. */
  1932. void RB_Exp_DrawInteractions( void ) {
  1933. if ( !initialized ) {
  1934. R_Exp_Allocate();
  1935. }
  1936. if ( !backEnd.viewDef->viewLights ) {
  1937. return;
  1938. }
  1939. // validate the samples
  1940. if ( r_sb_samples.GetInteger() != 16 && r_sb_samples.GetInteger() != 4 && r_sb_samples.GetInteger() != 1 ) {
  1941. r_sb_samples.SetInteger( 0 );
  1942. }
  1943. // validate the light resolution
  1944. if ( r_sb_lightResolution.GetInteger() < 64 ) {
  1945. r_sb_lightResolution.SetInteger( 64 );
  1946. } else if ( r_sb_lightResolution.GetInteger() > maxLightBufferSize ) {
  1947. r_sb_lightResolution.SetInteger( maxLightBufferSize );
  1948. }
  1949. lightBufferSize = r_sb_lightResolution.GetInteger();
  1950. lightBufferSizeFraction = (float)lightBufferSize / maxLightBufferSize;
  1951. // validate the view resolution
  1952. if ( r_sb_viewResolution.GetInteger() < 64 ) {
  1953. r_sb_viewResolution.SetInteger( 64 );
  1954. } else if ( r_sb_viewResolution.GetInteger() > maxViewBufferSize ) {
  1955. r_sb_viewResolution.SetInteger( maxViewBufferSize );
  1956. }
  1957. viewBufferSize = r_sb_viewResolution.GetInteger();
  1958. viewBufferHeight = viewBufferSize * 3 / 4;
  1959. viewBufferSizeFraction = (float)viewBufferSize / maxViewBufferSize;
  1960. viewBufferHeightFraction = (float)viewBufferHeight / maxViewBufferSize;
  1961. if ( viewBufferSize == backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1 ) {
  1962. nativeViewBuffer = true;
  1963. } else {
  1964. nativeViewBuffer = false;
  1965. }
  1966. // set up for either point sampled or percentage-closer filtering for the shadow sampling
  1967. shadowImage[0]->BindFragment();
  1968. if ( r_sb_linearFilter.GetBool() ) {
  1969. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  1970. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  1971. } else {
  1972. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  1973. qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  1974. }
  1975. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE );
  1976. globalImages->BindNull();
  1977. // copy the current depth buffer to a texture for image-space shadowing,
  1978. // or re-render at a lower resolution
  1979. R_EXP_RenderViewDepthImage();
  1980. GL_SelectTexture( 0 );
  1981. qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
  1982. // disable stencil shadow test
  1983. qglStencilFunc( GL_ALWAYS, 128, 255 );
  1984. // the jitter image will be used to offset sample centers
  1985. GL_SelectTextureNoClient( 8 );
  1986. if ( r_sb_samples.GetInteger() == 16 ) {
  1987. jitterImage16->BindFragment();
  1988. } else if ( r_sb_samples.GetInteger() == 4 ) {
  1989. jitterImage4->BindFragment();
  1990. } else {
  1991. jitterImage1->BindFragment();
  1992. }
  1993. // if we are using a float buffer, clear it now
  1994. if ( r_hdr_useFloats.GetBool() ) {
  1995. RB_EXP_SetRenderBuffer( NULL );
  1996. // we need to set a lot of things, because this is a completely different context
  1997. RB_SetDefaultGLState();
  1998. qglClearColor( 0.001f, 1.0f, 0.01f, 0.1f );
  1999. qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  2000. // clear the z buffer, set the projection matrix, etc
  2001. RB_BeginDrawingView();
  2002. RB_STD_FillDepthBuffer( (drawSurf_t **)&backEnd.viewDef->drawSurfs[0], backEnd.viewDef->numDrawSurfs );
  2003. }
  2004. //
  2005. // for each light, perform adding and shadowing
  2006. //
  2007. for ( viewLight_t *vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
  2008. backEnd.vLight = vLight;
  2009. const idMaterial *lightShader = vLight->lightShader;
  2010. // do fogging later
  2011. if ( lightShader->IsFogLight() ) {
  2012. continue;
  2013. }
  2014. if ( lightShader->IsBlendLight() ) {
  2015. continue;
  2016. }
  2017. if ( !vLight->localInteractions && !vLight->globalInteractions
  2018. && !vLight->translucentInteractions ) {
  2019. continue;
  2020. }
  2021. if ( !vLight->frustumTris->ambientCache ) {
  2022. R_CreateAmbientCache( const_cast<srfTriangles_t *>(vLight->frustumTris), false );
  2023. }
  2024. // all light side projections must currently match, so non-centered
  2025. // and non-cubic lights must take the largest length
  2026. viewLightAxialSize = R_EXP_CalcLightAxialSize( vLight );
  2027. int side, sideStop;
  2028. if ( vLight->lightDef->parms.pointLight ) {
  2029. if ( r_sb_singleSide.GetInteger() != -1 ) {
  2030. side = r_sb_singleSide.GetInteger();
  2031. sideStop = side+1;
  2032. } else {
  2033. side = 0;
  2034. sideStop = 6;
  2035. }
  2036. } else {
  2037. side = -1;
  2038. sideStop = 0;
  2039. }
  2040. for ( ; side < sideStop ; side++ ) {
  2041. // FIXME: check for frustums completely off the screen
  2042. // render a shadow buffer
  2043. RB_RenderShadowBuffer( vLight, side );
  2044. // back to view rendering, possibly in the off-screen buffer
  2045. if ( nativeViewBuffer || !r_sb_screenSpaceShadow.GetBool() ) {
  2046. // directly to screen
  2047. RB_EXP_SetRenderBuffer( vLight );
  2048. } else {
  2049. // to off screen buffer
  2050. if ( r_sb_usePbuffer.GetBool() ) {
  2051. GL_CheckErrors();
  2052. // set the current openGL drawable to the shadow buffer
  2053. R_MakeCurrent( viewPbufferDC, win32.hGLRC, viewPbuffer );
  2054. }
  2055. qglViewport( 0, 0, viewBufferSize, viewBufferHeight );
  2056. qglScissor( 0, 0, viewBufferSize, viewBufferHeight ); // !@# FIXME: scale light scissor
  2057. }
  2058. // render the shadows into destination alpha on the included pixels
  2059. RB_Exp_SelectFrustum( vLight, side );
  2060. if ( !r_sb_screenSpaceShadow.GetBool() ) {
  2061. // bind shadow buffer to texture
  2062. GL_SelectTextureNoClient( 7 );
  2063. shadowImage[0]->BindFragment();
  2064. RB_EXP_CreateDrawInteractions( vLight->localInteractions );
  2065. RB_EXP_CreateDrawInteractions( vLight->globalInteractions );
  2066. backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
  2067. RB_EXP_CreateDrawInteractions( vLight->translucentInteractions );
  2068. backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
  2069. }
  2070. }
  2071. // render the native window coordinates interactions
  2072. if ( r_sb_screenSpaceShadow.GetBool() ) {
  2073. if ( !nativeViewBuffer ) {
  2074. RB_shadowResampleAlpha();
  2075. qglEnable( GL_STENCIL_TEST );
  2076. } else {
  2077. RB_EXP_SetRenderBuffer( vLight );
  2078. if ( r_ignore.GetBool() ) {
  2079. qglEnable( GL_STENCIL_TEST ); //!@#
  2080. } else {
  2081. qglDisable( GL_STENCIL_TEST ); //!@#
  2082. }
  2083. }
  2084. RB_EXP_CreateDrawInteractions( vLight->localInteractions );
  2085. RB_EXP_CreateDrawInteractions( vLight->globalInteractions );
  2086. backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
  2087. RB_EXP_CreateDrawInteractions( vLight->translucentInteractions );
  2088. backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
  2089. }
  2090. }
  2091. GL_SelectTexture( 0 );
  2092. qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
  2093. // experimental transfer function
  2094. for ( int i = 7 ; i >= 0 ; i-- ) {
  2095. GL_SelectTextureNoClient( i );
  2096. globalImages->BindNull();
  2097. }
  2098. GL_State( 0 );
  2099. RB_EXP_Bloom();
  2100. RB_EXP_GammaDither();
  2101. // these haven't been state saved
  2102. for ( int i = 0 ; i < 8 ; i++ ) {
  2103. backEnd.glState.tmu[i].current2DMap = -1;
  2104. }
  2105. // take it out of texture compare mode so I can testImage it for debugging
  2106. shadowImage[0]->BindFragment();
  2107. qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
  2108. }
  2109. /*
  2110. ==================
  2111. R_Exp_Init
  2112. ==================
  2113. */
  2114. void R_Exp_Init( void ) {
  2115. glConfig.allowExpPath = false;
  2116. common->Printf( "---------- R_Exp_Init ----------\n" );
  2117. if ( !glConfig.ARBVertexProgramAvailable || !glConfig.ARBFragmentProgramAvailable ) {
  2118. common->Printf( "Not available.\n" );
  2119. return;
  2120. }
  2121. RB_CreateBloomTable();
  2122. #if 0
  2123. if ( !R_CheckExtension( "GL_NV_float_buffer" ) ) {
  2124. common->Printf( "Not available.\n" );
  2125. return;
  2126. }
  2127. if ( !R_CheckExtension( "GL_NV_texture_rectangle" ) ) {
  2128. common->Printf( "Not available.\n" );
  2129. return;
  2130. }
  2131. #endif
  2132. #if 0
  2133. qglCombinerParameterfvNV = (void (APIENTRY *)( GLenum pname, const GLfloat *params ))
  2134. GLimp_ExtensionPointer( "glCombinerParameterfvNV" );
  2135. #endif
  2136. common->Printf( "Available.\n" );
  2137. if ( !idStr::Icmp( r_renderer.GetString(), "exp" ) ) {
  2138. R_Exp_Allocate();
  2139. }
  2140. common->Printf( "--------------------------------------------\n" );
  2141. glConfig.allowExpPath = true;
  2142. }