123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- 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.
- ===========================================================================
- */
- #pragma hdrstop
- #include "../idlib/precompiled.h"
- #include "tr_local.h"
- // Vista OpenGL wrapper check
- #include "../sys/win32/win_local.h"
- // DeviceContext bypasses RenderSystem to work directly with this
- idGuiModel * tr_guiModel;
- // functions that are not called every frame
- glconfig_t glConfig;
- idCVar r_requestStereoPixelFormat( "r_requestStereoPixelFormat", "1", CVAR_RENDERER, "Ask for a stereo GL pixel format on startup" );
- idCVar r_debugContext( "r_debugContext", "0", CVAR_RENDERER, "Enable various levels of context debug." );
- idCVar r_glDriver( "r_glDriver", "", CVAR_RENDERER, "\"opengl32\", etc." );
- idCVar r_skipIntelWorkarounds( "r_skipIntelWorkarounds", "0", CVAR_RENDERER | CVAR_BOOL, "skip workarounds for Intel driver bugs" );
- idCVar r_multiSamples( "r_multiSamples", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "number of antialiasing samples" );
- idCVar r_vidMode( "r_vidMode", "0", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_INTEGER, "fullscreen video mode number" );
- idCVar r_displayRefresh( "r_displayRefresh", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_NOCHEAT, "optional display refresh rate option for vid mode", 0.0f, 240.0f );
- idCVar r_fullscreen( "r_fullscreen", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = windowed, 1 = full screen on monitor 1, 2 = full screen on monitor 2, etc" );
- idCVar r_customWidth( "r_customWidth", "1280", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen width. set r_vidMode to -1 to activate" );
- idCVar r_customHeight( "r_customHeight", "720", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen height. set r_vidMode to -1 to activate" );
- idCVar r_windowX( "r_windowX", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "Non-fullscreen parameter" );
- idCVar r_windowY( "r_windowY", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "Non-fullscreen parameter" );
- idCVar r_windowWidth( "r_windowWidth", "1280", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "Non-fullscreen parameter" );
- idCVar r_windowHeight( "r_windowHeight", "720", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "Non-fullscreen parameter" );
- idCVar r_useViewBypass( "r_useViewBypass", "1", CVAR_RENDERER | CVAR_INTEGER, "bypass a frame of latency to the view" );
- idCVar r_useLightPortalFlow( "r_useLightPortalFlow", "1", CVAR_RENDERER | CVAR_BOOL, "use a more precise area reference determination" );
- idCVar r_singleTriangle( "r_singleTriangle", "0", CVAR_RENDERER | CVAR_BOOL, "only draw a single triangle per primitive" );
- idCVar r_checkBounds( "r_checkBounds", "0", CVAR_RENDERER | CVAR_BOOL, "compare all surface bounds with precalculated ones" );
- idCVar r_useConstantMaterials( "r_useConstantMaterials", "1", CVAR_RENDERER | CVAR_BOOL, "use pre-calculated material registers if possible" );
- idCVar r_useSilRemap( "r_useSilRemap", "1", CVAR_RENDERER | CVAR_BOOL, "consider verts with the same XYZ, but different ST the same for shadows" );
- idCVar r_useNodeCommonChildren( "r_useNodeCommonChildren", "1", CVAR_RENDERER | CVAR_BOOL, "stop pushing reference bounds early when possible" );
- idCVar r_useShadowSurfaceScissor( "r_useShadowSurfaceScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor shadows by the scissor rect of the interaction surfaces" );
- idCVar r_useCachedDynamicModels( "r_useCachedDynamicModels", "1", CVAR_RENDERER | CVAR_BOOL, "cache snapshots of dynamic models" );
- idCVar r_useSeamlessCubeMap( "r_useSeamlessCubeMap", "1", CVAR_RENDERER | CVAR_BOOL, "use ARB_seamless_cube_map if available" );
- idCVar r_useSRGB( "r_useSRGB", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE, "1 = both texture and framebuffer, 2 = framebuffer only, 3 = texture only" );
- idCVar r_maxAnisotropicFiltering( "r_maxAnisotropicFiltering", "8", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "limit aniso filtering" );
- idCVar r_useTrilinearFiltering( "r_useTrilinearFiltering", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "Extra quality filtering" );
- idCVar r_lodBias( "r_lodBias", "0.5", CVAR_RENDERER | CVAR_ARCHIVE, "image lod bias" );
- idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" );
- idCVar r_znear( "r_znear", "3", CVAR_RENDERER | CVAR_FLOAT, "near Z clip plane distance", 0.001f, 200.0f );
- idCVar r_ignoreGLErrors( "r_ignoreGLErrors", "1", CVAR_RENDERER | CVAR_BOOL, "ignore GL errors" );
- idCVar r_swapInterval( "r_swapInterval", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = tear, 1 = swap-tear where available, 2 = always v-sync" );
- idCVar r_gamma( "r_gamma", "1.0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 3.0f );
- idCVar r_brightness( "r_brightness", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 2.0f );
- idCVar r_jitter( "r_jitter", "0", CVAR_RENDERER | CVAR_BOOL, "randomly subpixel jitter the projection matrix" );
- idCVar r_skipStaticInteractions( "r_skipStaticInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "skip interactions created at level load" );
- idCVar r_skipDynamicInteractions( "r_skipDynamicInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "skip interactions created after level load" );
- idCVar r_skipSuppress( "r_skipSuppress", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the per-view suppressions" );
- idCVar r_skipPostProcess( "r_skipPostProcess", "0", CVAR_RENDERER | CVAR_BOOL, "skip all post-process renderings" );
- idCVar r_skipInteractions( "r_skipInteractions", "0", CVAR_RENDERER | CVAR_BOOL, "skip all light/surface interaction drawing" );
- idCVar r_skipDynamicTextures( "r_skipDynamicTextures", "0", CVAR_RENDERER | CVAR_BOOL, "don't dynamically create textures" );
- idCVar r_skipCopyTexture( "r_skipCopyTexture", "0", CVAR_RENDERER | CVAR_BOOL, "do all rendering, but don't actually copyTexSubImage2D" );
- idCVar r_skipBackEnd( "r_skipBackEnd", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw anything" );
- idCVar r_skipRender( "r_skipRender", "0", CVAR_RENDERER | CVAR_BOOL, "skip 3D rendering, but pass 2D" );
- idCVar r_skipRenderContext( "r_skipRenderContext", "0", CVAR_RENDERER | CVAR_BOOL, "NULL the rendering context during backend 3D rendering" );
- idCVar r_skipTranslucent( "r_skipTranslucent", "0", CVAR_RENDERER | CVAR_BOOL, "skip the translucent interaction rendering" );
- idCVar r_skipAmbient( "r_skipAmbient", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all non-interaction drawing" );
- idCVar r_skipNewAmbient( "r_skipNewAmbient", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "bypasses all vertex/fragment program ambient drawing" );
- idCVar r_skipBlendLights( "r_skipBlendLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all blend lights" );
- idCVar r_skipFogLights( "r_skipFogLights", "0", CVAR_RENDERER | CVAR_BOOL, "skip all fog lights" );
- idCVar r_skipDeforms( "r_skipDeforms", "0", CVAR_RENDERER | CVAR_BOOL, "leave all deform materials in their original state" );
- idCVar r_skipFrontEnd( "r_skipFrontEnd", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all front end work, but 2D gui rendering still draws" );
- idCVar r_skipUpdates( "r_skipUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't accept any entity or light updates, making everything static" );
- idCVar r_skipDecals( "r_skipDecals", "0", CVAR_RENDERER | CVAR_BOOL, "skip decal surfaces" );
- idCVar r_skipOverlays( "r_skipOverlays", "0", CVAR_RENDERER | CVAR_BOOL, "skip overlay surfaces" );
- idCVar r_skipSpecular( "r_skipSpecular", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_CHEAT | CVAR_ARCHIVE, "use black for specular1" );
- idCVar r_skipBump( "r_skipBump", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "uses a flat surface instead of the bump map" );
- idCVar r_skipDiffuse( "r_skipDiffuse", "0", CVAR_RENDERER | CVAR_BOOL, "use black for diffuse" );
- idCVar r_skipSubviews( "r_skipSubviews", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = don't render any gui elements on surfaces" );
- idCVar r_skipGuiShaders( "r_skipGuiShaders", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all gui elements on surfaces, 2 = skip drawing but still handle events, 3 = draw but skip events", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_skipParticles( "r_skipParticles", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = skip all particle systems", 0, 1, idCmdSystem::ArgCompletion_Integer<0,1> );
- idCVar r_skipShadows( "r_skipShadows", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "disable shadows" );
- idCVar r_useLightPortalCulling( "r_useLightPortalCulling", "1", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = cull frustum corners to plane, 2 = exact clip the frustum faces", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
- idCVar r_useLightAreaCulling( "r_useLightAreaCulling", "1", CVAR_RENDERER | CVAR_BOOL, "0 = off, 1 = on" );
- idCVar r_useLightScissors( "r_useLightScissors", "3", CVAR_RENDERER | CVAR_INTEGER, "0 = no scissor, 1 = non-clipped scissor, 2 = near-clipped scissor, 3 = fully-clipped scissor", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_useEntityPortalCulling( "r_useEntityPortalCulling", "1", CVAR_RENDERER | CVAR_INTEGER, "0 = none, 1 = cull frustum corners to plane, 2 = exact clip the frustum faces", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
- idCVar r_logFile( "r_logFile", "0", CVAR_RENDERER | CVAR_INTEGER, "number of frames to emit GL logs" );
- idCVar r_clear( "r_clear", "2", CVAR_RENDERER, "force screen clear every frame, 1 = purple, 2 = black, 'r g b' = custom" );
- idCVar r_offsetFactor( "r_offsetfactor", "0", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" );
- idCVar r_offsetUnits( "r_offsetunits", "-600", CVAR_RENDERER | CVAR_FLOAT, "polygon offset parameter" );
- idCVar r_shadowPolygonOffset( "r_shadowPolygonOffset", "-1", CVAR_RENDERER | CVAR_FLOAT, "bias value added to depth test for stencil shadow drawing" );
- idCVar r_shadowPolygonFactor( "r_shadowPolygonFactor", "0", CVAR_RENDERER | CVAR_FLOAT, "scale value for stencil shadow drawing" );
- idCVar r_subviewOnly( "r_subviewOnly", "0", CVAR_RENDERER | CVAR_BOOL, "1 = don't render main view, allowing subviews to be debugged" );
- idCVar r_testGamma( "r_testGamma", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels", 0, 195 );
- idCVar r_testGammaBias( "r_testGammaBias", "0", CVAR_RENDERER | CVAR_FLOAT, "if > 0 draw a grid pattern to test gamma levels" );
- idCVar r_lightScale( "r_lightScale", "3", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_FLOAT, "all light intensities are multiplied by this" );
- idCVar r_flareSize( "r_flareSize", "1", CVAR_RENDERER | CVAR_FLOAT, "scale the flare deforms from the material def" );
- idCVar r_skipPrelightShadows( "r_skipPrelightShadows", "0", CVAR_RENDERER | CVAR_BOOL, "skip the dmap generated static shadow volumes" );
- idCVar r_useScissor( "r_useScissor", "1", CVAR_RENDERER | CVAR_BOOL, "scissor clip as portals and lights are processed" );
- idCVar r_useLightDepthBounds( "r_useLightDepthBounds", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test on lights to reduce both shadow and interaction fill" );
- idCVar r_useShadowDepthBounds( "r_useShadowDepthBounds", "1", CVAR_RENDERER | CVAR_BOOL, "use depth bounds test on individual shadow volumes to reduce shadow fill" );
- idCVar r_screenFraction( "r_screenFraction", "100", CVAR_RENDERER | CVAR_INTEGER, "for testing fill rate, the resolution of the entire screen can be changed" );
- idCVar r_usePortals( "r_usePortals", "1", CVAR_RENDERER | CVAR_BOOL, " 1 = use portals to perform area culling, otherwise draw everything" );
- idCVar r_singleLight( "r_singleLight", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one light" );
- idCVar r_singleEntity( "r_singleEntity", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one entity" );
- idCVar r_singleSurface( "r_singleSurface", "-1", CVAR_RENDERER | CVAR_INTEGER, "suppress all but one surface on each entity" );
- idCVar r_singleArea( "r_singleArea", "0", CVAR_RENDERER | CVAR_BOOL, "only draw the portal area the view is actually in" );
- idCVar r_orderIndexes( "r_orderIndexes", "1", CVAR_RENDERER | CVAR_BOOL, "perform index reorganization to optimize vertex use" );
- idCVar r_lightAllBackFaces( "r_lightAllBackFaces", "0", CVAR_RENDERER | CVAR_BOOL, "light all the back faces, even when they would be shadowed" );
- // visual debugging info
- idCVar r_showPortals( "r_showPortals", "0", CVAR_RENDERER | CVAR_BOOL, "draw portal outlines in color based on passed / not passed" );
- idCVar r_showUnsmoothedTangents( "r_showUnsmoothedTangents", "0", CVAR_RENDERER | CVAR_BOOL, "if 1, put all nvidia register combiner programming in display lists" );
- idCVar r_showSilhouette( "r_showSilhouette", "0", CVAR_RENDERER | CVAR_BOOL, "highlight edges that are casting shadow planes" );
- idCVar r_showVertexColor( "r_showVertexColor", "0", CVAR_RENDERER | CVAR_BOOL, "draws all triangles with the solid vertex color" );
- idCVar r_showUpdates( "r_showUpdates", "0", CVAR_RENDERER | CVAR_BOOL, "report entity and light updates and ref counts" );
- idCVar r_showDemo( "r_showDemo", "0", CVAR_RENDERER | CVAR_BOOL, "report reads and writes to the demo file" );
- idCVar r_showDynamic( "r_showDynamic", "0", CVAR_RENDERER | CVAR_BOOL, "report stats on dynamic surface generation" );
- idCVar r_showTrace( "r_showTrace", "0", CVAR_RENDERER | CVAR_INTEGER, "show the intersection of an eye trace with the world", idCmdSystem::ArgCompletion_Integer<0,2> );
- idCVar r_showIntensity( "r_showIntensity", "0", CVAR_RENDERER | CVAR_BOOL, "draw the screen colors based on intensity, red = 0, green = 128, blue = 255" );
- idCVar r_showLights( "r_showLights", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = just print volumes numbers, highlighting ones covering the view, 2 = also draw planes of each volume, 3 = also draw edges of each volume", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_showShadows( "r_showShadows", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = visualize the stencil shadow volumes, 2 = draw filled in", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_showLightScissors( "r_showLightScissors", "0", CVAR_RENDERER | CVAR_BOOL, "show light scissor rectangles" );
- idCVar r_showLightCount( "r_showLightCount", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = colors surfaces based on light count, 2 = also count everything through walls, 3 = also print overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_showViewEntitys( "r_showViewEntitys", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = displays the bounding boxes of all view models, 2 = print index numbers" );
- idCVar r_showTris( "r_showTris", "0", CVAR_RENDERER | CVAR_INTEGER, "enables wireframe rendering of the world, 1 = only draw visible ones, 2 = draw all front facing, 3 = draw all, 4 = draw with alpha", 0, 4, idCmdSystem::ArgCompletion_Integer<0,4> );
- idCVar r_showSurfaceInfo( "r_showSurfaceInfo", "0", CVAR_RENDERER | CVAR_BOOL, "show surface material name under crosshair" );
- idCVar r_showNormals( "r_showNormals", "0", CVAR_RENDERER | CVAR_FLOAT, "draws wireframe normals" );
- idCVar r_showMemory( "r_showMemory", "0", CVAR_RENDERER | CVAR_BOOL, "print frame memory utilization" );
- idCVar r_showCull( "r_showCull", "0", CVAR_RENDERER | CVAR_BOOL, "report sphere and box culling stats" );
- idCVar r_showAddModel( "r_showAddModel", "0", CVAR_RENDERER | CVAR_BOOL, "report stats from tr_addModel" );
- idCVar r_showDepth( "r_showDepth", "0", CVAR_RENDERER | CVAR_BOOL, "display the contents of the depth buffer and the depth range" );
- idCVar r_showSurfaces( "r_showSurfaces", "0", CVAR_RENDERER | CVAR_BOOL, "report surface/light/shadow counts" );
- idCVar r_showPrimitives( "r_showPrimitives", "0", CVAR_RENDERER | CVAR_INTEGER, "report drawsurf/index/vertex counts" );
- idCVar r_showEdges( "r_showEdges", "0", CVAR_RENDERER | CVAR_BOOL, "draw the sil edges" );
- idCVar r_showTexturePolarity( "r_showTexturePolarity", "0", CVAR_RENDERER | CVAR_BOOL, "shade triangles by texture area polarity" );
- idCVar r_showTangentSpace( "r_showTangentSpace", "0", CVAR_RENDERER | CVAR_INTEGER, "shade triangles by tangent space, 1 = use 1st tangent vector, 2 = use 2nd tangent vector, 3 = use normal vector", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_showDominantTri( "r_showDominantTri", "0", CVAR_RENDERER | CVAR_BOOL, "draw lines from vertexes to center of dominant triangles" );
- idCVar r_showTextureVectors( "r_showTextureVectors", "0", CVAR_RENDERER | CVAR_FLOAT, " if > 0 draw each triangles texture (tangent) vectors" );
- idCVar r_showOverDraw( "r_showOverDraw", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0,3> );
- idCVar r_useEntityCallbacks( "r_useEntityCallbacks", "1", CVAR_RENDERER | CVAR_BOOL, "if 0, issue the callback immediately at update time, rather than defering" );
- idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "draw the skeleton when model animates, 1 = draw model with skeleton, 2 = draw skeleton only", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
- idCVar r_jointNameScale( "r_jointNameScale", "0.02", CVAR_RENDERER | CVAR_FLOAT, "size of joint names when r_showskel is set to 1" );
- idCVar r_jointNameOffset( "r_jointNameOffset", "0.5", CVAR_RENDERER | CVAR_FLOAT, "offset of joint names when r_showskel is set to 1" );
- idCVar r_debugLineDepthTest( "r_debugLineDepthTest", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "perform depth test on debug lines" );
- idCVar r_debugLineWidth( "r_debugLineWidth", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "width of debug lines" );
- idCVar r_debugArrowStep( "r_debugArrowStep", "120", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "step size of arrow cone line rotation in degrees", 0, 120 );
- idCVar r_debugPolygonFilled( "r_debugPolygonFilled", "1", CVAR_RENDERER | CVAR_BOOL, "draw a filled polygon" );
- idCVar r_materialOverride( "r_materialOverride", "", CVAR_RENDERER, "overrides all materials", idCmdSystem::ArgCompletion_Decl<DECL_MATERIAL> );
- idCVar r_debugRenderToTexture( "r_debugRenderToTexture", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
- idCVar stereoRender_enable( "stereoRender_enable", "0", CVAR_INTEGER | CVAR_ARCHIVE, "1 = side-by-side compressed, 2 = top and bottom compressed, 3 = side-by-side, 4 = 720 frame packed, 5 = interlaced, 6 = OpenGL quad buffer" );
- idCVar stereoRender_swapEyes( "stereoRender_swapEyes", "0", CVAR_BOOL | CVAR_ARCHIVE, "reverse eye adjustments" );
- idCVar stereoRender_deGhost( "stereoRender_deGhost", "0.05", CVAR_FLOAT | CVAR_ARCHIVE, "subtract from opposite eye to reduce ghosting" );
- // GL_ARB_multitexture
- PFNGLACTIVETEXTUREPROC qglActiveTextureARB;
- PFNGLCLIENTACTIVETEXTUREPROC qglClientActiveTextureARB;
- // GL_EXT_direct_state_access
- PFNGLBINDMULTITEXTUREEXTPROC qglBindMultiTextureEXT;
- // GL_ARB_texture_compression
- PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
- PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC qglCompressedTexSubImage2DARB;
- PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
- // GL_ARB_vertex_buffer_object
- PFNGLBINDBUFFERARBPROC qglBindBufferARB;
- PFNGLBINDBUFFERRANGEPROC qglBindBufferRange;
- PFNGLDELETEBUFFERSARBPROC qglDeleteBuffersARB;
- PFNGLGENBUFFERSARBPROC qglGenBuffersARB;
- PFNGLISBUFFERARBPROC qglIsBufferARB;
- PFNGLBUFFERDATAARBPROC qglBufferDataARB;
- PFNGLBUFFERSUBDATAARBPROC qglBufferSubDataARB;
- PFNGLGETBUFFERSUBDATAARBPROC qglGetBufferSubDataARB;
- PFNGLMAPBUFFERARBPROC qglMapBufferARB;
- PFNGLUNMAPBUFFERARBPROC qglUnmapBufferARB;
- PFNGLGETBUFFERPARAMETERIVARBPROC qglGetBufferParameterivARB;
- PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB;
- // GL_ARB_map_buffer_range
- PFNGLMAPBUFFERRANGEPROC qglMapBufferRange;
- // GL_ARB_draw_elements_base_vertex
- PFNGLDRAWELEMENTSBASEVERTEXPROC qglDrawElementsBaseVertex;
- // GL_ARB_vertex_array_object
- PFNGLGENVERTEXARRAYSPROC qglGenVertexArrays;
- PFNGLBINDVERTEXARRAYPROC qglBindVertexArray;
- PFNGLDELETEVERTEXARRAYSPROC qglDeleteVertexArrays;
- // GL_ARB_vertex_program / GL_ARB_fragment_program
- PFNGLVERTEXATTRIBPOINTERARBPROC qglVertexAttribPointerARB;
- PFNGLENABLEVERTEXATTRIBARRAYARBPROC qglEnableVertexAttribArrayARB;
- PFNGLDISABLEVERTEXATTRIBARRAYARBPROC qglDisableVertexAttribArrayARB;
- PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
- PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
- PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
- PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB;
- PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB;
- PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB;
- // GLSL / OpenGL 2.0
- PFNGLCREATESHADERPROC qglCreateShader;
- PFNGLDELETESHADERPROC qglDeleteShader;
- PFNGLSHADERSOURCEPROC qglShaderSource;
- PFNGLCOMPILESHADERPROC qglCompileShader;
- PFNGLGETSHADERIVPROC qglGetShaderiv;
- PFNGLGETSHADERINFOLOGPROC qglGetShaderInfoLog;
- PFNGLCREATEPROGRAMPROC qglCreateProgram;
- PFNGLDELETEPROGRAMPROC qglDeleteProgram;
- PFNGLATTACHSHADERPROC qglAttachShader;
- PFNGLDETACHSHADERPROC qglDetachShader;
- PFNGLLINKPROGRAMPROC qglLinkProgram;
- PFNGLUSEPROGRAMPROC qglUseProgram;
- PFNGLGETPROGRAMIVPROC qglGetProgramiv;
- PFNGLGETPROGRAMINFOLOGPROC qglGetProgramInfoLog;
- PFNGLPROGRAMPARAMETERIPROC qglProgramParameteri;
- PFNGLBINDATTRIBLOCATIONPROC qglBindAttribLocation;
- PFNGLGETUNIFORMLOCATIONPROC qglGetUniformLocation;
- PFNGLUNIFORM1IPROC qglUniform1i;
- PFNGLUNIFORM4FVPROC qglUniform4fv;
- // GL_ARB_uniform_buffer_object
- PFNGLGETUNIFORMBLOCKINDEXPROC qglGetUniformBlockIndex;
- PFNGLUNIFORMBLOCKBINDINGPROC qglUniformBlockBinding;
- // GL_ATI_separate_stencil / OpenGL 2.0
- PFNGLSTENCILOPSEPARATEATIPROC qglStencilOpSeparate;
- PFNGLSTENCILFUNCSEPARATEATIPROC qglStencilFuncSeparate;
- // GL_EXT_depth_bounds_test
- PFNGLDEPTHBOUNDSEXTPROC qglDepthBoundsEXT;
- // GL_ARB_sync
- PFNGLFENCESYNCPROC qglFenceSync;
- PFNGLISSYNCPROC qglIsSync;
- PFNGLCLIENTWAITSYNCPROC qglClientWaitSync;
- PFNGLDELETESYNCPROC qglDeleteSync;
- // GL_ARB_occlusion_query
- PFNGLGENQUERIESARBPROC qglGenQueriesARB;
- PFNGLDELETEQUERIESARBPROC qglDeleteQueriesARB;
- PFNGLISQUERYARBPROC qglIsQueryARB;
- PFNGLBEGINQUERYARBPROC qglBeginQueryARB;
- PFNGLENDQUERYARBPROC qglEndQueryARB;
- PFNGLGETQUERYIVARBPROC qglGetQueryivARB;
- PFNGLGETQUERYOBJECTIVARBPROC qglGetQueryObjectivARB;
- PFNGLGETQUERYOBJECTUIVARBPROC qglGetQueryObjectuivARB;
- // GL_ARB_timer_query / GL_EXT_timer_query
- PFNGLGETQUERYOBJECTUI64VEXTPROC qglGetQueryObjectui64vEXT;
- // GL_ARB_debug_output
- PFNGLDEBUGMESSAGECONTROLARBPROC qglDebugMessageControlARB;
- PFNGLDEBUGMESSAGEINSERTARBPROC qglDebugMessageInsertARB;
- PFNGLDEBUGMESSAGECALLBACKARBPROC qglDebugMessageCallbackARB;
- PFNGLGETDEBUGMESSAGELOGARBPROC qglGetDebugMessageLogARB;
- PFNGLGETSTRINGIPROC qglGetStringi;
- /*
- ========================
- glBindMultiTextureEXT
- As of 2011/09/16 the Intel drivers for "Sandy Bridge" and "Ivy Bridge" integrated graphics do not support this extension.
- ========================
- */
- void APIENTRY glBindMultiTextureEXT( GLenum texunit, GLenum target, GLuint texture ) {
- qglActiveTextureARB( texunit );
- qglBindTexture( target, texture );
- }
- /*
- =================
- R_CheckExtension
- =================
- */
- bool R_CheckExtension( char *name ) {
- if ( !strstr( glConfig.extensions_string, name ) ) {
- common->Printf( "X..%s not found\n", name );
- return false;
- }
- common->Printf( "...using %s\n", name );
- return true;
- }
- /*
- ========================
- DebugCallback
- For ARB_debug_output
- ========================
- */
- static void CALLBACK DebugCallback(unsigned int source, unsigned int type,
- unsigned int id, unsigned int severity, int length, const char * message, void * userParam) {
- // it probably isn't safe to do an idLib::Printf at this point
- OutputDebugString( message );
- OutputDebugString( "\n" );
- }
- /*
- ==================
- R_CheckPortableExtensions
- ==================
- */
- static void R_CheckPortableExtensions() {
- glConfig.glVersion = atof( glConfig.version_string );
- const char * badVideoCard = idLocalization::GetString( "#str_06780" );
- if ( glConfig.glVersion < 2.0f ) {
- idLib::FatalError( badVideoCard );
- }
- if ( idStr::Icmpn( glConfig.renderer_string, "ATI ", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "AMD ", 4 ) == 0 ) {
- glConfig.vendor = VENDOR_AMD;
- } else if ( idStr::Icmpn( glConfig.renderer_string, "NVIDIA", 6 ) == 0 ) {
- glConfig.vendor = VENDOR_NVIDIA;
- } else if ( idStr::Icmpn( glConfig.renderer_string, "Intel", 5 ) == 0 ) {
- glConfig.vendor = VENDOR_INTEL;
- }
- // GL_ARB_multitexture
- glConfig.multitextureAvailable = R_CheckExtension( "GL_ARB_multitexture" );
- if ( glConfig.multitextureAvailable ) {
- qglActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glActiveTextureARB" );
- qglClientActiveTextureARB = (void(APIENTRY *)(GLenum))GLimp_ExtensionPointer( "glClientActiveTextureARB" );
- }
- // GL_EXT_direct_state_access
- glConfig.directStateAccess = R_CheckExtension( "GL_EXT_direct_state_access" );
- if ( glConfig.directStateAccess ) {
- qglBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)GLimp_ExtensionPointer( "glBindMultiTextureEXT" );
- } else {
- qglBindMultiTextureEXT = glBindMultiTextureEXT;
- }
- // GL_ARB_texture_compression + GL_S3_s3tc
- // DRI drivers may have GL_ARB_texture_compression but no GL_EXT_texture_compression_s3tc
- glConfig.textureCompressionAvailable = R_CheckExtension( "GL_ARB_texture_compression" ) && R_CheckExtension( "GL_EXT_texture_compression_s3tc" );
- if ( glConfig.textureCompressionAvailable ) {
- qglCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)GLimp_ExtensionPointer( "glCompressedTexImage2DARB" );
- qglCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)GLimp_ExtensionPointer( "glCompressedTexSubImage2DARB" );
- qglGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)GLimp_ExtensionPointer( "glGetCompressedTexImageARB" );
- }
- // GL_EXT_texture_filter_anisotropic
- glConfig.anisotropicFilterAvailable = R_CheckExtension( "GL_EXT_texture_filter_anisotropic" );
- if ( glConfig.anisotropicFilterAvailable ) {
- qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxTextureAnisotropy );
- common->Printf( " maxTextureAnisotropy: %f\n", glConfig.maxTextureAnisotropy );
- } else {
- glConfig.maxTextureAnisotropy = 1;
- }
- // GL_EXT_texture_lod_bias
- // The actual extension is broken as specificed, storing the state in the texture unit instead
- // of the texture object. The behavior in GL 1.4 is the behavior we use.
- glConfig.textureLODBiasAvailable = ( glConfig.glVersion >= 1.4 || R_CheckExtension( "GL_EXT_texture_lod_bias" ) );
- if ( glConfig.textureLODBiasAvailable ) {
- common->Printf( "...using %s\n", "GL_EXT_texture_lod_bias" );
- } else {
- common->Printf( "X..%s not found\n", "GL_EXT_texture_lod_bias" );
- }
- // GL_ARB_seamless_cube_map
- glConfig.seamlessCubeMapAvailable = R_CheckExtension( "GL_ARB_seamless_cube_map" );
- r_useSeamlessCubeMap.SetModified(); // the CheckCvars() next frame will enable / disable it
- // GL_ARB_framebuffer_sRGB
- glConfig.sRGBFramebufferAvailable = R_CheckExtension( "GL_ARB_framebuffer_sRGB" );
- r_useSRGB.SetModified(); // the CheckCvars() next frame will enable / disable it
- // GL_ARB_vertex_buffer_object
- glConfig.vertexBufferObjectAvailable = R_CheckExtension( "GL_ARB_vertex_buffer_object" );
- if ( glConfig.vertexBufferObjectAvailable ) {
- qglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLimp_ExtensionPointer( "glBindBufferARB" );
- qglBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)GLimp_ExtensionPointer( "glBindBufferRange" );
- qglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLimp_ExtensionPointer( "glDeleteBuffersARB" );
- qglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLimp_ExtensionPointer( "glGenBuffersARB" );
- qglIsBufferARB = (PFNGLISBUFFERARBPROC)GLimp_ExtensionPointer( "glIsBufferARB" );
- qglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLimp_ExtensionPointer( "glBufferDataARB" );
- qglBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glBufferSubDataARB" );
- qglGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLimp_ExtensionPointer( "glGetBufferSubDataARB" );
- qglMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glMapBufferARB" );
- qglUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLimp_ExtensionPointer( "glUnmapBufferARB" );
- qglGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLimp_ExtensionPointer( "glGetBufferParameterivARB" );
- qglGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLimp_ExtensionPointer( "glGetBufferPointervARB" );
- }
- // GL_ARB_map_buffer_range, map a section of a buffer object's data store
- glConfig.mapBufferRangeAvailable = R_CheckExtension( "GL_ARB_map_buffer_range" );
- if ( glConfig.mapBufferRangeAvailable ) {
- qglMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)GLimp_ExtensionPointer( "glMapBufferRange" );
- }
- // GL_ARB_vertex_array_object
- glConfig.vertexArrayObjectAvailable = R_CheckExtension( "GL_ARB_vertex_array_object" );
- if ( glConfig.vertexArrayObjectAvailable ) {
- qglGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GLimp_ExtensionPointer( "glGenVertexArrays" );
- qglBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GLimp_ExtensionPointer( "glBindVertexArray" );
- qglDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GLimp_ExtensionPointer( "glDeleteVertexArrays" );
- }
- // GL_ARB_draw_elements_base_vertex
- glConfig.drawElementsBaseVertexAvailable = R_CheckExtension( "GL_ARB_draw_elements_base_vertex" );
- if ( glConfig.drawElementsBaseVertexAvailable ) {
- qglDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)GLimp_ExtensionPointer( "glDrawElementsBaseVertex" );
- }
- // GL_ARB_vertex_program / GL_ARB_fragment_program
- glConfig.fragmentProgramAvailable = R_CheckExtension( "GL_ARB_fragment_program" );
- if ( glConfig.fragmentProgramAvailable ) {
- qglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GLimp_ExtensionPointer( "glVertexAttribPointerARB" );
- qglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glEnableVertexAttribArrayARB" );
- qglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GLimp_ExtensionPointer( "glDisableVertexAttribArrayARB" );
- qglProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)GLimp_ExtensionPointer( "glProgramStringARB" );
- qglBindProgramARB = (PFNGLBINDPROGRAMARBPROC)GLimp_ExtensionPointer( "glBindProgramARB" );
- qglGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)GLimp_ExtensionPointer( "glGenProgramsARB" );
- qglDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)GLimp_ExtensionPointer( "glDeleteProgramsARB" );
- qglProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramEnvParameter4fvARB" );
- qglProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)GLimp_ExtensionPointer( "glProgramLocalParameter4fvARB" );
- qglGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, (GLint *)&glConfig.maxTextureCoords );
- qglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (GLint *)&glConfig.maxTextureImageUnits );
- }
- // GLSL, core in OpenGL > 2.0
- glConfig.glslAvailable = ( glConfig.glVersion >= 2.0f );
- if ( glConfig.glslAvailable ) {
- qglCreateShader = (PFNGLCREATESHADERPROC)GLimp_ExtensionPointer( "glCreateShader" );
- qglDeleteShader = (PFNGLDELETESHADERPROC)GLimp_ExtensionPointer( "glDeleteShader" );
- qglShaderSource = (PFNGLSHADERSOURCEPROC)GLimp_ExtensionPointer( "glShaderSource" );
- qglCompileShader = (PFNGLCOMPILESHADERPROC)GLimp_ExtensionPointer( "glCompileShader" );
- qglGetShaderiv = (PFNGLGETSHADERIVPROC)GLimp_ExtensionPointer( "glGetShaderiv" );
- qglGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GLimp_ExtensionPointer( "glGetShaderInfoLog" );
- qglCreateProgram = (PFNGLCREATEPROGRAMPROC)GLimp_ExtensionPointer( "glCreateProgram" );
- qglDeleteProgram = (PFNGLDELETEPROGRAMPROC)GLimp_ExtensionPointer( "glDeleteProgram" );
- qglAttachShader = (PFNGLATTACHSHADERPROC)GLimp_ExtensionPointer( "glAttachShader" );
- qglDetachShader = (PFNGLDETACHSHADERPROC)GLimp_ExtensionPointer( "glDetachShader" );
- qglLinkProgram = (PFNGLLINKPROGRAMPROC)GLimp_ExtensionPointer( "glLinkProgram" );
- qglUseProgram = (PFNGLUSEPROGRAMPROC)GLimp_ExtensionPointer( "glUseProgram" );
- qglGetProgramiv = (PFNGLGETPROGRAMIVPROC)GLimp_ExtensionPointer( "glGetProgramiv" );
- qglGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GLimp_ExtensionPointer( "glGetProgramInfoLog" );
- qglBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)GLimp_ExtensionPointer( "glBindAttribLocation" );
- qglGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)GLimp_ExtensionPointer( "glGetUniformLocation" );
- qglUniform1i = (PFNGLUNIFORM1IPROC)GLimp_ExtensionPointer( "glUniform1i" );
- qglUniform4fv = (PFNGLUNIFORM4FVPROC)GLimp_ExtensionPointer( "glUniform4fv" );
- }
- // GL_ARB_uniform_buffer_object
- glConfig.uniformBufferAvailable = R_CheckExtension( "GL_ARB_uniform_buffer_object" );
- if ( glConfig.uniformBufferAvailable ) {
- qglGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)GLimp_ExtensionPointer( "glGetUniformBlockIndex" );
- qglUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)GLimp_ExtensionPointer( "glUniformBlockBinding" );
- qglGetIntegerv( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, (GLint *)&glConfig.uniformBufferOffsetAlignment );
- if ( glConfig.uniformBufferOffsetAlignment < 256 ) {
- glConfig.uniformBufferOffsetAlignment = 256;
- }
- }
- // ATI_separate_stencil / OpenGL 2.0 separate stencil
- glConfig.twoSidedStencilAvailable = ( glConfig.glVersion >= 2.0f ) || R_CheckExtension( "GL_ATI_separate_stencil" );
- if ( glConfig.twoSidedStencilAvailable ) {
- qglStencilOpSeparate = (PFNGLSTENCILOPSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilOpSeparate" );
- qglStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEATIPROC)GLimp_ExtensionPointer( "glStencilFuncSeparate" );
- }
- // GL_EXT_depth_bounds_test
- glConfig.depthBoundsTestAvailable = R_CheckExtension( "GL_EXT_depth_bounds_test" );
- if ( glConfig.depthBoundsTestAvailable ) {
- qglDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)GLimp_ExtensionPointer( "glDepthBoundsEXT" );
- }
- // GL_ARB_sync
- glConfig.syncAvailable = R_CheckExtension( "GL_ARB_sync" ) &&
- // as of 5/24/2012 (driver version 15.26.12.64.2761) sync objects
- // do not appear to work for the Intel HD 4000 graphics
- ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() );
- if ( glConfig.syncAvailable ) {
- qglFenceSync = (PFNGLFENCESYNCPROC)GLimp_ExtensionPointer( "glFenceSync" );
- qglIsSync = (PFNGLISSYNCPROC)GLimp_ExtensionPointer( "glIsSync" );
- qglClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)GLimp_ExtensionPointer( "glClientWaitSync" );
- qglDeleteSync = (PFNGLDELETESYNCPROC)GLimp_ExtensionPointer( "glDeleteSync" );
- }
- // GL_ARB_occlusion_query
- glConfig.occlusionQueryAvailable = R_CheckExtension( "GL_ARB_occlusion_query" );
- if ( glConfig.occlusionQueryAvailable ) {
- // defined in GL_ARB_occlusion_query, which is required for GL_EXT_timer_query
- qglGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLimp_ExtensionPointer( "glGenQueriesARB" );
- qglDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLimp_ExtensionPointer( "glDeleteQueriesARB" );
- qglIsQueryARB = (PFNGLISQUERYARBPROC)GLimp_ExtensionPointer( "glIsQueryARB" );
- qglBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLimp_ExtensionPointer( "glBeginQueryARB" );
- qglEndQueryARB = (PFNGLENDQUERYARBPROC)GLimp_ExtensionPointer( "glEndQueryARB" );
- qglGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLimp_ExtensionPointer( "glGetQueryivARB" );
- qglGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLimp_ExtensionPointer( "glGetQueryObjectivARB" );
- qglGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLimp_ExtensionPointer( "glGetQueryObjectuivARB" );
- }
- // GL_ARB_timer_query
- glConfig.timerQueryAvailable = R_CheckExtension( "GL_ARB_timer_query" ) || R_CheckExtension( "GL_EXT_timer_query" );
- if ( glConfig.timerQueryAvailable ) {
- qglGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLimp_ExtensionPointer( "glGetQueryObjectui64vARB" );
- if ( qglGetQueryObjectui64vEXT == NULL ) {
- qglGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLimp_ExtensionPointer( "glGetQueryObjectui64vEXT" );
- }
- }
- // GL_ARB_debug_output
- glConfig.debugOutputAvailable = R_CheckExtension( "GL_ARB_debug_output" );
- if ( glConfig.debugOutputAvailable ) {
- qglDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)GLimp_ExtensionPointer( "glDebugMessageControlARB" );
- qglDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)GLimp_ExtensionPointer( "glDebugMessageInsertARB" );
- qglDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)GLimp_ExtensionPointer( "glDebugMessageCallbackARB" );
- qglGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)GLimp_ExtensionPointer( "glGetDebugMessageLogARB" );
- if ( r_debugContext.GetInteger() >= 1 ) {
- qglDebugMessageCallbackARB( DebugCallback, NULL );
- }
- if ( r_debugContext.GetInteger() >= 2 ) {
- // force everything to happen in the main thread instead of in a separate driver thread
- glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB );
- }
- if ( r_debugContext.GetInteger() >= 3 ) {
- // enable all the low priority messages
- qglDebugMessageControlARB( GL_DONT_CARE,
- GL_DONT_CARE,
- GL_DEBUG_SEVERITY_LOW_ARB,
- 0, NULL, true );
- }
- }
- // GL_ARB_multitexture
- if ( !glConfig.multitextureAvailable ) {
- idLib::Error( "GL_ARB_multitexture not available" );
- }
- // GL_ARB_texture_compression + GL_EXT_texture_compression_s3tc
- if ( !glConfig.textureCompressionAvailable ) {
- idLib::Error( "GL_ARB_texture_compression or GL_EXT_texture_compression_s3tc not available" );
- }
- // GL_ARB_vertex_buffer_object
- if ( !glConfig.vertexBufferObjectAvailable ) {
- idLib::Error( "GL_ARB_vertex_buffer_object not available" );
- }
- // GL_ARB_map_buffer_range
- if ( !glConfig.mapBufferRangeAvailable ) {
- idLib::Error( "GL_ARB_map_buffer_range not available" );
- }
- // GL_ARB_vertex_array_object
- if ( !glConfig.vertexArrayObjectAvailable ) {
- idLib::Error( "GL_ARB_vertex_array_object not available" );
- }
- // GL_ARB_draw_elements_base_vertex
- if ( !glConfig.drawElementsBaseVertexAvailable ) {
- idLib::Error( "GL_ARB_draw_elements_base_vertex not available" );
- }
- // GL_ARB_vertex_program / GL_ARB_fragment_program
- if ( !glConfig.fragmentProgramAvailable ) {
- idLib::Error( "GL_ARB_fragment_program not available" );
- }
- // GLSL
- if ( !glConfig.glslAvailable ) {
- idLib::Error( "GLSL not available" );
- }
- // GL_ARB_uniform_buffer_object
- if ( !glConfig.uniformBufferAvailable ) {
- idLib::Error( "GL_ARB_uniform_buffer_object not available" );
- }
- // GL_EXT_stencil_two_side
- if ( !glConfig.twoSidedStencilAvailable ) {
- idLib::Error( "GL_ATI_separate_stencil not available" );
- }
- // generate one global Vertex Array Object (VAO)
- qglGenVertexArrays( 1, &glConfig.global_vao );
- qglBindVertexArray( glConfig.global_vao );
- }
- static bool r_initialized = false;
- /*
- =============================
- R_IsInitialized
- =============================
- */
- bool R_IsInitialized() {
- return r_initialized;
- }
- /*
- =============================
- R_SetNewMode
- r_fullScreen -1 borderless window at exact desktop coordinates
- r_fullScreen 0 bordered window at exact desktop coordinates
- r_fullScreen 1 fullscreen on monitor 1 at r_vidMode
- r_fullScreen 2 fullscreen on monitor 2 at r_vidMode
- ...
- r_vidMode -1 use r_customWidth / r_customHeight, even if they don't appear on the mode list
- r_vidMode 0 use first mode returned by EnumDisplaySettings()
- r_vidMode 1 use second mode returned by EnumDisplaySettings()
- ...
- r_displayRefresh 0 don't specify refresh
- r_displayRefresh 70 specify 70 hz, etc
- =============================
- */
- void R_SetNewMode( const bool fullInit ) {
- // try up to three different configurations
- for ( int i = 0 ; i < 3 ; i++ ) {
- if ( i == 0 && stereoRender_enable.GetInteger() != STEREO3D_QUAD_BUFFER ) {
- continue; // don't even try for a stereo mode
- }
- glimpParms_t parms;
- if ( r_fullscreen.GetInteger() <= 0 ) {
- // use explicit position / size for window
- parms.x = r_windowX.GetInteger();
- parms.y = r_windowY.GetInteger();
- parms.width = r_windowWidth.GetInteger();
- parms.height = r_windowHeight.GetInteger();
- // may still be -1 to force a borderless window
- parms.fullScreen = r_fullscreen.GetInteger();
- parms.displayHz = 0; // ignored
- } else {
- // get the mode list for this monitor
- idList<vidMode_t> modeList;
- if ( !R_GetModeListForDisplay( r_fullscreen.GetInteger()-1, modeList ) ) {
- idLib::Printf( "r_fullscreen reset from %i to 1 because mode list failed.", r_fullscreen.GetInteger() );
- r_fullscreen.SetInteger( 1 );
- R_GetModeListForDisplay( r_fullscreen.GetInteger()-1, modeList );
- }
- if ( modeList.Num() < 1 ) {
- idLib::Printf( "Going to safe mode because mode list failed." );
- goto safeMode;
- }
- parms.x = 0; // ignored
- parms.y = 0; // ignored
- parms.fullScreen = r_fullscreen.GetInteger();
- // set the parameters we are trying
- if ( r_vidMode.GetInteger() < 0 ) {
- // try forcing a specific mode, even if it isn't on the list
- parms.width = r_customWidth.GetInteger();
- parms.height = r_customHeight.GetInteger();
- parms.displayHz = r_displayRefresh.GetInteger();
- } else {
- if ( r_vidMode.GetInteger() > modeList.Num() ) {
- idLib::Printf( "r_vidMode reset from %i to 0.\n", r_vidMode.GetInteger() );
- r_vidMode.SetInteger( 0 );
- }
- parms.width = modeList[ r_vidMode.GetInteger() ].width;
- parms.height = modeList[ r_vidMode.GetInteger() ].height;
- parms.displayHz = modeList[ r_vidMode.GetInteger() ].displayHz;
- }
- }
- parms.multiSamples = r_multiSamples.GetInteger();
- if ( i == 0 ) {
- parms.stereo = ( stereoRender_enable.GetInteger() == STEREO3D_QUAD_BUFFER );
- } else {
- parms.stereo = false;
- }
- if ( fullInit ) {
- // create the context as well as setting up the window
- if ( GLimp_Init( parms ) ) {
- // it worked
- break;
- }
- } else {
- // just rebuild the window
- if ( GLimp_SetScreenParms( parms ) ) {
- // it worked
- break;
- }
- }
- if ( i == 2 ) {
- common->FatalError( "Unable to initialize OpenGL" );
- }
- if ( i == 0 ) {
- // same settings, no stereo
- continue;
- }
- safeMode:
- // if we failed, set everything back to "safe mode"
- // and try again
- r_vidMode.SetInteger( 0 );
- r_fullscreen.SetInteger( 1 );
- r_displayRefresh.SetInteger( 0 );
- r_multiSamples.SetInteger( 0 );
- }
- }
- idStr extensions_string;
- /*
- ==================
- R_InitOpenGL
- This function is responsible for initializing a valid OpenGL subsystem
- for rendering. This is done by calling the system specific GLimp_Init,
- which gives us a working OGL subsystem, then setting all necessary openGL
- state, including images, vertex programs, and display lists.
- Changes to the vertex cache size or smp state require a vid_restart.
- If R_IsInitialized() is false, no rendering can take place, but
- all renderSystem functions will still operate properly, notably the material
- and model information functions.
- ==================
- */
- void R_InitOpenGL() {
- common->Printf( "----- R_InitOpenGL -----\n" );
- if ( R_IsInitialized() ) {
- common->FatalError( "R_InitOpenGL called while active" );
- }
- R_SetNewMode( true );
- // input and sound systems need to be tied to the new window
- Sys_InitInput();
- // get our config strings
- glConfig.vendor_string = (const char *)qglGetString( GL_VENDOR );
- glConfig.renderer_string = (const char *)qglGetString( GL_RENDERER );
- glConfig.version_string = (const char *)qglGetString( GL_VERSION );
- glConfig.shading_language_string = (const char *)qglGetString( GL_SHADING_LANGUAGE_VERSION );
- glConfig.extensions_string = (const char *)qglGetString( GL_EXTENSIONS );
- if ( glConfig.extensions_string == NULL ) {
- // As of OpenGL 3.2, glGetStringi is required to obtain the available extensions
- qglGetStringi = (PFNGLGETSTRINGIPROC)GLimp_ExtensionPointer( "glGetStringi" );
- // Build the extensions string
- GLint numExtensions;
- qglGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions );
- extensions_string.Clear();
- for ( int i = 0; i < numExtensions; i++ ) {
- extensions_string.Append( (const char*)qglGetStringi( GL_EXTENSIONS, i ) );
- // the now deprecated glGetString method usaed to create a single string with each extension separated by a space
- if ( i < numExtensions - 1 ) {
- extensions_string.Append( ' ' );
- }
- }
- glConfig.extensions_string = extensions_string.c_str();
- }
- float glVersion = atof( glConfig.version_string );
- float glslVersion = atof( glConfig.shading_language_string );
- idLib::Printf( "OpenGL Version: %3.1f\n", glVersion );
- idLib::Printf( "OpenGL Vendor : %s\n", glConfig.vendor_string );
- idLib::Printf( "OpenGL GLSL : %3.1f\n", glslVersion );
-
- // OpenGL driver constants
- GLint temp;
- qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
- glConfig.maxTextureSize = temp;
- // stubbed or broken drivers may have reported 0...
- if ( glConfig.maxTextureSize <= 0 ) {
- glConfig.maxTextureSize = 256;
- }
- r_initialized = true;
- // recheck all the extensions (FIXME: this might be dangerous)
- R_CheckPortableExtensions();
- renderProgManager.Init();
- r_initialized = true;
- // allocate the vertex array range or vertex objects
- vertexCache.Init();
- // allocate the frame data, which may be more if smp is enabled
- R_InitFrameData();
- // Reset our gamma
- R_SetColorMappings();
- static bool glCheck = false;
- if ( !glCheck && win32.osversion.dwMajorVersion == 6 ) {
- glCheck = true;
- if ( !idStr::Icmp( glConfig.vendor_string, "Microsoft" ) && idStr::FindText( glConfig.renderer_string, "OpenGL-D3D" ) != -1 ) {
- if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
- cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" );
- Sys_GrabMouseCursor( false );
- }
- int ret = MessageBox( NULL, "Please install OpenGL drivers from your graphics hardware vendor to run " GAME_NAME ".\nYour OpenGL functionality is limited.",
- "Insufficient OpenGL capabilities", MB_OKCANCEL | MB_ICONWARNING | MB_TASKMODAL );
- if ( ret == IDCANCEL ) {
- cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" );
- cmdSystem->ExecuteCommandBuffer();
- }
- if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
- cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "vid_restart\n" );
- }
- }
- }
- }
- /*
- ==================
- GL_CheckErrors
- ==================
- */
- void GL_CheckErrors() {
- int err;
- char s[64];
- int i;
- // check for up to 10 errors pending
- for ( i = 0 ; i < 10 ; i++ ) {
- err = qglGetError();
- if ( err == GL_NO_ERROR ) {
- return;
- }
- switch( err ) {
- case GL_INVALID_ENUM:
- strcpy( s, "GL_INVALID_ENUM" );
- break;
- case GL_INVALID_VALUE:
- strcpy( s, "GL_INVALID_VALUE" );
- break;
- case GL_INVALID_OPERATION:
- strcpy( s, "GL_INVALID_OPERATION" );
- break;
- case GL_STACK_OVERFLOW:
- strcpy( s, "GL_STACK_OVERFLOW" );
- break;
- case GL_STACK_UNDERFLOW:
- strcpy( s, "GL_STACK_UNDERFLOW" );
- break;
- case GL_OUT_OF_MEMORY:
- strcpy( s, "GL_OUT_OF_MEMORY" );
- break;
- default:
- idStr::snPrintf( s, sizeof(s), "%i", err);
- break;
- }
- if ( !r_ignoreGLErrors.GetBool() ) {
- common->Printf( "GL_CheckErrors: %s\n", s );
- }
- }
- }
- /*
- =====================
- R_ReloadSurface_f
- Reload the material displayed by r_showSurfaceInfo
- =====================
- */
- static void R_ReloadSurface_f( const idCmdArgs &args ) {
- modelTrace_t mt;
- idVec3 start, end;
-
- // start far enough away that we don't hit the player model
- start = tr.primaryView->renderView.vieworg + tr.primaryView->renderView.viewaxis[0] * 16;
- end = start + tr.primaryView->renderView.viewaxis[0] * 1000.0f;
- if ( !tr.primaryWorld->Trace( mt, start, end, 0.0f, false ) ) {
- return;
- }
- common->Printf( "Reloading %s\n", mt.material->GetName() );
- // reload the decl
- mt.material->base->Reload();
- // reload any images used by the decl
- mt.material->ReloadImages( false );
- }
- /*
- ==============
- R_ListModes_f
- ==============
- */
- static void R_ListModes_f( const idCmdArgs &args ) {
- for ( int displayNum = 0 ; ; displayNum++ ) {
- idList<vidMode_t> modeList;
- if ( !R_GetModeListForDisplay( displayNum, modeList ) ) {
- break;
- }
- for ( int i = 0; i < modeList.Num() ; i++ ) {
- common->Printf( "Monitor %i, mode %3i: %4i x %4i @ %ihz\n", displayNum+1, i, modeList[i].width, modeList[i].height, modeList[i].displayHz );
- }
- }
- }
- /*
- =============
- R_TestImage_f
- Display the given image centered on the screen.
- testimage <number>
- testimage <filename>
- =============
- */
- void R_TestImage_f( const idCmdArgs &args ) {
- int imageNum;
- if ( tr.testVideo ) {
- delete tr.testVideo;
- tr.testVideo = NULL;
- }
- tr.testImage = NULL;
- if ( args.Argc() != 2 ) {
- return;
- }
- if ( idStr::IsNumeric( args.Argv(1) ) ) {
- imageNum = atoi( args.Argv(1) );
- if ( imageNum >= 0 && imageNum < globalImages->images.Num() ) {
- tr.testImage = globalImages->images[imageNum];
- }
- } else {
- tr.testImage = globalImages->ImageFromFile( args.Argv( 1 ), TF_DEFAULT, TR_REPEAT, TD_DEFAULT );
- }
- }
- /*
- =============
- R_TestVideo_f
- Plays the cinematic file in a testImage
- =============
- */
- void R_TestVideo_f( const idCmdArgs &args ) {
- if ( tr.testVideo ) {
- delete tr.testVideo;
- tr.testVideo = NULL;
- }
- tr.testImage = NULL;
- if ( args.Argc() < 2 ) {
- return;
- }
- tr.testImage = globalImages->ImageFromFile( "_scratch", TF_DEFAULT, TR_REPEAT, TD_DEFAULT );
- tr.testVideo = idCinematic::Alloc();
- tr.testVideo->InitFromFile( args.Argv( 1 ), true );
- cinData_t cin;
- cin = tr.testVideo->ImageForTime( 0 );
- if ( cin.imageY == NULL ) {
- delete tr.testVideo;
- tr.testVideo = NULL;
- tr.testImage = NULL;
- return;
- }
- common->Printf( "%i x %i images\n", cin.imageWidth, cin.imageHeight );
- int len = tr.testVideo->AnimationLength();
- common->Printf( "%5.1f seconds of video\n", len * 0.001 );
- tr.testVideoStartTime = tr.primaryRenderView.time[1];
- // try to play the matching wav file
- idStr wavString = args.Argv( ( args.Argc() == 2 ) ? 1 : 2 );
- wavString.StripFileExtension();
- wavString = wavString + ".wav";
- common->SW()->PlayShaderDirectly( wavString.c_str() );
- }
- static int R_QsortSurfaceAreas( const void *a, const void *b ) {
- const idMaterial *ea, *eb;
- int ac, bc;
- ea = *(idMaterial **)a;
- if ( !ea->EverReferenced() ) {
- ac = 0;
- } else {
- ac = ea->GetSurfaceArea();
- }
- eb = *(idMaterial **)b;
- if ( !eb->EverReferenced() ) {
- bc = 0;
- } else {
- bc = eb->GetSurfaceArea();
- }
- if ( ac < bc ) {
- return -1;
- }
- if ( ac > bc ) {
- return 1;
- }
- return idStr::Icmp( ea->GetName(), eb->GetName() );
- }
- /*
- ===================
- R_ReportSurfaceAreas_f
- Prints a list of the materials sorted by surface area
- ===================
- */
- #pragma warning( disable: 6385 ) // This is simply to get pass a false defect for /analyze -- if you can figure out a better way, please let Shawn know...
- void R_ReportSurfaceAreas_f( const idCmdArgs &args ) {
- unsigned int i;
- idMaterial **list;
- const unsigned int count = declManager->GetNumDecls( DECL_MATERIAL );
- if ( count == 0 ) {
- return;
- }
- list = (idMaterial **)_alloca( count * sizeof( *list ) );
- for ( i = 0 ; i < count ; i++ ) {
- list[i] = (idMaterial *)declManager->DeclByIndex( DECL_MATERIAL, i, false );
- }
- qsort( list, count, sizeof( list[0] ), R_QsortSurfaceAreas );
- // skip over ones with 0 area
- for ( i = 0 ; i < count ; i++ ) {
- if ( list[i]->GetSurfaceArea() > 0 ) {
- break;
- }
- }
- for ( ; i < count ; i++ ) {
- // report size in "editor blocks"
- int blocks = list[i]->GetSurfaceArea() / 4096.0;
- common->Printf( "%7i %s\n", blocks, list[i]->GetName() );
- }
- }
- #pragma warning( default: 6385 )
- /*
- ==============================================================================
-
- SCREEN SHOTS
-
- ==============================================================================
- */
- /*
- ====================
- R_ReadTiledPixels
- NO LONGER SUPPORTED (FIXME: make standard case work)
- Used to allow the rendering of an image larger than the actual window by
- tiling it into window-sized chunks and rendering each chunk separately
- If ref isn't specified, the full session UpdateScreen will be done.
- ====================
- */
- void R_ReadTiledPixels( int width, int height, byte *buffer, renderView_t *ref = NULL ) {
- // include extra space for OpenGL padding to word boundaries
- int sysWidth = renderSystem->GetWidth();
- int sysHeight = renderSystem->GetHeight();
- byte * temp = (byte *)R_StaticAlloc( (sysWidth+3) * sysHeight * 3 );
- // disable scissor, so we don't need to adjust all those rects
- r_useScissor.SetBool( false );
- for ( int xo = 0 ; xo < width ; xo += sysWidth ) {
- for ( int yo = 0 ; yo < height ; yo += sysHeight ) {
- if ( ref ) {
- // discard anything currently on the list
- tr.SwapCommandBuffers( NULL, NULL, NULL, NULL );
- // build commands to render the scene
- tr.primaryWorld->RenderScene( ref );
- // finish off these commands
- const emptyCommand_t * cmd = tr.SwapCommandBuffers( NULL, NULL, NULL, NULL );
- // issue the commands to the GPU
- tr.RenderCommandBuffers( cmd );
- } else {
- const bool captureToImage = false;
- common->UpdateScreen( captureToImage );
- }
- int w = sysWidth;
- if ( xo + w > width ) {
- w = width - xo;
- }
- int h = sysHeight;
- if ( yo + h > height ) {
- h = height - yo;
- }
- qglReadBuffer( GL_FRONT );
- qglReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, temp );
- int row = ( w * 3 + 3 ) & ~3; // OpenGL pads to dword boundaries
- for ( int y = 0 ; y < h ; y++ ) {
- memcpy( buffer + ( ( yo + y )* width + xo ) * 3,
- temp + y * row, w * 3 );
- }
- }
- }
- r_useScissor.SetBool( true );
- R_StaticFree( temp );
- }
- /*
- ==================
- TakeScreenshot
- Move to tr_imagefiles.c...
- Downsample is the number of steps to mipmap the image before saving it
- If ref == NULL, common->UpdateScreen will be used
- ==================
- */
- void idRenderSystemLocal::TakeScreenshot( int width, int height, const char *fileName, int blends, renderView_t *ref ) {
- byte *buffer;
- int i, j, c, temp;
- takingScreenshot = true;
- const int pix = width * height;
- const int bufferSize = pix * 3 + 18;
- buffer = (byte *)R_StaticAlloc( bufferSize );
- memset( buffer, 0, bufferSize );
- if ( blends <= 1 ) {
- R_ReadTiledPixels( width, height, buffer + 18, ref );
- } else {
- unsigned short *shortBuffer = (unsigned short *)R_StaticAlloc(pix*2*3);
- memset (shortBuffer, 0, pix*2*3);
- // enable anti-aliasing jitter
- r_jitter.SetBool( true );
- for ( i = 0 ; i < blends ; i++ ) {
- R_ReadTiledPixels( width, height, buffer + 18, ref );
- for ( j = 0 ; j < pix*3 ; j++ ) {
- shortBuffer[j] += buffer[18+j];
- }
- }
- // divide back to bytes
- for ( i = 0 ; i < pix*3 ; i++ ) {
- buffer[18+i] = shortBuffer[i] / blends;
- }
- R_StaticFree( shortBuffer );
- r_jitter.SetBool( false );
- }
- // fill in the header (this is vertically flipped, which qglReadPixels emits)
- buffer[2] = 2; // uncompressed type
- buffer[12] = width & 255;
- buffer[13] = width >> 8;
- buffer[14] = height & 255;
- buffer[15] = height >> 8;
- buffer[16] = 24; // pixel size
- // swap rgb to bgr
- c = 18 + width * height * 3;
- for (i=18 ; i<c ; i+=3) {
- temp = buffer[i];
- buffer[i] = buffer[i+2];
- buffer[i+2] = temp;
- }
- fileSystem->WriteFile( fileName, buffer, c );
- R_StaticFree( buffer );
- takingScreenshot = false;
- }
- /*
- ==================
- R_ScreenshotFilename
- Returns a filename with digits appended
- if we have saved a previous screenshot, don't scan
- from the beginning, because recording demo avis can involve
- thousands of shots
- ==================
- */
- void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ) {
- int a,b,c,d, e;
- bool restrict = cvarSystem->GetCVarBool( "fs_restrict" );
- cvarSystem->SetCVarBool( "fs_restrict", false );
- lastNumber++;
- if ( lastNumber > 99999 ) {
- lastNumber = 99999;
- }
- for ( ; lastNumber < 99999 ; lastNumber++ ) {
- int frac = lastNumber;
- a = frac / 10000;
- frac -= a*10000;
- b = frac / 1000;
- frac -= b*1000;
- c = frac / 100;
- frac -= c*100;
- d = frac / 10;
- frac -= d*10;
- e = frac;
- sprintf( fileName, "%s%i%i%i%i%i.tga", base, a, b, c, d, e );
- if ( lastNumber == 99999 ) {
- break;
- }
- int len = fileSystem->ReadFile( fileName, NULL, NULL );
- if ( len <= 0 ) {
- break;
- }
- // check again...
- }
- cvarSystem->SetCVarBool( "fs_restrict", restrict );
- }
- /*
- ==================
- R_BlendedScreenShot
- screenshot
- screenshot [filename]
- screenshot [width] [height]
- screenshot [width] [height] [samples]
- ==================
- */
- #define MAX_BLENDS 256 // to keep the accumulation in shorts
- void R_ScreenShot_f( const idCmdArgs &args ) {
- static int lastNumber = 0;
- idStr checkname;
- int width = renderSystem->GetWidth();
- int height = renderSystem->GetHeight();
- int blends = 0;
- switch ( args.Argc() ) {
- case 1:
- width = renderSystem->GetWidth();
- height = renderSystem->GetHeight();
- blends = 1;
- R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
- break;
- case 2:
- width = renderSystem->GetWidth();
- height = renderSystem->GetHeight();
- blends = 1;
- checkname = args.Argv( 1 );
- break;
- case 3:
- width = atoi( args.Argv( 1 ) );
- height = atoi( args.Argv( 2 ) );
- blends = 1;
- R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
- break;
- case 4:
- width = atoi( args.Argv( 1 ) );
- height = atoi( args.Argv( 2 ) );
- blends = atoi( args.Argv( 3 ) );
- if ( blends < 1 ) {
- blends = 1;
- }
- if ( blends > MAX_BLENDS ) {
- blends = MAX_BLENDS;
- }
- R_ScreenshotFilename( lastNumber, "screenshots/shot", checkname );
- break;
- default:
- common->Printf( "usage: screenshot\n screenshot <filename>\n screenshot <width> <height>\n screenshot <width> <height> <blends>\n" );
- return;
- }
- // put the console away
- console->Close();
- tr.TakeScreenshot( width, height, checkname, blends, NULL );
- common->Printf( "Wrote %s\n", checkname.c_str() );
- }
- /*
- ===============
- R_StencilShot
- Save out a screenshot showing the stencil buffer expanded by 16x range
- ===============
- */
- void R_StencilShot() {
- int i, c;
- int width = tr.GetWidth();
- int height = tr.GetHeight();
- int pix = width * height;
- c = pix * 3 + 18;
- idTempArray< byte > buffer( c );
- memset( buffer.Ptr(), 0, 18 );
- idTempArray< byte > byteBuffer( pix );
- qglReadPixels( 0, 0, width, height, GL_STENCIL_INDEX , GL_UNSIGNED_BYTE, byteBuffer.Ptr() );
- for ( i = 0 ; i < pix ; i++ ) {
- buffer[18+i*3] =
- buffer[18+i*3+1] =
- // buffer[18+i*3+2] = ( byteBuffer[i] & 15 ) * 16;
- buffer[18+i*3+2] = byteBuffer[i];
- }
- // fill in the header (this is vertically flipped, which qglReadPixels emits)
- buffer[2] = 2; // uncompressed type
- buffer[12] = width & 255;
- buffer[13] = width >> 8;
- buffer[14] = height & 255;
- buffer[15] = height >> 8;
- buffer[16] = 24; // pixel size
- fileSystem->WriteFile( "screenshots/stencilShot.tga", buffer.Ptr(), c, "fs_savepath" );
- }
- //============================================================================
- static idMat3 cubeAxis[6];
- /*
- ==================
- R_SampleCubeMap
- ==================
- */
- void R_SampleCubeMap( const idVec3 &dir, int size, byte *buffers[6], byte result[4] ) {
- float adir[3];
- int axis, x, y;
- adir[0] = fabs(dir[0]);
- adir[1] = fabs(dir[1]);
- adir[2] = fabs(dir[2]);
- if ( dir[0] >= adir[1] && dir[0] >= adir[2] ) {
- axis = 0;
- } else if ( -dir[0] >= adir[1] && -dir[0] >= adir[2] ) {
- axis = 1;
- } else if ( dir[1] >= adir[0] && dir[1] >= adir[2] ) {
- axis = 2;
- } else if ( -dir[1] >= adir[0] && -dir[1] >= adir[2] ) {
- axis = 3;
- } else if ( dir[2] >= adir[1] && dir[2] >= adir[2] ) {
- axis = 4;
- } else {
- axis = 5;
- }
- float fx = (dir * cubeAxis[axis][1]) / (dir * cubeAxis[axis][0]);
- float fy = (dir * cubeAxis[axis][2]) / (dir * cubeAxis[axis][0]);
- fx = -fx;
- fy = -fy;
- x = size * 0.5 * (fx + 1);
- y = size * 0.5 * (fy + 1);
- if ( x < 0 ) {
- x = 0;
- } else if ( x >= size ) {
- x = size-1;
- }
- if ( y < 0 ) {
- y = 0;
- } else if ( y >= size ) {
- y = size-1;
- }
- result[0] = buffers[axis][(y*size+x)*4+0];
- result[1] = buffers[axis][(y*size+x)*4+1];
- result[2] = buffers[axis][(y*size+x)*4+2];
- result[3] = buffers[axis][(y*size+x)*4+3];
- }
- /*
- ==================
- R_MakeAmbientMap_f
- R_MakeAmbientMap_f <basename> [size]
- Saves out env/<basename>_amb_ft.tga, etc
- ==================
- */
- void R_MakeAmbientMap_f( const idCmdArgs &args ) {
- idStr fullname;
- const char *baseName;
- int i;
- renderView_t ref;
- viewDef_t primary;
- int downSample;
- char *extensions[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
- "_pz.tga", "_nz.tga" };
- int outSize;
- byte *buffers[6];
- int width = 0, height = 0;
- if ( args.Argc() != 2 && args.Argc() != 3 ) {
- common->Printf( "USAGE: ambientshot <basename> [size]\n" );
- return;
- }
- baseName = args.Argv( 1 );
- downSample = 0;
- if ( args.Argc() == 3 ) {
- outSize = atoi( args.Argv( 2 ) );
- } else {
- outSize = 32;
- }
- memset( &cubeAxis, 0, sizeof( cubeAxis ) );
- cubeAxis[0][0][0] = 1;
- cubeAxis[0][1][2] = 1;
- cubeAxis[0][2][1] = 1;
- cubeAxis[1][0][0] = -1;
- cubeAxis[1][1][2] = -1;
- cubeAxis[1][2][1] = 1;
- cubeAxis[2][0][1] = 1;
- cubeAxis[2][1][0] = -1;
- cubeAxis[2][2][2] = -1;
- cubeAxis[3][0][1] = -1;
- cubeAxis[3][1][0] = -1;
- cubeAxis[3][2][2] = 1;
- cubeAxis[4][0][2] = 1;
- cubeAxis[4][1][0] = -1;
- cubeAxis[4][2][1] = 1;
- cubeAxis[5][0][2] = -1;
- cubeAxis[5][1][0] = 1;
- cubeAxis[5][2][1] = 1;
- // read all of the images
- for ( i = 0 ; i < 6 ; i++ ) {
- sprintf( fullname, "env/%s%s", baseName, extensions[i] );
- common->Printf( "loading %s\n", fullname.c_str() );
- const bool captureToImage = false;
- common->UpdateScreen( captureToImage );
- R_LoadImage( fullname, &buffers[i], &width, &height, NULL, true );
- if ( !buffers[i] ) {
- common->Printf( "failed.\n" );
- for ( i-- ; i >= 0 ; i-- ) {
- Mem_Free( buffers[i] );
- }
- return;
- }
- }
- // resample with hemispherical blending
- int samples = 1000;
- byte *outBuffer = (byte *)_alloca( outSize * outSize * 4 );
- for ( int map = 0 ; map < 2 ; map++ ) {
- for ( i = 0 ; i < 6 ; i++ ) {
- for ( int x = 0 ; x < outSize ; x++ ) {
- for ( int y = 0 ; y < outSize ; y++ ) {
- idVec3 dir;
- float total[3];
- dir = cubeAxis[i][0] + -( -1 + 2.0*x/(outSize-1) ) * cubeAxis[i][1] + -( -1 + 2.0*y/(outSize-1) ) * cubeAxis[i][2];
- dir.Normalize();
- total[0] = total[1] = total[2] = 0;
- //samples = 1;
- float limit = map ? 0.95 : 0.25; // small for specular, almost hemisphere for ambient
- for ( int s = 0 ; s < samples ; s++ ) {
- // pick a random direction vector that is inside the unit sphere but not behind dir,
- // which is a robust way to evenly sample a hemisphere
- idVec3 test;
- while( 1 ) {
- for ( int j = 0 ; j < 3 ; j++ ) {
- test[j] = -1 + 2 * (rand()&0x7fff)/(float)0x7fff;
- }
- if ( test.Length() > 1.0 ) {
- continue;
- }
- test.Normalize();
- if ( test * dir > limit ) { // don't do a complete hemisphere
- break;
- }
- }
- byte result[4];
- //test = dir;
- R_SampleCubeMap( test, width, buffers, result );
- total[0] += result[0];
- total[1] += result[1];
- total[2] += result[2];
- }
- outBuffer[(y*outSize+x)*4+0] = total[0] / samples;
- outBuffer[(y*outSize+x)*4+1] = total[1] / samples;
- outBuffer[(y*outSize+x)*4+2] = total[2] / samples;
- outBuffer[(y*outSize+x)*4+3] = 255;
- }
- }
- if ( map == 0 ) {
- sprintf( fullname, "env/%s_amb%s", baseName, extensions[i] );
- } else {
- sprintf( fullname, "env/%s_spec%s", baseName, extensions[i] );
- }
- common->Printf( "writing %s\n", fullname.c_str() );
- const bool captureToImage = false;
- common->UpdateScreen( captureToImage );
- R_WriteTGA( fullname, outBuffer, outSize, outSize );
- }
- }
- for ( i = 0 ; i < 6 ; i++ ) {
- if ( buffers[i] ) {
- Mem_Free( buffers[i] );
- }
- }
- }
- //============================================================================
- /*
- ===============
- R_SetColorMappings
- ===============
- */
- void R_SetColorMappings() {
- float b = r_brightness.GetFloat();
- float invg = 1.0f / r_gamma.GetFloat();
- float j = 0.0f;
- for ( int i = 0; i < 256; i++, j += b ) {
- int inf = idMath::Ftoi( 0xffff * pow( j / 255.0f, invg ) + 0.5f );
- tr.gammaTable[i] = idMath::ClampInt( 0, 0xFFFF, inf );
- }
- GLimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable );
- }
- /*
- ================
- GfxInfo_f
- ================
- */
- void GfxInfo_f( const idCmdArgs &args ) {
- common->Printf( "CPU: %s\n", Sys_GetProcessorString() );
- const char *fsstrings[] =
- {
- "windowed",
- "fullscreen"
- };
- common->Printf( "\nGL_VENDOR: %s\n", glConfig.vendor_string );
- common->Printf( "GL_RENDERER: %s\n", glConfig.renderer_string );
- common->Printf( "GL_VERSION: %s\n", glConfig.version_string );
- common->Printf( "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
- if ( glConfig.wgl_extensions_string ) {
- common->Printf( "WGL_EXTENSIONS: %s\n", glConfig.wgl_extensions_string );
- }
- common->Printf( "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
- common->Printf( "GL_MAX_TEXTURE_COORDS_ARB: %d\n", glConfig.maxTextureCoords );
- common->Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %d\n", glConfig.maxTextureImageUnits );
- // print all the display adapters, monitors, and video modes
- void DumpAllDisplayDevices();
- DumpAllDisplayDevices();
- common->Printf( "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
- common->Printf( "MODE: %d, %d x %d %s hz:", r_vidMode.GetInteger(), renderSystem->GetWidth(), renderSystem->GetHeight(), fsstrings[r_fullscreen.GetBool()] );
- if ( glConfig.displayFrequency ) {
- common->Printf( "%d\n", glConfig.displayFrequency );
- } else {
- common->Printf( "N/A\n" );
- }
- common->Printf( "-------\n" );
- // WGL_EXT_swap_interval
- typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
- extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
- if ( r_swapInterval.GetInteger() && wglSwapIntervalEXT != NULL ) {
- common->Printf( "Forcing swapInterval %i\n", r_swapInterval.GetInteger() );
- } else {
- common->Printf( "swapInterval not forced\n" );
- }
- if ( glConfig.stereoPixelFormatAvailable && glConfig.isStereoPixelFormat ) {
- idLib::Printf( "OpenGl quad buffer stereo pixel format active\n" );
- } else if ( glConfig.stereoPixelFormatAvailable ) {
- idLib::Printf( "OpenGl quad buffer stereo pixel available but not selected\n" );
- } else {
- idLib::Printf( "OpenGl quad buffer stereo pixel format not available\n" );
- }
- idLib::Printf( "Stereo mode: " );
- switch ( renderSystem->GetStereo3DMode() ) {
- case STEREO3D_OFF: idLib::Printf( "STEREO3D_OFF\n" ); break;
- case STEREO3D_SIDE_BY_SIDE_COMPRESSED: idLib::Printf( "STEREO3D_SIDE_BY_SIDE_COMPRESSED\n" ); break;
- case STEREO3D_TOP_AND_BOTTOM_COMPRESSED:idLib::Printf( "STEREO3D_TOP_AND_BOTTOM_COMPRESSED\n" ); break;
- case STEREO3D_SIDE_BY_SIDE: idLib::Printf( "STEREO3D_SIDE_BY_SIDE\n" ); break;
- case STEREO3D_HDMI_720: idLib::Printf( "STEREO3D_HDMI_720\n" ); break;
- case STEREO3D_INTERLACED: idLib::Printf( "STEREO3D_INTERLACED\n" ); break;
- case STEREO3D_QUAD_BUFFER: idLib::Printf( "STEREO3D_QUAD_BUFFER\n" ); break;
- default:idLib::Printf( "Unknown (%i)\n", renderSystem->GetStereo3DMode() ); break;
- }
- idLib::Printf( "%i multisamples\n", glConfig.multisamples );
- common->Printf( "%5.1f cm screen width (%4.1f\" diagonal)\n",
- glConfig.physicalScreenWidthInCentimeters, glConfig.physicalScreenWidthInCentimeters / 2.54f
- * sqrt( (float)(16*16 + 9*9) ) / 16.0f );
- extern idCVar r_forceScreenWidthCentimeters;
- if ( r_forceScreenWidthCentimeters.GetFloat() ) {
- common->Printf( "screen size manually forced to %5.1f cm width (%4.1f\" diagonal)\n",
- renderSystem->GetPhysicalScreenWidthInCentimeters(), renderSystem->GetPhysicalScreenWidthInCentimeters() / 2.54f
- * sqrt( (float)(16*16 + 9*9) ) / 16.0f );
- }
- }
- /*
- =================
- R_VidRestart_f
- =================
- */
- void R_VidRestart_f( const idCmdArgs &args ) {
- // if OpenGL isn't started, do nothing
- if ( !R_IsInitialized() ) {
- return;
- }
- // set the mode without re-initializing the context
- R_SetNewMode( false );
- #if 0
- bool full = true;
- bool forceWindow = false;
- for ( int i = 1 ; i < args.Argc() ; i++ ) {
- if ( idStr::Icmp( args.Argv( i ), "partial" ) == 0 ) {
- full = false;
- continue;
- }
- if ( idStr::Icmp( args.Argv( i ), "windowed" ) == 0 ) {
- forceWindow = true;
- continue;
- }
- }
- // this could take a while, so give them the cursor back ASAP
- Sys_GrabMouseCursor( false );
- // dump ambient caches
- renderModelManager->FreeModelVertexCaches();
- // free any current world interaction surfaces and vertex caches
- R_FreeDerivedData();
- // make sure the defered frees are actually freed
- R_ToggleSmpFrame();
- R_ToggleSmpFrame();
- // free the vertex caches so they will be regenerated again
- vertexCache.PurgeAll();
- // sound and input are tied to the window we are about to destroy
- if ( full ) {
- // free all of our texture numbers
- Sys_ShutdownInput();
- globalImages->PurgeAllImages();
- // free the context and close the window
- GLimp_Shutdown();
- r_initialized = false;
- // create the new context and vertex cache
- bool latch = cvarSystem->GetCVarBool( "r_fullscreen" );
- if ( forceWindow ) {
- cvarSystem->SetCVarBool( "r_fullscreen", false );
- }
- R_InitOpenGL();
- cvarSystem->SetCVarBool( "r_fullscreen", latch );
- // regenerate all images
- globalImages->ReloadImages( true );
- } else {
- glimpParms_t parms;
- parms.width = glConfig.nativeScreenWidth;
- parms.height = glConfig.nativeScreenHeight;
- parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetInteger();
- parms.displayHz = r_displayRefresh.GetInteger();
- parms.multiSamples = r_multiSamples.GetInteger();
- parms.stereo = false;
- GLimp_SetScreenParms( parms );
- }
- // make sure the regeneration doesn't use anything no longer valid
- tr.viewCount++;
- tr.viewDef = NULL;
- // check for problems
- int err = qglGetError();
- if ( err != GL_NO_ERROR ) {
- common->Printf( "glGetError() = 0x%x\n", err );
- }
- #endif
- }
- /*
- =================
- R_InitMaterials
- =================
- */
- void R_InitMaterials() {
- tr.defaultMaterial = declManager->FindMaterial( "_default", false );
- if ( !tr.defaultMaterial ) {
- common->FatalError( "_default material not found" );
- }
- tr.defaultPointLight = declManager->FindMaterial( "lights/defaultPointLight" );
- tr.defaultProjectedLight = declManager->FindMaterial( "lights/defaultProjectedLight" );
- tr.whiteMaterial = declManager->FindMaterial( "_white" );
- tr.charSetMaterial = declManager->FindMaterial( "textures/bigchars" );
- }
- /*
- =================
- R_SizeUp_f
- Keybinding command
- =================
- */
- static void R_SizeUp_f( const idCmdArgs &args ) {
- if ( r_screenFraction.GetInteger() + 10 > 100 ) {
- r_screenFraction.SetInteger( 100 );
- } else {
- r_screenFraction.SetInteger( r_screenFraction.GetInteger() + 10 );
- }
- }
- /*
- =================
- R_SizeDown_f
- Keybinding command
- =================
- */
- static void R_SizeDown_f( const idCmdArgs &args ) {
- if ( r_screenFraction.GetInteger() - 10 < 10 ) {
- r_screenFraction.SetInteger( 10 );
- } else {
- r_screenFraction.SetInteger( r_screenFraction.GetInteger() - 10 );
- }
- }
- /*
- ===============
- TouchGui_f
- this is called from the main thread
- ===============
- */
- void R_TouchGui_f( const idCmdArgs &args ) {
- const char *gui = args.Argv( 1 );
- if ( !gui[0] ) {
- common->Printf( "USAGE: touchGui <guiName>\n" );
- return;
- }
- common->Printf( "touchGui %s\n", gui );
- const bool captureToImage = false;
- common->UpdateScreen( captureToImage );
- uiManager->Touch( gui );
- }
- /*
- =================
- R_InitCvars
- =================
- */
- void R_InitCvars() {
- // update latched cvars here
- }
- /*
- =================
- R_InitCommands
- =================
- */
- void R_InitCommands() {
- cmdSystem->AddCommand( "sizeUp", R_SizeUp_f, CMD_FL_RENDERER, "makes the rendered view larger" );
- cmdSystem->AddCommand( "sizeDown", R_SizeDown_f, CMD_FL_RENDERER, "makes the rendered view smaller" );
- cmdSystem->AddCommand( "reloadGuis", R_ReloadGuis_f, CMD_FL_RENDERER, "reloads guis" );
- cmdSystem->AddCommand( "listGuis", R_ListGuis_f, CMD_FL_RENDERER, "lists guis" );
- cmdSystem->AddCommand( "touchGui", R_TouchGui_f, CMD_FL_RENDERER, "touches a gui" );
- cmdSystem->AddCommand( "screenshot", R_ScreenShot_f, CMD_FL_RENDERER, "takes a screenshot" );
- cmdSystem->AddCommand( "makeAmbientMap", R_MakeAmbientMap_f, CMD_FL_RENDERER|CMD_FL_CHEAT, "makes an ambient map" );
- cmdSystem->AddCommand( "gfxInfo", GfxInfo_f, CMD_FL_RENDERER, "show graphics info" );
- cmdSystem->AddCommand( "modulateLights", R_ModulateLights_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "modifies shader parms on all lights" );
- cmdSystem->AddCommand( "testImage", R_TestImage_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given image centered on screen", idCmdSystem::ArgCompletion_ImageName );
- cmdSystem->AddCommand( "testVideo", R_TestVideo_f, CMD_FL_RENDERER | CMD_FL_CHEAT, "displays the given cinematic", idCmdSystem::ArgCompletion_VideoName );
- cmdSystem->AddCommand( "reportSurfaceAreas", R_ReportSurfaceAreas_f, CMD_FL_RENDERER, "lists all used materials sorted by surface area" );
- cmdSystem->AddCommand( "showInteractionMemory", R_ShowInteractionMemory_f, CMD_FL_RENDERER, "shows memory used by interactions" );
- cmdSystem->AddCommand( "vid_restart", R_VidRestart_f, CMD_FL_RENDERER, "restarts renderSystem" );
- cmdSystem->AddCommand( "listRenderEntityDefs", R_ListRenderEntityDefs_f, CMD_FL_RENDERER, "lists the entity defs" );
- cmdSystem->AddCommand( "listRenderLightDefs", R_ListRenderLightDefs_f, CMD_FL_RENDERER, "lists the light defs" );
- cmdSystem->AddCommand( "listModes", R_ListModes_f, CMD_FL_RENDERER, "lists all video modes" );
- cmdSystem->AddCommand( "reloadSurface", R_ReloadSurface_f, CMD_FL_RENDERER, "reloads the decl and images for selected surface" );
- }
- /*
- ===============
- idRenderSystemLocal::Clear
- ===============
- */
- void idRenderSystemLocal::Clear() {
- registered = false;
- frameCount = 0;
- viewCount = 0;
- frameShaderTime = 0.0f;
- ambientLightVector.Zero();
- worlds.Clear();
- primaryWorld = NULL;
- memset( &primaryRenderView, 0, sizeof( primaryRenderView ) );
- primaryView = NULL;
- defaultMaterial = NULL;
- testImage = NULL;
- ambientCubeImage = NULL;
- viewDef = NULL;
- memset( &pc, 0, sizeof( pc ) );
- memset( &identitySpace, 0, sizeof( identitySpace ) );
- memset( renderCrops, 0, sizeof( renderCrops ) );
- currentRenderCrop = 0;
- currentColorNativeBytesOrder = 0xFFFFFFFF;
- currentGLState = 0;
- guiRecursionLevel = 0;
- guiModel = NULL;
- memset( gammaTable, 0, sizeof( gammaTable ) );
- takingScreenshot = false;
- if ( unitSquareTriangles != NULL ) {
- Mem_Free( unitSquareTriangles );
- unitSquareTriangles = NULL;
- }
- if ( zeroOneCubeTriangles != NULL ) {
- Mem_Free( zeroOneCubeTriangles );
- zeroOneCubeTriangles = NULL;
- }
- if ( testImageTriangles != NULL ) {
- Mem_Free( testImageTriangles );
- testImageTriangles = NULL;
- }
- frontEndJobList = NULL;
- }
- /*
- =============
- R_MakeFullScreenTris
- =============
- */
- static srfTriangles_t * R_MakeFullScreenTris() {
- // copy verts and indexes
- srfTriangles_t * tri = (srfTriangles_t *)Mem_ClearedAlloc( sizeof( *tri ), TAG_RENDER_TOOLS );
- tri->numIndexes = 6;
- tri->numVerts = 4;
- int indexSize = tri->numIndexes * sizeof( tri->indexes[0] );
- int allocatedIndexBytes = ALIGN( indexSize, 16 );
- tri->indexes = (triIndex_t *)Mem_Alloc( allocatedIndexBytes, TAG_RENDER_TOOLS );
- int vertexSize = tri->numVerts * sizeof( tri->verts[0] );
- int allocatedVertexBytes = ALIGN( vertexSize, 16 );
- tri->verts = (idDrawVert *)Mem_ClearedAlloc( allocatedVertexBytes, TAG_RENDER_TOOLS );
- idDrawVert * verts = tri->verts;
- triIndex_t tempIndexes[6] = { 3, 0, 2, 2, 0, 1 };
- memcpy( tri->indexes, tempIndexes, indexSize );
-
- verts[0].xyz[0] = -1.0f;
- verts[0].xyz[1] = 1.0f;
- verts[0].SetTexCoord( 0.0f, 1.0f );
- verts[1].xyz[0] = 1.0f;
- verts[1].xyz[1] = 1.0f;
- verts[1].SetTexCoord( 1.0f, 1.0f );
- verts[2].xyz[0] = 1.0f;
- verts[2].xyz[1] = -1.0f;
- verts[2].SetTexCoord( 1.0f, 0.0f );
- verts[3].xyz[0] = -1.0f;
- verts[3].xyz[1] = -1.0f;
- verts[3].SetTexCoord( 0.0f, 0.0f );
- for ( int i = 0 ; i < 4 ; i++ ) {
- verts[i].SetColor( 0xffffffff );
- }
- return tri;
- }
- /*
- =============
- R_MakeZeroOneCubeTris
- =============
- */
- static srfTriangles_t * R_MakeZeroOneCubeTris() {
- srfTriangles_t * tri = (srfTriangles_t *)Mem_ClearedAlloc( sizeof( *tri ), TAG_RENDER_TOOLS );
- tri->numVerts = 8;
- tri->numIndexes = 36;
- const int indexSize = tri->numIndexes * sizeof( tri->indexes[0] );
- const int allocatedIndexBytes = ALIGN( indexSize, 16 );
- tri->indexes = (triIndex_t *)Mem_Alloc( allocatedIndexBytes, TAG_RENDER_TOOLS );
- const int vertexSize = tri->numVerts * sizeof( tri->verts[0] );
- const int allocatedVertexBytes = ALIGN( vertexSize, 16 );
- tri->verts = (idDrawVert *)Mem_ClearedAlloc( allocatedVertexBytes, TAG_RENDER_TOOLS );
- idDrawVert * verts = tri->verts;
- const float low = 0.0f;
- const float high = 1.0f;
- idVec3 center( 0.0f );
- idVec3 mx( low, 0.0f, 0.0f );
- idVec3 px( high, 0.0f, 0.0f );
- idVec3 my( 0.0f, low, 0.0f );
- idVec3 py( 0.0f, high, 0.0f );
- idVec3 mz( 0.0f, 0.0f, low );
- idVec3 pz( 0.0f, 0.0f, high );
- verts[0].xyz = center + mx + my + mz;
- verts[1].xyz = center + px + my + mz;
- verts[2].xyz = center + px + py + mz;
- verts[3].xyz = center + mx + py + mz;
- verts[4].xyz = center + mx + my + pz;
- verts[5].xyz = center + px + my + pz;
- verts[6].xyz = center + px + py + pz;
- verts[7].xyz = center + mx + py + pz;
- // bottom
- tri->indexes[ 0*3+0] = 2;
- tri->indexes[ 0*3+1] = 3;
- tri->indexes[ 0*3+2] = 0;
- tri->indexes[ 1*3+0] = 1;
- tri->indexes[ 1*3+1] = 2;
- tri->indexes[ 1*3+2] = 0;
- // back
- tri->indexes[ 2*3+0] = 5;
- tri->indexes[ 2*3+1] = 1;
- tri->indexes[ 2*3+2] = 0;
- tri->indexes[ 3*3+0] = 4;
- tri->indexes[ 3*3+1] = 5;
- tri->indexes[ 3*3+2] = 0;
- // left
- tri->indexes[ 4*3+0] = 7;
- tri->indexes[ 4*3+1] = 4;
- tri->indexes[ 4*3+2] = 0;
- tri->indexes[ 5*3+0] = 3;
- tri->indexes[ 5*3+1] = 7;
- tri->indexes[ 5*3+2] = 0;
- // right
- tri->indexes[ 6*3+0] = 1;
- tri->indexes[ 6*3+1] = 5;
- tri->indexes[ 6*3+2] = 6;
- tri->indexes[ 7*3+0] = 2;
- tri->indexes[ 7*3+1] = 1;
- tri->indexes[ 7*3+2] = 6;
- // front
- tri->indexes[ 8*3+0] = 3;
- tri->indexes[ 8*3+1] = 2;
- tri->indexes[ 8*3+2] = 6;
- tri->indexes[ 9*3+0] = 7;
- tri->indexes[ 9*3+1] = 3;
- tri->indexes[ 9*3+2] = 6;
- // top
- tri->indexes[10*3+0] = 4;
- tri->indexes[10*3+1] = 7;
- tri->indexes[10*3+2] = 6;
- tri->indexes[11*3+0] = 5;
- tri->indexes[11*3+1] = 4;
- tri->indexes[11*3+2] = 6;
- for ( int i = 0 ; i < 4 ; i++ ) {
- verts[i].SetColor( 0xffffffff );
- }
- return tri;
- }
- /*
- ================
- R_MakeTestImageTriangles
- Initializes the Test Image Triangles
- ================
- */
- srfTriangles_t* R_MakeTestImageTriangles() {
- srfTriangles_t * tri = (srfTriangles_t *)Mem_ClearedAlloc( sizeof( *tri ), TAG_RENDER_TOOLS );
- tri->numIndexes = 6;
- tri->numVerts = 4;
- int indexSize = tri->numIndexes * sizeof( tri->indexes[0] );
- int allocatedIndexBytes = ALIGN( indexSize, 16 );
- tri->indexes = (triIndex_t *)Mem_Alloc( allocatedIndexBytes, TAG_RENDER_TOOLS );
- int vertexSize = tri->numVerts * sizeof( tri->verts[0] );
- int allocatedVertexBytes = ALIGN( vertexSize, 16 );
- tri->verts = (idDrawVert *)Mem_ClearedAlloc( allocatedVertexBytes, TAG_RENDER_TOOLS );
- ALIGNTYPE16 triIndex_t tempIndexes[6] = { 3, 0, 2, 2, 0, 1 };
- memcpy( tri->indexes, tempIndexes, indexSize );
- idDrawVert* tempVerts = tri->verts;
- tempVerts[0].xyz[0] = 0.0f;
- tempVerts[0].xyz[1] = 0.0f;
- tempVerts[0].xyz[2] = 0;
- tempVerts[0].SetTexCoord( 0.0, 0.0f );
- tempVerts[1].xyz[0] = 1.0f;
- tempVerts[1].xyz[1] = 0.0f;
- tempVerts[1].xyz[2] = 0;
- tempVerts[1].SetTexCoord( 1.0f, 0.0f );
- tempVerts[2].xyz[0] = 1.0f;
- tempVerts[2].xyz[1] = 1.0f;
- tempVerts[2].xyz[2] = 0;
- tempVerts[2].SetTexCoord( 1.0f, 1.0f );
- tempVerts[3].xyz[0] = 0.0f;
- tempVerts[3].xyz[1] = 1.0f;
- tempVerts[3].xyz[2] = 0;
- tempVerts[3].SetTexCoord( 0.0f, 1.0f );
- for ( int i = 0; i < 4; i++ ) {
- tempVerts[i].SetColor( 0xFFFFFFFF );
- }
- return tri;
- }
- /*
- ===============
- idRenderSystemLocal::Init
- ===============
- */
- void idRenderSystemLocal::Init() {
- common->Printf( "------- Initializing renderSystem --------\n" );
- // clear all our internal state
- viewCount = 1; // so cleared structures never match viewCount
- // we used to memset tr, but now that it is a class, we can't, so
- // there may be other state we need to reset
- ambientLightVector[0] = 0.5f;
- ambientLightVector[1] = 0.5f - 0.385f;
- ambientLightVector[2] = 0.8925f;
- ambientLightVector[3] = 1.0f;
- memset( &backEnd, 0, sizeof( backEnd ) );
- R_InitCvars();
- R_InitCommands();
- guiModel = new (TAG_RENDER) idGuiModel;
- guiModel->Clear();
- tr_guiModel = guiModel; // for DeviceContext fast path
- globalImages->Init();
- idCinematic::InitCinematic( );
- // build brightness translation tables
- R_SetColorMappings();
- R_InitMaterials();
- renderModelManager->Init();
- // set the identity space
- identitySpace.modelMatrix[0*4+0] = 1.0f;
- identitySpace.modelMatrix[1*4+1] = 1.0f;
- identitySpace.modelMatrix[2*4+2] = 1.0f;
- // make sure the tr.unitSquareTriangles data is current in the vertex / index cache
- if ( unitSquareTriangles == NULL ) {
- unitSquareTriangles = R_MakeFullScreenTris();
- }
- // make sure the tr.zeroOneCubeTriangles data is current in the vertex / index cache
- if ( zeroOneCubeTriangles == NULL ) {
- zeroOneCubeTriangles = R_MakeZeroOneCubeTris();
- }
- // make sure the tr.testImageTriangles data is current in the vertex / index cache
- if ( testImageTriangles == NULL ) {
- testImageTriangles = R_MakeTestImageTriangles();
- }
- frontEndJobList = parallelJobManager->AllocJobList( JOBLIST_RENDERER_FRONTEND, JOBLIST_PRIORITY_MEDIUM, 2048, 0, NULL );
- // make sure the command buffers are ready to accept the first screen update
- SwapCommandBuffers( NULL, NULL, NULL, NULL );
- common->Printf( "renderSystem initialized.\n" );
- common->Printf( "--------------------------------------\n" );
- }
- /*
- ===============
- idRenderSystemLocal::Shutdown
- ===============
- */
- void idRenderSystemLocal::Shutdown() {
- common->Printf( "idRenderSystem::Shutdown()\n" );
- fonts.DeleteContents();
- if ( R_IsInitialized() ) {
- globalImages->PurgeAllImages();
- }
- renderModelManager->Shutdown();
- idCinematic::ShutdownCinematic( );
- globalImages->Shutdown();
- // free frame memory
- R_ShutdownFrameData();
- UnbindBufferObjects();
- // free the vertex cache, which should have nothing allocated now
- vertexCache.Shutdown();
- RB_ShutdownDebugTools();
- delete guiModel;
- parallelJobManager->FreeJobList( frontEndJobList );
- Clear();
- ShutdownOpenGL();
- }
- /*
- ========================
- idRenderSystemLocal::ResetGuiModels
- ========================
- */
- void idRenderSystemLocal::ResetGuiModels() {
- delete guiModel;
- guiModel = new (TAG_RENDER) idGuiModel;
- guiModel->Clear();
- guiModel->BeginFrame();
- tr_guiModel = guiModel; // for DeviceContext fast path
- }
- /*
- ========================
- idRenderSystemLocal::BeginLevelLoad
- ========================
- */
- void idRenderSystemLocal::BeginLevelLoad() {
- globalImages->BeginLevelLoad();
- renderModelManager->BeginLevelLoad();
- // Re-Initialize the Default Materials if needed.
- R_InitMaterials();
- }
- /*
- ========================
- idRenderSystemLocal::LoadLevelImages
- ========================
- */
- void idRenderSystemLocal::LoadLevelImages() {
- globalImages->LoadLevelImages( false );
- }
- /*
- ========================
- idRenderSystemLocal::Preload
- ========================
- */
- void idRenderSystemLocal::Preload( const idPreloadManifest &manifest, const char *mapName ) {
- globalImages->Preload( manifest, true );
- uiManager->Preload( mapName );
- renderModelManager->Preload( manifest );
- }
- /*
- ========================
- idRenderSystemLocal::EndLevelLoad
- ========================
- */
- void idRenderSystemLocal::EndLevelLoad() {
- renderModelManager->EndLevelLoad();
- globalImages->EndLevelLoad();
- }
- /*
- ========================
- idRenderSystemLocal::BeginAutomaticBackgroundSwaps
- ========================
- */
- void idRenderSystemLocal::BeginAutomaticBackgroundSwaps( autoRenderIconType_t icon ) {
- }
- /*
- ========================
- idRenderSystemLocal::EndAutomaticBackgroundSwaps
- ========================
- */
- void idRenderSystemLocal::EndAutomaticBackgroundSwaps() {
- }
- /*
- ========================
- idRenderSystemLocal::AreAutomaticBackgroundSwapsRunning
- ========================
- */
- bool idRenderSystemLocal::AreAutomaticBackgroundSwapsRunning( autoRenderIconType_t * icon ) const {
- return false;
- }
- /*
- ============
- idRenderSystemLocal::RegisterFont
- ============
- */
- idFont * idRenderSystemLocal::RegisterFont( const char * fontName ) {
- idStrStatic< MAX_OSPATH > baseFontName = fontName;
- baseFontName.Replace( "fonts/", "" );
- for ( int i = 0; i < fonts.Num(); i++ ) {
- if ( idStr::Icmp( fonts[i]->GetName(), baseFontName ) == 0 ) {
- fonts[i]->Touch();
- return fonts[i];
- }
- }
- idFont * newFont = new (TAG_FONT) idFont( baseFontName );
- fonts.Append( newFont );
- return newFont;
- }
- /*
- ========================
- idRenderSystemLocal::ResetFonts
- ========================
- */
- void idRenderSystemLocal::ResetFonts() {
- fonts.DeleteContents( true );
- }
- /*
- ========================
- idRenderSystemLocal::InitOpenGL
- ========================
- */
- void idRenderSystemLocal::InitOpenGL() {
- // if OpenGL isn't started, start it now
- if ( !R_IsInitialized() ) {
- R_InitOpenGL();
- // Reloading images here causes the rendertargets to get deleted. Figure out how to handle this properly on 360
- globalImages->ReloadImages( true );
-
- int err = qglGetError();
- if ( err != GL_NO_ERROR ) {
- common->Printf( "glGetError() = 0x%x\n", err );
- }
- }
- }
- /*
- ========================
- idRenderSystemLocal::ShutdownOpenGL
- ========================
- */
- void idRenderSystemLocal::ShutdownOpenGL() {
- // free the context and close the window
- R_ShutdownFrameData();
- GLimp_Shutdown();
- r_initialized = false;
- }
- /*
- ========================
- idRenderSystemLocal::IsOpenGLRunning
- ========================
- */
- bool idRenderSystemLocal::IsOpenGLRunning() const {
- return R_IsInitialized();
- }
- /*
- ========================
- idRenderSystemLocal::IsFullScreen
- ========================
- */
- bool idRenderSystemLocal::IsFullScreen() const {
- return glConfig.isFullscreen != 0;
- }
- /*
- ========================
- idRenderSystemLocal::GetWidth
- ========================
- */
- int idRenderSystemLocal::GetWidth() const {
- if ( glConfig.stereo3Dmode == STEREO3D_SIDE_BY_SIDE || glConfig.stereo3Dmode == STEREO3D_SIDE_BY_SIDE_COMPRESSED ) {
- return glConfig.nativeScreenWidth >> 1;
- }
- return glConfig.nativeScreenWidth;
- }
- /*
- ========================
- idRenderSystemLocal::GetHeight
- ========================
- */
- int idRenderSystemLocal::GetHeight() const {
- if ( glConfig.stereo3Dmode == STEREO3D_HDMI_720 ) {
- return 720;
- }
- extern idCVar stereoRender_warp;
- if ( glConfig.stereo3Dmode == STEREO3D_SIDE_BY_SIDE && stereoRender_warp.GetBool() ) {
- // for the Rift, render a square aspect view that will be symetric for the optics
- return glConfig.nativeScreenWidth >> 1;
- }
- if ( glConfig.stereo3Dmode == STEREO3D_INTERLACED || glConfig.stereo3Dmode == STEREO3D_TOP_AND_BOTTOM_COMPRESSED ) {
- return glConfig.nativeScreenHeight >> 1;
- }
- return glConfig.nativeScreenHeight;
- }
- /*
- ========================
- idRenderSystemLocal::GetStereo3DMode
- ========================
- */
- stereo3DMode_t idRenderSystemLocal::GetStereo3DMode() const {
- return glConfig.stereo3Dmode;
- }
- /*
- ========================
- idRenderSystemLocal::IsStereoScopicRenderingSupported
- ========================
- */
- bool idRenderSystemLocal::IsStereoScopicRenderingSupported() const {
- return true;
- }
- /*
- ========================
- idRenderSystemLocal::HasQuadBufferSupport
- ========================
- */
- bool idRenderSystemLocal::HasQuadBufferSupport() const {
- return glConfig.stereoPixelFormatAvailable;
- }
- /*
- ========================
- idRenderSystemLocal::GetStereoScopicRenderingMode
- ========================
- */
- stereo3DMode_t idRenderSystemLocal::GetStereoScopicRenderingMode() const {
- return ( !IsStereoScopicRenderingSupported() ) ? STEREO3D_OFF : (stereo3DMode_t)stereoRender_enable.GetInteger();
- }
- /*
- ========================
- idRenderSystemLocal::IsStereoScopicRenderingSupported
- ========================
- */
- void idRenderSystemLocal::EnableStereoScopicRendering( const stereo3DMode_t mode ) const {
- stereoRender_enable.SetInteger( mode );
- }
- /*
- ========================
- idRenderSystemLocal::GetPixelAspect
- ========================
- */
- float idRenderSystemLocal::GetPixelAspect() const {
- switch( glConfig.stereo3Dmode ) {
- case STEREO3D_SIDE_BY_SIDE_COMPRESSED:
- return glConfig.pixelAspect * 2.0f;
- case STEREO3D_TOP_AND_BOTTOM_COMPRESSED:
- case STEREO3D_INTERLACED:
- return glConfig.pixelAspect * 0.5f;
- default:
- return glConfig.pixelAspect;
- }
- }
- /*
- ========================
- idRenderSystemLocal::GetPhysicalScreenWidthInCentimeters
- This is used to calculate stereoscopic screen offset for a given interocular distance.
- ========================
- */
- idCVar r_forceScreenWidthCentimeters( "r_forceScreenWidthCentimeters", "0", CVAR_RENDERER | CVAR_ARCHIVE, "Override screen width returned by hardware" );
- float idRenderSystemLocal::GetPhysicalScreenWidthInCentimeters() const {
- if ( r_forceScreenWidthCentimeters.GetFloat() > 0 ) {
- return r_forceScreenWidthCentimeters.GetFloat();
- }
- return glConfig.physicalScreenWidthInCentimeters;
- }
|