1 /* 2 =========================================================================== 3 4 Doom 3 GPL Source Code 5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). 8 9 Doom 3 Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 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. 25 26 =========================================================================== 27 */ 28 29 #ifndef __TR_LOCAL_H__ 30 #define __TR_LOCAL_H__ 31 32 class idScreenRect; // yay for include recursion 33 34 #include "renderer/Image.h" 35 #include "renderer/Interaction.h" 36 #include "renderer/MegaTexture.h" 37 #include "renderer/ModelDecal.h" 38 #include "renderer/ModelOverlay.h" 39 #include "renderer/RenderSystem.h" 40 #include "renderer/RenderWorld.h" 41 42 class idRenderWorldLocal; 43 44 // everything that is needed by the backend needs 45 // to be double buffered to allow it to run in 46 // parallel on a dual cpu machine 47 const int SMP_FRAMES = 1; 48 49 const int FALLOFF_TEXTURE_SIZE = 64; 50 51 const float DEFAULT_FOG_DISTANCE = 500.0f; 52 53 const int FOG_ENTER_SIZE = 64; 54 const float FOG_ENTER = (FOG_ENTER_SIZE+1.0f)/(FOG_ENTER_SIZE*2); 55 // picky to get the bilerp correct at terminator 56 57 58 // idScreenRect gets carried around with each drawSurf, so it makes sense 59 // to keep it compact, instead of just using the idBounds class 60 class idScreenRect { 61 public: 62 short x1, y1, x2, y2; // inclusive pixel bounds inside viewport 63 float zmin, zmax; // for depth bounds test 64 65 void Clear(); // clear to backwards values 66 void AddPoint( float x, float y ); // adds a point 67 void Expand(); // expand by one pixel each way to fix roundoffs 68 void Intersect( const idScreenRect &rect ); 69 void Union( const idScreenRect &rect ); 70 bool Equals( const idScreenRect &rect ) const; 71 bool IsEmpty() const; 72 }; 73 74 idScreenRect R_ScreenRectFromViewFrustumBounds( const idBounds &bounds ); 75 void R_ShowColoredScreenRect( const idScreenRect &rect, int colorIndex ); 76 77 typedef enum { 78 DC_BAD, 79 DC_RENDERVIEW, 80 DC_UPDATE_ENTITYDEF, 81 DC_DELETE_ENTITYDEF, 82 DC_UPDATE_LIGHTDEF, 83 DC_DELETE_LIGHTDEF, 84 DC_LOADMAP, 85 DC_CROP_RENDER, 86 DC_UNCROP_RENDER, 87 DC_CAPTURE_RENDER, 88 DC_END_FRAME, 89 DC_DEFINE_MODEL, 90 DC_SET_PORTAL_STATE, 91 DC_UPDATE_SOUNDOCCLUSION, 92 DC_GUI_MODEL 93 } demoCommand_t; 94 95 /* 96 ============================================================================== 97 98 SURFACES 99 100 ============================================================================== 101 */ 102 103 // drawSurf_t structures command the back end to render surfaces 104 // a given srfTriangles_t may be used with multiple viewEntity_t, 105 // as when viewed in a subview or multiple viewport render, or 106 // with multiple shaders when skinned, or, possibly with multiple 107 // lights, although currently each lighting interaction creates 108 // unique srfTriangles_t 109 110 // drawSurf_t are always allocated and freed every frame, they are never cached 111 static const int DSF_VIEW_INSIDE_SHADOW = 1; 112 113 typedef struct drawSurf_s { 114 const srfTriangles_t *geo; 115 const struct viewEntity_s *space; 116 const idMaterial *material; // may be NULL for shadow volumes 117 float sort; // material->sort, modified by gui / entity sort offsets 118 const float *shaderRegisters; // evaluated and adjusted for referenceShaders 119 const struct drawSurf_s *nextOnLight; // viewLight chains 120 idScreenRect scissorRect; // for scissor clipping, local inside renderView viewport 121 int dsFlags; // DSF_VIEW_INSIDE_SHADOW, etc 122 struct vertCache_s *dynamicTexCoords; // float * in vertex cache memory 123 // specular directions for non vertex program cards, skybox texcoords, etc 124 } drawSurf_t; 125 126 127 typedef struct { 128 int numPlanes; // this is always 6 for now 129 idPlane planes[6]; 130 // positive sides facing inward 131 // plane 5 is always the plane the projection is going to, the 132 // other planes are just clip planes 133 // all planes are in global coordinates 134 135 bool makeClippedPlanes; 136 // a projected light with a single frustum needs to make sil planes 137 // from triangles that clip against side planes, but a point light 138 // that has adjacent frustums doesn't need to 139 } shadowFrustum_t; 140 141 142 // areas have references to hold all the lights and entities in them 143 typedef struct areaReference_s { 144 struct areaReference_s *areaNext; // chain in the area 145 struct areaReference_s *areaPrev; 146 struct areaReference_s *ownerNext; // chain on either the entityDef or lightDef 147 idRenderEntityLocal * entity; // only one of entity / light will be non-NULL 148 idRenderLightLocal * light; // only one of entity / light will be non-NULL 149 struct portalArea_s * area; // so owners can find all the areas they are in 150 } areaReference_t; 151 152 153 // idRenderLight should become the new public interface replacing the qhandle_t to light defs in the idRenderWorld interface 154 class idRenderLight { 155 public: ~idRenderLight()156 virtual ~idRenderLight() {} 157 158 virtual void FreeRenderLight() = 0; 159 virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false ) = 0; 160 virtual void GetRenderLight( renderLight_t *re ) = 0; 161 virtual void ForceUpdate() = 0; 162 virtual int GetIndex() = 0; 163 }; 164 165 166 // idRenderEntity should become the new public interface replacing the qhandle_t to entity defs in the idRenderWorld interface 167 class idRenderEntity { 168 public: ~idRenderEntity()169 virtual ~idRenderEntity() {} 170 171 virtual void FreeRenderEntity() = 0; 172 virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false ) = 0; 173 virtual void GetRenderEntity( renderEntity_t *re ) = 0; 174 virtual void ForceUpdate() = 0; 175 virtual int GetIndex() = 0; 176 177 // overlays are extra polygons that deform with animating models for blood and damage marks 178 virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ) = 0; 179 virtual void RemoveDecals() = 0; 180 }; 181 182 183 class idRenderLightLocal : public idRenderLight { 184 public: 185 idRenderLightLocal(); 186 187 virtual void FreeRenderLight(); 188 virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false ); 189 virtual void GetRenderLight( renderLight_t *re ); 190 virtual void ForceUpdate(); 191 virtual int GetIndex(); 192 193 renderLight_t parms; // specification 194 195 bool lightHasMoved; // the light has changed its position since it was 196 // first added, so the prelight model is not valid 197 198 float modelMatrix[16]; // this is just a rearrangement of parms.axis and parms.origin 199 200 idRenderWorldLocal * world; 201 int index; // in world lightdefs 202 203 int areaNum; // if not -1, we may be able to cull all the light's 204 // interactions if !viewDef->connectedAreas[areaNum] 205 206 int lastModifiedFrameNum; // to determine if it is constantly changing, 207 // and should go in the dynamic frame memory, or kept 208 // in the cached memory 209 bool archived; // for demo writing 210 211 212 // derived information 213 idPlane lightProject[4]; 214 215 const idMaterial * lightShader; // guaranteed to be valid, even if parms.shader isn't 216 idImage * falloffImage; 217 218 idVec3 globalLightOrigin; // accounting for lightCenter and parallel 219 220 221 idPlane frustum[6]; // in global space, positive side facing out, last two are front/back 222 idWinding * frustumWindings[6]; // used for culling 223 srfTriangles_t * frustumTris; // triangulated frustumWindings[] 224 225 int numShadowFrustums; // one for projected lights, usually six for point lights 226 shadowFrustum_t shadowFrustums[6]; 227 228 int viewCount; // if == tr.viewCount, the light is on the viewDef->viewLights list 229 struct viewLight_s * viewLight; 230 231 areaReference_t * references; // each area the light is present in will have a lightRef 232 idInteraction * firstInteraction; // doubly linked list 233 idInteraction * lastInteraction; 234 235 struct doublePortal_s * foggedPortals; 236 }; 237 238 239 class idRenderEntityLocal : public idRenderEntity { 240 public: 241 idRenderEntityLocal(); 242 243 virtual void FreeRenderEntity(); 244 virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false ); 245 virtual void GetRenderEntity( renderEntity_t *re ); 246 virtual void ForceUpdate(); 247 virtual int GetIndex(); 248 249 // overlays are extra polygons that deform with animating models for blood and damage marks 250 virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ); 251 virtual void RemoveDecals(); 252 253 renderEntity_t parms; 254 255 float modelMatrix[16]; // this is just a rearrangement of parms.axis and parms.origin 256 257 idRenderWorldLocal * world; 258 int index; // in world entityDefs 259 260 int lastModifiedFrameNum; // to determine if it is constantly changing, 261 // and should go in the dynamic frame memory, or kept 262 // in the cached memory 263 bool archived; // for demo writing 264 265 idRenderModel * dynamicModel; // if parms.model->IsDynamicModel(), this is the generated data 266 int dynamicModelFrameCount; // continuously animating dynamic models will recreate 267 // dynamicModel if this doesn't == tr.viewCount 268 idRenderModel * cachedDynamicModel; 269 270 idBounds referenceBounds; // the local bounds used to place entityRefs, either from parms or a model 271 272 // a viewEntity_t is created whenever a idRenderEntityLocal is considered for inclusion 273 // in a given view, even if it turns out to not be visible 274 int viewCount; // if tr.viewCount == viewCount, viewEntity is valid, 275 // but the entity may still be off screen 276 struct viewEntity_s * viewEntity; // in frame temporary memory 277 278 int visibleCount; 279 // if tr.viewCount == visibleCount, at least one ambient 280 // surface has actually been added by R_AddAmbientDrawsurfs 281 // note that an entity could still be in the view frustum and not be visible due 282 // to portal passing 283 284 idRenderModelDecal * decals; // chain of decals that have been projected on this model 285 idRenderModelOverlay * overlay; // blood overlays on animated models 286 287 areaReference_t * entityRefs; // chain of all references 288 idInteraction * firstInteraction; // doubly linked list 289 idInteraction * lastInteraction; 290 291 bool needsPortalSky; 292 }; 293 294 295 // viewLights are allocated on the frame temporary stack memory 296 // a viewLight contains everything that the back end needs out of an idRenderLightLocal, 297 // which the front end may be modifying simultaniously if running in SMP mode. 298 // a viewLight may exist even without any surfaces, and may be relevent for fogging, 299 // but should never exist if its volume does not intersect the view frustum 300 typedef struct viewLight_s { 301 struct viewLight_s * next; 302 303 // back end should NOT reference the lightDef, because it can change when running SMP 304 idRenderLightLocal * lightDef; 305 306 // for scissor clipping, local inside renderView viewport 307 // scissorRect.Empty() is true if the viewEntity_t was never actually 308 // seen through any portals 309 idScreenRect scissorRect; 310 311 // if the view isn't inside the light, we can use the non-reversed 312 // shadow drawing, avoiding the draws of the front and rear caps 313 bool viewInsideLight; 314 315 // true if globalLightOrigin is inside the view frustum, even if it may 316 // be obscured by geometry. This allows us to skip shadows from non-visible objects 317 bool viewSeesGlobalLightOrigin; 318 319 // if !viewInsideLight, the corresponding bit for each of the shadowFrustum 320 // projection planes that the view is on the negative side of will be set, 321 // allowing us to skip drawing the projected caps of shadows if we can't see the face 322 int viewSeesShadowPlaneBits; 323 324 idVec3 globalLightOrigin; // global light origin used by backend 325 idPlane lightProject[4]; // light project used by backend 326 idPlane fogPlane; // fog plane for backend fog volume rendering 327 const srfTriangles_t * frustumTris; // light frustum for backend fog volume rendering 328 const idMaterial * lightShader; // light shader used by backend 329 const float * shaderRegisters; // shader registers used by backend 330 idImage * falloffImage; // falloff image used by backend 331 332 const struct drawSurf_s *globalShadows; // shadow everything 333 const struct drawSurf_s *localInteractions; // don't get local shadows 334 const struct drawSurf_s *localShadows; // don't shadow local Surfaces 335 const struct drawSurf_s *globalInteractions; // get shadows from everything 336 const struct drawSurf_s *translucentInteractions; // get shadows from everything 337 } viewLight_t; 338 339 340 // a viewEntity is created whenever a idRenderEntityLocal is considered for inclusion 341 // in the current view, but it may still turn out to be culled. 342 // viewEntity are allocated on the frame temporary stack memory 343 // a viewEntity contains everything that the back end needs out of a idRenderEntityLocal, 344 // which the front end may be modifying simultaniously if running in SMP mode. 345 // A single entityDef can generate multiple viewEntity_t in a single frame, as when seen in a mirror 346 typedef struct viewEntity_s { 347 struct viewEntity_s *next; 348 349 // back end should NOT reference the entityDef, because it can change when running SMP 350 idRenderEntityLocal *entityDef; 351 352 // for scissor clipping, local inside renderView viewport 353 // scissorRect.Empty() is true if the viewEntity_t was never actually 354 // seen through any portals, but was created for shadow casting. 355 // a viewEntity can have a non-empty scissorRect, meaning that an area 356 // that it is in is visible, and still not be visible. 357 idScreenRect scissorRect; 358 359 bool weaponDepthHack; 360 float modelDepthHack; 361 362 float modelMatrix[16]; // local coords to global coords 363 float modelViewMatrix[16]; // local coords to eye coords 364 } viewEntity_t; 365 366 367 const int MAX_CLIP_PLANES = 1; // we may expand this to six for some subview issues 368 369 // viewDefs are allocated on the frame temporary stack memory 370 typedef struct viewDef_s { 371 // specified in the call to DrawScene() 372 renderView_t renderView; 373 374 float projectionMatrix[16]; 375 viewEntity_t worldSpace; 376 377 idRenderWorldLocal *renderWorld; 378 379 float floatTime; 380 381 idVec3 initialViewAreaOrigin; 382 // Used to find the portalArea that view flooding will take place from. 383 // for a normal view, the initialViewOrigin will be renderView.viewOrg, 384 // but a mirror may put the projection origin outside 385 // of any valid area, or in an unconnected area of the map, so the view 386 // area must be based on a point just off the surface of the mirror / subview. 387 // It may be possible to get a failed portal pass if the plane of the 388 // mirror intersects a portal, and the initialViewAreaOrigin is on 389 // a different side than the renderView.viewOrg is. 390 391 bool isSubview; // true if this view is not the main view 392 bool isMirror; // the portal is a mirror, invert the face culling 393 bool isXraySubview; 394 395 bool isEditor; 396 397 int numClipPlanes; // mirrors will often use a single clip plane 398 idPlane clipPlanes[MAX_CLIP_PLANES]; // in world space, the positive side 399 // of the plane is the visible side 400 idScreenRect viewport; // in real pixels and proper Y flip 401 402 idScreenRect scissor; 403 // for scissor clipping, local inside renderView viewport 404 // subviews may only be rendering part of the main view 405 // these are real physical pixel values, possibly scaled and offset from the 406 // renderView x/y/width/height 407 408 struct viewDef_s * superView; // never go into an infinite subview loop 409 struct drawSurf_s * subviewSurface; 410 411 // drawSurfs are the visible surfaces of the viewEntities, sorted 412 // by the material sort parameter 413 drawSurf_t ** drawSurfs; // we don't use an idList for this, because 414 int numDrawSurfs; // it is allocated in frame temporary memory 415 int maxDrawSurfs; // may be resized 416 417 struct viewLight_s *viewLights; // chain of all viewLights effecting view 418 struct viewEntity_s *viewEntitys; // chain of all viewEntities effecting view, including off screen ones casting shadows 419 // we use viewEntities as a check to see if a given view consists solely 420 // of 2D rendering, which we can optimize in certain ways. A 2D view will 421 // not have any viewEntities 422 423 idPlane frustum[5]; // positive sides face outward, [4] is the front clip plane 424 idFrustum viewFrustum; 425 426 int areaNum; // -1 = not in a valid area 427 428 bool * connectedAreas; 429 // An array in frame temporary memory that lists if an area can be reached without 430 // crossing a closed door. This is used to avoid drawing interactions 431 // when the light is behind a closed door. 432 433 } viewDef_t; 434 435 436 // complex light / surface interactions are broken up into multiple passes of a 437 // simple interaction shader 438 typedef struct { 439 const drawSurf_t * surf; 440 441 idImage * lightImage; 442 idImage * lightFalloffImage; 443 idImage * bumpImage; 444 idImage * diffuseImage; 445 idImage * specularImage; 446 447 idVec4 diffuseColor; // may have a light color baked into it, will be < tr.backEndRendererMaxLight 448 idVec4 specularColor; // may have a light color baked into it, will be < tr.backEndRendererMaxLight 449 stageVertexColor_t vertexColor; // applies to both diffuse and specular 450 451 int ambientLight; // use tr.ambientNormalMap instead of normalization cube map 452 // (not a bool just to avoid an uninitialized memory check of the pad region by valgrind) 453 454 // these are loaded into the vertex program 455 idVec4 localLightOrigin; 456 idVec4 localViewOrigin; 457 idVec4 lightProjection[4]; // in local coordinates, possibly with a texture matrix baked in 458 idVec4 bumpMatrix[2]; 459 idVec4 diffuseMatrix[2]; 460 idVec4 specularMatrix[2]; 461 } drawInteraction_t; 462 463 464 /* 465 ============================================================= 466 467 RENDERER BACK END COMMAND QUEUE 468 469 TR_CMDS 470 471 ============================================================= 472 */ 473 474 typedef enum { 475 RC_NOP, 476 RC_DRAW_VIEW, 477 RC_SET_BUFFER, 478 RC_COPY_RENDER, 479 RC_SWAP_BUFFERS // can't just assume swap at end of list because 480 // of forced list submission before syncs 481 } renderCommand_t; 482 483 typedef struct { 484 renderCommand_t commandId, *next; 485 } emptyCommand_t; 486 487 typedef struct { 488 renderCommand_t commandId, *next; 489 GLenum buffer; 490 int frameCount; 491 } setBufferCommand_t; 492 493 typedef struct { 494 renderCommand_t commandId, *next; 495 viewDef_t *viewDef; 496 } drawSurfsCommand_t; 497 498 typedef struct { 499 renderCommand_t commandId, *next; 500 int x, y, imageWidth, imageHeight; 501 idImage *image; 502 int cubeFace; // when copying to a cubeMap 503 } copyRenderCommand_t; 504 505 506 //======================================================================= 507 508 // this is the inital allocation for max number of drawsurfs 509 // in a given view, but it will automatically grow if needed 510 const int INITIAL_DRAWSURFS = 0x4000; 511 512 // a request for frame memory will never fail 513 // (until malloc fails), but it may force the 514 // allocation of a new memory block that will 515 // be discontinuous with the existing memory 516 typedef struct frameMemoryBlock_s { 517 struct frameMemoryBlock_s *next; 518 int size; 519 int used; 520 int poop; // so that base is 16 byte aligned 521 byte base[4]; // dynamically allocated as [size] 522 } frameMemoryBlock_t; 523 524 // all of the information needed by the back end must be 525 // contained in a frameData_t. This entire structure is 526 // duplicated so the front and back end can run in parallel 527 // on an SMP machine (OBSOLETE: this capability has been removed) 528 typedef struct { 529 // one or more blocks of memory for all frame 530 // temporary allocations 531 frameMemoryBlock_t *memory; 532 533 // alloc will point somewhere into the memory chain 534 frameMemoryBlock_t *alloc; 535 536 srfTriangles_t * firstDeferredFreeTriSurf; 537 srfTriangles_t * lastDeferredFreeTriSurf; 538 539 int memoryHighwater; // max used on any frame 540 541 // the currently building command list 542 // commands can be inserted at the front if needed, as for required 543 // dynamically generated textures 544 emptyCommand_t *cmdHead, *cmdTail; // may be of other command type based on commandId 545 } frameData_t; 546 547 extern frameData_t *frameData; 548 549 //======================================================================= 550 551 void R_LockSurfaceScene( viewDef_t *parms ); 552 void R_ClearCommandChain( void ); 553 void R_AddDrawViewCmd( viewDef_t *parms ); 554 555 void R_ReloadGuis_f( const idCmdArgs &args ); 556 void R_ListGuis_f( const idCmdArgs &args ); 557 558 void *R_GetCommandBuffer( int bytes ); 559 560 // this allows a global override of all materials 561 bool R_GlobalShaderOverride( const idMaterial **shader ); 562 563 // this does various checks before calling the idDeclSkin 564 const idMaterial *R_RemapShaderBySkin( const idMaterial *shader, const idDeclSkin *customSkin, const idMaterial *customShader ); 565 566 567 //==================================================== 568 569 570 /* 571 ** performanceCounters_t 572 */ 573 typedef struct { 574 int c_sphere_cull_in, c_sphere_cull_clip, c_sphere_cull_out; 575 int c_box_cull_in, c_box_cull_out; 576 int c_createInteractions; // number of calls to idInteraction::CreateInteraction 577 int c_createLightTris; 578 int c_createShadowVolumes; 579 int c_generateMd5; 580 int c_entityDefCallbacks; 581 int c_alloc, c_free; // counts for R_StaticAllc/R_StaticFree 582 int c_visibleViewEntities; 583 int c_shadowViewEntities; 584 int c_viewLights; 585 int c_numViews; // number of total views rendered 586 int c_deformedSurfaces; // idMD5Mesh::GenerateSurface 587 int c_deformedVerts; // idMD5Mesh::GenerateSurface 588 int c_deformedIndexes; // idMD5Mesh::GenerateSurface 589 int c_tangentIndexes; // R_DeriveTangents() 590 int c_entityUpdates, c_lightUpdates, c_entityReferences, c_lightReferences; 591 int c_guiSurfs; 592 int frontEndMsec; // sum of time in all RE_RenderScene's in a frame 593 } performanceCounters_t; 594 595 596 typedef struct { 597 int current2DMap; 598 int current3DMap; 599 int currentCubeMap; 600 int texEnv; 601 textureType_t textureType; 602 } tmu_t; 603 604 const int MAX_MULTITEXTURE_UNITS = 8; 605 typedef struct { 606 tmu_t tmu[MAX_MULTITEXTURE_UNITS]; 607 int currenttmu; 608 609 int faceCulling; 610 int glStateBits; 611 bool forceGlState; // the next GL_State will ignore glStateBits and set everything 612 } glstate_t; 613 614 615 typedef struct { 616 int c_surfaces; 617 int c_shaders; 618 int c_vertexes; 619 int c_indexes; // one set per pass 620 int c_totalIndexes; // counting all passes 621 622 int c_drawElements; 623 int c_drawIndexes; 624 int c_drawVertexes; 625 int c_drawRefIndexes; 626 int c_drawRefVertexes; 627 628 int c_shadowElements; 629 int c_shadowIndexes; 630 int c_shadowVertexes; 631 632 int c_vboIndexes; 633 float c_overDraw; 634 635 float maxLightValue; // for light scale 636 int msec; // total msec for backend run 637 } backEndCounters_t; 638 639 // all state modified by the back end is separated 640 // from the front end state 641 typedef struct { 642 int frameCount; // used to track all images used in a frame 643 const viewDef_t * viewDef; 644 backEndCounters_t pc; 645 646 const viewEntity_t *currentSpace; // for detecting when a matrix must change 647 idScreenRect currentScissor; 648 // for scissor clipping, local inside renderView viewport 649 650 viewLight_t * vLight; 651 int depthFunc; // GLS_DEPTHFUNC_EQUAL, or GLS_DEPTHFUNC_LESS for translucent 652 float lightTextureMatrix[16]; // only if lightStage->texture.hasMatrix 653 float lightColor[4]; // evaluation of current light's color stage 654 655 float lightScale; // Every light color calaculation will be multiplied by this, 656 // which will guarantee that the result is < tr.backEndRendererMaxLight 657 // A card with high dynamic range will have this set to 1.0 658 float overBright; // The amount that all light interactions must be multiplied by 659 // with post processing to get the desired total light level. 660 // A high dynamic range card will have this set to 1.0. 661 662 bool currentRenderCopied; // true if any material has already referenced _currentRender 663 664 // our OpenGL state deltas 665 glstate_t glState; 666 667 int c_copyFrameBuffer; 668 } backEndState_t; 669 670 671 const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for guis, will 672 // be automatically expanded as needed 673 674 typedef enum { 675 BE_ARB2, 676 BE_BAD 677 } backEndName_t; 678 679 typedef struct { 680 int x, y, width, height; // these are in physical, OpenGL Y-at-bottom pixels 681 } renderCrop_t; 682 static const int MAX_RENDER_CROPS = 8; 683 684 /* 685 ** Most renderer globals are defined here. 686 ** backend functions should never modify any of these fields, 687 ** but may read fields that aren't dynamically modified 688 ** by the frontend. 689 */ 690 class idRenderSystemLocal : public idRenderSystem { 691 public: 692 // external functions 693 virtual void Init( void ); 694 virtual void Shutdown( void ); 695 virtual void InitOpenGL( void ); 696 virtual void ShutdownOpenGL( void ); 697 virtual bool IsOpenGLRunning( void ) const; 698 virtual bool IsFullScreen( void ) const; 699 virtual int GetScreenWidth( void ) const; 700 virtual int GetScreenHeight( void ) const; 701 virtual idRenderWorld * AllocRenderWorld( void ); 702 virtual void FreeRenderWorld( idRenderWorld *rw ); 703 virtual void BeginLevelLoad( void ); 704 virtual void EndLevelLoad( void ); 705 virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ); 706 virtual void SetColor( const idVec4 &rgba ); 707 virtual void SetColor4( float r, float g, float b, float a ); 708 virtual void DrawStretchPic ( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material, 709 bool clip = true, float x = 0.0f, float y = 0.0f, float w = 640.0f, float h = 0.0f ); 710 virtual void DrawStretchPic ( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ); 711 712 virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ); 713 virtual void GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ); 714 virtual void GetGLSettings( int& width, int& height ); 715 virtual void PrintMemInfo( MemInfo_t *mi ); 716 717 virtual void DrawSmallChar( int x, int y, int ch, const idMaterial *material ); 718 virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ); 719 virtual void DrawBigChar( int x, int y, int ch, const idMaterial *material ); 720 virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ); 721 virtual void WriteDemoPics(); 722 virtual void DrawDemoPics(); 723 virtual void BeginFrame( int windowWidth, int windowHeight ); 724 virtual void EndFrame( int *frontEndMsec, int *backEndMsec ); 725 virtual void TakeScreenshot( int width, int height, const char *fileName, int downSample, renderView_t *ref ); 726 virtual void CropRenderSize( int width, int height, bool makePowerOfTwo = false, bool forceDimensions = false ); 727 virtual void CaptureRenderToImage( const char *imageName ); 728 virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha ); 729 virtual void UnCrop(); 730 virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ); 731 732 public: 733 // internal functions 734 idRenderSystemLocal( void ); 735 ~idRenderSystemLocal( void ); 736 737 void Clear( void ); 738 void SetBackEndRenderer(); // sets tr.backEndRenderer based on cvars 739 void RenderViewToViewport( const renderView_t *renderView, idScreenRect *viewport ); 740 741 public: 742 // renderer globals 743 bool registered; // cleared at shutdown, set at InitOpenGL 744 745 bool takingScreenshot; 746 747 int frameCount; // incremented every frame 748 int viewCount; // incremented every view (twice a scene if subviewed) 749 // and every R_MarkFragments call 750 751 int staticAllocCount; // running total of bytes allocated 752 753 float frameShaderTime; // shader time for all non-world 2D rendering 754 755 int viewportOffset[2]; // for doing larger-than-window tiled renderings 756 int tiledViewport[2]; 757 758 // determines which back end to use, and if vertex programs are in use 759 backEndName_t backEndRenderer; 760 bool backEndRendererHasVertexPrograms; 761 float backEndRendererMaxLight; // 1.0 for standard, unlimited for floats 762 // determines how much overbrighting needs 763 // to be done post-process 764 765 idVec4 ambientLightVector; // used for "ambient bump mapping" 766 767 float sortOffset; // for determinist sorting of equal sort materials 768 769 idList<idRenderWorldLocal*>worlds; 770 771 idRenderWorldLocal * primaryWorld; 772 renderView_t primaryRenderView; 773 viewDef_t * primaryView; 774 // many console commands need to know which world they should operate on 775 776 const idMaterial * defaultMaterial; 777 idImage * testImage; 778 idCinematic * testVideo; 779 float testVideoStartTime; 780 781 idImage * ambientCubeImage; // hack for testing dependent ambient lighting 782 783 viewDef_t * viewDef; 784 785 performanceCounters_t pc; // performance counters 786 787 drawSurfsCommand_t lockSurfacesCmd; // use this when r_lockSurfaces = 1 788 789 viewEntity_t identitySpace; // can use if we don't know viewDef->worldSpace is valid 790 int stencilIncr, stencilDecr; // GL_INCR / INCR_WRAP_EXT, GL_DECR / GL_DECR_EXT 791 792 renderCrop_t renderCrops[MAX_RENDER_CROPS]; 793 int currentRenderCrop; 794 795 // GUI drawing variables for surface creation 796 int guiRecursionLevel; // to prevent infinite overruns 797 class idGuiModel * guiModel; 798 class idGuiModel * demoGuiModel; 799 800 // DG: remember the original glConfig.vidWidth/Height values that get overwritten in BeginFrame() 801 // so they can be reset in EndFrame() (Editors tend to mess up the viewport by using BeginFrame()) 802 int origWidth; 803 int origHeight; 804 }; 805 806 extern backEndState_t backEnd; 807 extern idRenderSystemLocal tr; 808 extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init 809 810 811 // 812 // cvars 813 // 814 extern idCVar r_mode; // video mode number 815 extern idCVar r_displayRefresh; // optional display refresh rate option for vid mode 816 extern idCVar r_fullscreen; // 0 = windowed, 1 = full screen 817 extern idCVar r_fullscreenDesktop; // 0: 'real' fullscreen mode 1: keep resolution 'desktop' fullscreen mode 818 extern idCVar r_multiSamples; // number of antialiasing samples 819 820 extern idCVar r_ignore; // used for random debugging without defining new vars 821 extern idCVar r_ignore2; // used for random debugging without defining new vars 822 extern idCVar r_znear; // near Z clip plane 823 824 extern idCVar r_finish; // force a call to glFinish() every frame 825 extern idCVar r_frontBuffer; // draw to front buffer for debugging 826 extern idCVar r_swapInterval; // changes the GL swap interval 827 extern idCVar r_offsetFactor; // polygon offset parameter 828 extern idCVar r_offsetUnits; // polygon offset parameter 829 extern idCVar r_singleTriangle; // only draw a single triangle per primitive 830 extern idCVar r_clear; // force screen clear every frame 831 extern idCVar r_shadows; // enable shadows 832 extern idCVar r_subviewOnly; // 1 = don't render main view, allowing subviews to be debugged 833 extern idCVar r_lightScale; // all light intensities are multiplied by this, which is normally 2 834 extern idCVar r_flareSize; // scale the flare deforms from the material def 835 836 extern idCVar r_gamma; // changes gamma tables 837 extern idCVar r_brightness; // changes gamma tables 838 839 extern idCVar r_renderer; // arb2, etc 840 841 extern idCVar r_checkBounds; // compare all surface bounds with precalculated ones 842 843 extern idCVar r_useLightPortalFlow; // 1 = do a more precise area reference determination 844 extern idCVar r_useShadowSurfaceScissor;// 1 = scissor shadows by the scissor rect of the interaction surfaces 845 extern idCVar r_useConstantMaterials; // 1 = use pre-calculated material registers if possible 846 extern idCVar r_useInteractionTable; // create a full entityDefs * lightDefs table to make finding interactions faster 847 extern idCVar r_useNodeCommonChildren; // stop pushing reference bounds early when possible 848 extern idCVar r_useSilRemap; // 1 = consider verts with the same XYZ, but different ST the same for shadows 849 extern idCVar r_useCulling; // 0 = none, 1 = sphere, 2 = sphere + box 850 extern idCVar r_useLightCulling; // 0 = none, 1 = box, 2 = exact clip of polyhedron faces 851 extern idCVar r_useLightScissors; // 1 = use custom scissor rectangle for each light 852 extern idCVar r_useClippedLightScissors;// 0 = full screen when near clipped, 1 = exact when near clipped, 2 = exact always 853 extern idCVar r_useEntityCulling; // 0 = none, 1 = box 854 extern idCVar r_useEntityScissors; // 1 = use custom scissor rectangle for each entity 855 extern idCVar r_useInteractionCulling; // 1 = cull interactions 856 extern idCVar r_useInteractionScissors; // 1 = use a custom scissor rectangle for each interaction 857 extern idCVar r_useFrustumFarDistance; // if != 0 force the view frustum far distance to this distance 858 extern idCVar r_useShadowCulling; // try to cull shadows from partially visible lights 859 extern idCVar r_usePreciseTriangleInteractions; // 1 = do winding clipping to determine if each ambiguous tri should be lit 860 extern idCVar r_useTurboShadow; // 1 = use the infinite projection with W technique for dynamic shadows 861 extern idCVar r_useExternalShadows; // 1 = skip drawing caps when outside the light volume 862 extern idCVar r_useOptimizedShadows; // 1 = use the dmap generated static shadow volumes 863 extern idCVar r_useShadowVertexProgram; // 1 = do the shadow projection in the vertex program on capable cards 864 extern idCVar r_useShadowProjectedCull; // 1 = discard triangles outside light volume before shadowing 865 extern idCVar r_useDeferredTangents; // 1 = don't always calc tangents after deform 866 extern idCVar r_useCachedDynamicModels; // 1 = cache snapshots of dynamic models 867 extern idCVar r_useTwoSidedStencil; // 1 = do stencil shadows in one pass with different ops on each side 868 extern idCVar r_useInfiniteFarZ; // 1 = use the no-far-clip-plane trick 869 extern idCVar r_useScissor; // 1 = scissor clip as portals and lights are processed 870 extern idCVar r_usePortals; // 1 = use portals to perform area culling, otherwise draw everything 871 extern idCVar r_useStateCaching; // avoid redundant state changes in GL_*() calls 872 extern idCVar r_useCombinerDisplayLists;// if 1, put all nvidia register combiner programming in display lists 873 extern idCVar r_useVertexBuffers; // if 0, don't use ARB_vertex_buffer_object for vertexes 874 extern idCVar r_useIndexBuffers; // if 0, don't use ARB_vertex_buffer_object for indexes 875 extern idCVar r_useEntityCallbacks; // if 0, issue the callback immediately at update time, rather than defering 876 extern idCVar r_lightAllBackFaces; // light all the back faces, even when they would be shadowed 877 extern idCVar r_useDepthBoundsTest; // use depth bounds test to reduce shadow fill 878 879 extern idCVar r_skipPostProcess; // skip all post-process renderings 880 extern idCVar r_skipSuppress; // ignore the per-view suppressions 881 extern idCVar r_skipInteractions; // skip all light/surface interaction drawing 882 extern idCVar r_skipFrontEnd; // bypasses all front end work, but 2D gui rendering still draws 883 extern idCVar r_skipBackEnd; // don't draw anything 884 extern idCVar r_skipCopyTexture; // do all rendering, but don't actually copyTexSubImage2D 885 extern idCVar r_skipRender; // skip 3D rendering, but pass 2D 886 extern idCVar r_skipRenderContext; // NULL the rendering context during backend 3D rendering 887 extern idCVar r_skipTranslucent; // skip the translucent interaction rendering 888 extern idCVar r_skipAmbient; // bypasses all non-interaction drawing 889 extern idCVar r_skipNewAmbient; // bypasses all vertex/fragment program ambients 890 extern idCVar r_skipBlendLights; // skip all blend lights 891 extern idCVar r_skipFogLights; // skip all fog lights 892 extern idCVar r_skipSubviews; // 1 = don't render any mirrors / cameras / etc 893 extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces 894 extern idCVar r_skipParticles; // 1 = don't render any particles 895 extern idCVar r_skipUpdates; // 1 = don't accept any entity or light updates, making everything static 896 extern idCVar r_skipDeforms; // leave all deform materials in their original state 897 extern idCVar r_skipDynamicTextures; // don't dynamically create textures 898 extern idCVar r_skipLightScale; // don't do any post-interaction light scaling, makes things dim on low-dynamic range cards 899 extern idCVar r_skipBump; // uses a flat surface instead of the bump map 900 extern idCVar r_skipSpecular; // use black for specular 901 extern idCVar r_skipDiffuse; // use black for diffuse 902 extern idCVar r_skipOverlays; // skip overlay surfaces 903 extern idCVar r_skipROQ; 904 905 extern idCVar r_ignoreGLErrors; 906 907 extern idCVar r_forceLoadImages; // draw all images to screen after registration 908 extern idCVar r_demonstrateBug; // used during development to show IHV's their problems 909 extern idCVar r_screenFraction; // for testing fill rate, the resolution of the entire screen can be changed 910 911 extern idCVar r_showUnsmoothedTangents; // highlight geometry rendered with unsmoothed tangents 912 extern idCVar r_showSilhouette; // highlight edges that are casting shadow planes 913 extern idCVar r_showVertexColor; // draws all triangles with the solid vertex color 914 extern idCVar r_showUpdates; // report entity and light updates and ref counts 915 extern idCVar r_showDemo; // report reads and writes to the demo file 916 extern idCVar r_showDynamic; // report stats on dynamic surface generation 917 extern idCVar r_showLightScale; // report the scale factor applied to drawing for overbrights 918 extern idCVar r_showIntensity; // draw the screen colors based on intensity, red = 0, green = 128, blue = 255 919 extern idCVar r_showDefs; // report the number of modeDefs and lightDefs in view 920 extern idCVar r_showTrace; // show the intersection of an eye trace with the world 921 extern idCVar r_showSmp; // show which end (front or back) is blocking 922 extern idCVar r_showDepth; // display the contents of the depth buffer and the depth range 923 extern idCVar r_showImages; // draw all images to screen instead of rendering 924 extern idCVar r_showTris; // enables wireframe rendering of the world 925 extern idCVar r_showSurfaceInfo; // show surface material name under crosshair 926 extern idCVar r_showNormals; // draws wireframe normals 927 extern idCVar r_showEdges; // draw the sil edges 928 extern idCVar r_showViewEntitys; // displays the bounding boxes of all view models and optionally the index 929 extern idCVar r_showTexturePolarity; // shade triangles by texture area polarity 930 extern idCVar r_showTangentSpace; // shade triangles by tangent space 931 extern idCVar r_showDominantTri; // draw lines from vertexes to center of dominant triangles 932 extern idCVar r_showTextureVectors; // draw each triangles texture (tangent) vectors 933 extern idCVar r_showLights; // 1 = print light info, 2 = also draw volumes 934 extern idCVar r_showLightCount; // colors surfaces based on light count 935 extern idCVar r_showShadows; // visualize the stencil shadow volumes 936 extern idCVar r_showShadowCount; // colors screen based on shadow volume depth complexity 937 extern idCVar r_showLightScissors; // show light scissor rectangles 938 extern idCVar r_showEntityScissors; // show entity scissor rectangles 939 extern idCVar r_showInteractionFrustums;// show a frustum for each interaction 940 extern idCVar r_showInteractionScissors;// show screen rectangle which contains the interaction frustum 941 extern idCVar r_showMemory; // print frame memory utilization 942 extern idCVar r_showCull; // report sphere and box culling stats 943 extern idCVar r_showInteractions; // report interaction generation activity 944 extern idCVar r_showSurfaces; // report surface/light/shadow counts 945 extern idCVar r_showPrimitives; // report vertex/index/draw counts 946 extern idCVar r_showPortals; // draw portal outlines in color based on passed / not passed 947 extern idCVar r_showAlloc; // report alloc/free counts 948 extern idCVar r_showSkel; // draw the skeleton when model animates 949 extern idCVar r_showOverDraw; // show overdraw 950 extern idCVar r_jointNameScale; // size of joint names when r_showskel is set to 1 951 extern idCVar r_jointNameOffset; // offset of joint names when r_showskel is set to 1 952 953 extern idCVar r_testGamma; // draw a grid pattern to test gamma levels 954 extern idCVar r_testStepGamma; // draw a grid pattern to test gamma levels 955 extern idCVar r_testGammaBias; // draw a grid pattern to test gamma levels 956 957 extern idCVar r_testARBProgram; // experiment with vertex/fragment programs 958 959 extern idCVar r_singleLight; // suppress all but one light 960 extern idCVar r_singleEntity; // suppress all but one entity 961 extern idCVar r_singleArea; // only draw the portal area the view is actually in 962 extern idCVar r_singleSurface; // suppress all but one surface on each entity 963 extern idCVar r_shadowPolygonOffset; // bias value added to depth test for stencil shadow drawing 964 extern idCVar r_shadowPolygonFactor; // scale value for stencil shadow drawing 965 966 extern idCVar r_jitter; // randomly subpixel jitter the projection matrix 967 extern idCVar r_lightSourceRadius; // for soft-shadow sampling 968 extern idCVar r_lockSurfaces; 969 extern idCVar r_orderIndexes; // perform index reorganization to optimize vertex use 970 971 extern idCVar r_debugLineDepthTest; // perform depth test on debug lines 972 extern idCVar r_debugLineWidth; // width of debug lines 973 extern idCVar r_debugArrowStep; // step size of arrow cone line rotation in degrees 974 extern idCVar r_debugPolygonFilled; 975 976 extern idCVar r_materialOverride; // override all materials 977 978 extern idCVar r_debugRenderToTexture; 979 980 /* 981 ==================================================================== 982 983 GL wrapper/helper functions 984 985 ==================================================================== 986 */ 987 988 void GL_SelectTexture( int unit ); 989 void GL_CheckErrors( void ); 990 void GL_ClearStateDelta( void ); 991 void GL_State( int stateVector ); 992 void GL_TexEnv( int env ); 993 void GL_Cull( int cullType ); 994 995 const int GLS_SRCBLEND_ZERO = 0x00000001; 996 const int GLS_SRCBLEND_ONE = 0x0; 997 const int GLS_SRCBLEND_DST_COLOR = 0x00000003; 998 const int GLS_SRCBLEND_ONE_MINUS_DST_COLOR = 0x00000004; 999 const int GLS_SRCBLEND_SRC_ALPHA = 0x00000005; 1000 const int GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA = 0x00000006; 1001 const int GLS_SRCBLEND_DST_ALPHA = 0x00000007; 1002 const int GLS_SRCBLEND_ONE_MINUS_DST_ALPHA = 0x00000008; 1003 const int GLS_SRCBLEND_ALPHA_SATURATE = 0x00000009; 1004 const int GLS_SRCBLEND_BITS = 0x0000000f; 1005 1006 const int GLS_DSTBLEND_ZERO = 0x0; 1007 const int GLS_DSTBLEND_ONE = 0x00000020; 1008 const int GLS_DSTBLEND_SRC_COLOR = 0x00000030; 1009 const int GLS_DSTBLEND_ONE_MINUS_SRC_COLOR = 0x00000040; 1010 const int GLS_DSTBLEND_SRC_ALPHA = 0x00000050; 1011 const int GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA = 0x00000060; 1012 const int GLS_DSTBLEND_DST_ALPHA = 0x00000070; 1013 const int GLS_DSTBLEND_ONE_MINUS_DST_ALPHA = 0x00000080; 1014 const int GLS_DSTBLEND_BITS = 0x000000f0; 1015 1016 1017 // these masks are the inverse, meaning when set the glColorMask value will be 0, 1018 // preventing that channel from being written 1019 const int GLS_DEPTHMASK = 0x00000100; 1020 const int GLS_REDMASK = 0x00000200; 1021 const int GLS_GREENMASK = 0x00000400; 1022 const int GLS_BLUEMASK = 0x00000800; 1023 const int GLS_ALPHAMASK = 0x00001000; 1024 const int GLS_COLORMASK = (GLS_REDMASK|GLS_GREENMASK|GLS_BLUEMASK); 1025 1026 const int GLS_POLYMODE_LINE = 0x00002000; 1027 1028 const int GLS_DEPTHFUNC_ALWAYS = 0x00010000; 1029 const int GLS_DEPTHFUNC_EQUAL = 0x00020000; 1030 const int GLS_DEPTHFUNC_LESS = 0x0; 1031 1032 const int GLS_ATEST_EQ_255 = 0x10000000; 1033 const int GLS_ATEST_LT_128 = 0x20000000; 1034 const int GLS_ATEST_GE_128 = 0x40000000; 1035 const int GLS_ATEST_BITS = 0x70000000; 1036 1037 const int GLS_DEFAULT = GLS_DEPTHFUNC_ALWAYS; 1038 1039 void R_Init( void ); 1040 void R_InitOpenGL( void ); 1041 1042 void R_DoneFreeType( void ); 1043 1044 void R_SetColorMappings( void ); 1045 1046 void R_ScreenShot_f( const idCmdArgs &args ); 1047 void R_StencilShot( void ); 1048 1049 bool R_CheckExtension( const char *name ); 1050 1051 1052 /* 1053 ==================================================================== 1054 1055 IMPLEMENTATION SPECIFIC FUNCTIONS 1056 1057 ==================================================================== 1058 */ 1059 1060 typedef struct { 1061 int width; 1062 int height; 1063 bool fullScreen; 1064 bool stereo; 1065 int displayHz; 1066 int multiSamples; 1067 } glimpParms_t; 1068 1069 bool GLimp_Init( glimpParms_t parms ); 1070 // If the desired mode can't be set satisfactorily, false will be returned. 1071 // The renderer will then reset the glimpParms to "safe mode" of 640x480 1072 // fullscreen and try again. If that also fails, the error will be fatal. 1073 1074 bool GLimp_SetScreenParms( glimpParms_t parms ); 1075 // will set up gl up with the new parms 1076 1077 void GLimp_Shutdown( void ); 1078 // Destroys the rendering context, closes the window, resets the resolution, 1079 // and resets the gamma ramps. 1080 1081 void GLimp_SwapBuffers( void ); 1082 // Calls the system specific swapbuffers routine, and may also perform 1083 // other system specific cvar checks that happen every frame. 1084 // This will not be called if 'r_drawBuffer GL_FRONT' 1085 1086 void GLimp_SetGamma( unsigned short red[256], 1087 unsigned short green[256], 1088 unsigned short blue[256] ); 1089 // Sets the hardware gamma ramps for gamma and brightness adjustment. 1090 // These are now taken as 16 bit values, so we can take full advantage 1091 // of dacs with >8 bits of precision 1092 1093 1094 // Returns false if the system only has a single processor 1095 1096 void GLimp_ActivateContext( void ); 1097 void GLimp_DeactivateContext( void ); 1098 // These are used for managing SMP handoffs of the OpenGL context 1099 // between threads, and as a performance tunining aid. Setting 1100 // 'r_skipRenderContext 1' will call GLimp_DeactivateContext() before 1101 // the 3D rendering code, and GLimp_ActivateContext() afterwards. On 1102 // most OpenGL implementations, this will result in all OpenGL calls 1103 // being immediate returns, which lets us guage how much time is 1104 // being spent inside OpenGL. 1105 1106 const int GRAB_ENABLE = (1 << 0); 1107 const int GRAB_REENABLE = (1 << 1); 1108 const int GRAB_HIDECURSOR = (1 << 2); 1109 const int GRAB_SETSTATE = (1 << 3); 1110 1111 void GLimp_GrabInput(int flags); 1112 /* 1113 ==================================================================== 1114 1115 MAIN 1116 1117 ==================================================================== 1118 */ 1119 1120 void R_RenderView( viewDef_t *parms ); 1121 1122 // performs radius cull first, then corner cull 1123 bool R_CullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); 1124 bool R_RadiusCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); 1125 bool R_CornerCullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); 1126 1127 void R_AxisToModelMatrix( const idMat3 &axis, const idVec3 &origin, float modelMatrix[16] ); 1128 1129 // note that many of these assume a normalized matrix, and will not work with scaled axis 1130 void R_GlobalPointToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); 1131 void R_GlobalVectorToLocal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); 1132 void R_GlobalPlaneToLocal( const float modelMatrix[16], const idPlane &in, idPlane &out ); 1133 void R_PointTimesMatrix( const float modelMatrix[16], const idVec4 &in, idVec4 &out ); 1134 void R_LocalPointToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); 1135 void R_LocalVectorToGlobal( const float modelMatrix[16], const idVec3 &in, idVec3 &out ); 1136 void R_LocalPlaneToGlobal( const float modelMatrix[16], const idPlane &in, idPlane &out ); 1137 void R_TransformEyeZToWin( float src_z, const float *projectionMatrix, float &dst_z ); 1138 1139 void R_GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ); 1140 1141 void R_TransformModelToClip( const idVec3 &src, const float *modelMatrix, const float *projectionMatrix, idPlane &eye, idPlane &dst ); 1142 1143 void R_TransformClipToDevice( const idPlane &clip, const viewDef_t *view, idVec3 &normalized ); 1144 1145 void R_TransposeGLMatrix( const float in[16], float out[16] ); 1146 1147 void R_SetViewMatrix( viewDef_t *viewDef ); 1148 1149 void myGlMultMatrix( const float *a, const float *b, float *out ); 1150 1151 /* 1152 ============================================================ 1153 1154 LIGHT 1155 1156 ============================================================ 1157 */ 1158 1159 void R_ListRenderLightDefs_f( const idCmdArgs &args ); 1160 void R_ListRenderEntityDefs_f( const idCmdArgs &args ); 1161 1162 bool R_IssueEntityDefCallback( idRenderEntityLocal *def ); 1163 idRenderModel *R_EntityDefDynamicModel( idRenderEntityLocal *def ); 1164 1165 viewEntity_t *R_SetEntityDefViewEntity( idRenderEntityLocal *def ); 1166 viewLight_t *R_SetLightDefViewLight( idRenderLightLocal *def ); 1167 1168 void R_AddDrawSurf( const srfTriangles_t *tri, const viewEntity_t *space, const renderEntity_t *renderEntity, 1169 const idMaterial *shader, const idScreenRect &scissor ); 1170 1171 void R_LinkLightSurf( const drawSurf_t **link, const srfTriangles_t *tri, const viewEntity_t *space, 1172 const idRenderLightLocal *light, const idMaterial *shader, const idScreenRect &scissor, bool viewInsideShadow ); 1173 1174 bool R_CreateAmbientCache( srfTriangles_t *tri, bool needsLighting ); 1175 bool R_CreateLightingCache( const idRenderEntityLocal *ent, const idRenderLightLocal *light, srfTriangles_t *tri ); 1176 void R_CreatePrivateShadowCache( srfTriangles_t *tri ); 1177 void R_CreateVertexProgramShadowCache( srfTriangles_t *tri ); 1178 1179 /* 1180 ============================================================ 1181 1182 LIGHTRUN 1183 1184 ============================================================ 1185 */ 1186 1187 void R_RegenerateWorld_f( const idCmdArgs &args ); 1188 1189 void R_ModulateLights_f( const idCmdArgs &args ); 1190 1191 void R_SetLightProject( idPlane lightProject[4], const idVec3 origin, const idVec3 targetPoint, 1192 const idVec3 rightVector, const idVec3 upVector, const idVec3 start, const idVec3 stop ); 1193 1194 void R_AddLightSurfaces( void ); 1195 void R_AddModelSurfaces( void ); 1196 void R_RemoveUnecessaryViewLights( void ); 1197 1198 void R_FreeDerivedData( void ); 1199 void R_ReCreateWorldReferences( void ); 1200 1201 void R_CreateEntityRefs( idRenderEntityLocal *def ); 1202 void R_CreateLightRefs( idRenderLightLocal *light ); 1203 1204 void R_DeriveLightData( idRenderLightLocal *light ); 1205 void R_FreeLightDefDerivedData( idRenderLightLocal *light ); 1206 void R_CheckForEntityDefsUsingModel( idRenderModel *model ); 1207 1208 void R_ClearEntityDefDynamicModel( idRenderEntityLocal *def ); 1209 void R_FreeEntityDefDerivedData( idRenderEntityLocal *def, bool keepDecals, bool keepCachedDynamicModel ); 1210 void R_FreeEntityDefCachedDynamicModel( idRenderEntityLocal *def ); 1211 void R_FreeEntityDefDecals( idRenderEntityLocal *def ); 1212 void R_FreeEntityDefOverlay( idRenderEntityLocal *def ); 1213 void R_FreeEntityDefFadedDecals( idRenderEntityLocal *def, int time ); 1214 1215 void R_CreateLightDefFogPortals( idRenderLightLocal *ldef ); 1216 1217 /* 1218 ============================================================ 1219 1220 POLYTOPE 1221 1222 ============================================================ 1223 */ 1224 1225 srfTriangles_t *R_PolytopeSurface( int numPlanes, const idPlane *planes, idWinding **windings ); 1226 1227 /* 1228 ============================================================ 1229 1230 RENDER 1231 1232 ============================================================ 1233 */ 1234 1235 void RB_EnterWeaponDepthHack(); 1236 void RB_EnterModelDepthHack( float depth ); 1237 void RB_LeaveDepthHack(); 1238 void RB_DrawElementsImmediate( const srfTriangles_t *tri ); 1239 void RB_RenderTriangleSurface( const srfTriangles_t *tri ); 1240 void RB_T_RenderTriangleSurface( const drawSurf_t *surf ); 1241 void RB_RenderDrawSurfListWithFunction( drawSurf_t **drawSurfs, int numDrawSurfs, 1242 void (*triFunc_)( const drawSurf_t *) ); 1243 void RB_RenderDrawSurfChainWithFunction( const drawSurf_t *drawSurfs, 1244 void (*triFunc_)( const drawSurf_t *) ); 1245 void RB_DrawShaderPasses( drawSurf_t **drawSurfs, int numDrawSurfs ); 1246 void RB_LoadShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture ); 1247 void RB_GetShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture, float matrix[16] ); 1248 void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInteraction)(const drawInteraction_t *) ); 1249 1250 const shaderStage_t *RB_SetLightTexture( const idRenderLightLocal *light ); 1251 1252 void RB_DrawView( const void *data ); 1253 1254 void RB_DetermineLightScale( void ); 1255 void RB_STD_LightScale( void ); 1256 void RB_BeginDrawingView (void); 1257 1258 /* 1259 ============================================================ 1260 1261 DRAW_STANDARD 1262 1263 ============================================================ 1264 */ 1265 1266 void RB_DrawElementsWithCounters( const srfTriangles_t *tri ); 1267 void RB_DrawShadowElementsWithCounters( const srfTriangles_t *tri, int numIndexes ); 1268 void RB_STD_FillDepthBuffer( drawSurf_t **drawSurfs, int numDrawSurfs ); 1269 void RB_BindVariableStageImage( const textureStage_t *texture, const float *shaderRegisters ); 1270 void RB_BindStageTexture( const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf ); 1271 void RB_FinishStageTexture( const textureStage_t *texture, const drawSurf_t *surf ); 1272 void RB_StencilShadowPass( const drawSurf_t *drawSurfs ); 1273 void RB_STD_DrawView( void ); 1274 void RB_STD_FogAllLights( void ); 1275 void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float textureMatrix[16] ); 1276 1277 /* 1278 ============================================================ 1279 1280 DRAW_* 1281 1282 ============================================================ 1283 */ 1284 1285 void R_ARB2_Init( void ); 1286 void RB_ARB2_DrawInteractions( void ); 1287 void R_ReloadARBPrograms_f( const idCmdArgs &args ); 1288 int R_FindARBProgram( GLenum target, const char *program ); 1289 1290 typedef enum { 1291 PROG_INVALID, 1292 VPROG_INTERACTION, 1293 VPROG_ENVIRONMENT, 1294 VPROG_BUMPY_ENVIRONMENT, 1295 VPROG_STENCIL_SHADOW, 1296 VPROG_TEST, 1297 FPROG_INTERACTION, 1298 FPROG_ENVIRONMENT, 1299 FPROG_BUMPY_ENVIRONMENT, 1300 FPROG_TEST, 1301 VPROG_AMBIENT, 1302 FPROG_AMBIENT, 1303 VPROG_GLASSWARP, 1304 FPROG_GLASSWARP, 1305 PROG_USER 1306 } program_t; 1307 1308 /* 1309 1310 All vertex programs use the same constant register layout: 1311 1312 c[4] localLightOrigin 1313 c[5] localViewOrigin 1314 c[6] lightProjection S 1315 c[7] lightProjection T 1316 c[8] lightProjection Q 1317 c[9] lightFalloff S 1318 c[10] bumpMatrix S 1319 c[11] bumpMatrix T 1320 c[12] diffuseMatrix S 1321 c[13] diffuseMatrix T 1322 c[14] specularMatrix S 1323 c[15] specularMatrix T 1324 1325 1326 c[20] light falloff tq constant 1327 1328 // texture 0 was cube map 1329 // texture 1 will be the per-surface bump map 1330 // texture 2 will be the light falloff texture 1331 // texture 3 will be the light projection texture 1332 // texture 4 is the per-surface diffuse map 1333 // texture 5 is the per-surface specular map 1334 // texture 6 is the specular half angle cube map 1335 1336 */ 1337 1338 typedef enum { 1339 PP_LIGHT_ORIGIN = 4, 1340 PP_VIEW_ORIGIN, 1341 PP_LIGHT_PROJECT_S, 1342 PP_LIGHT_PROJECT_T, 1343 PP_LIGHT_PROJECT_Q, 1344 PP_LIGHT_FALLOFF_S, 1345 PP_BUMP_MATRIX_S, 1346 PP_BUMP_MATRIX_T, 1347 PP_DIFFUSE_MATRIX_S, 1348 PP_DIFFUSE_MATRIX_T, 1349 PP_SPECULAR_MATRIX_S, 1350 PP_SPECULAR_MATRIX_T, 1351 PP_COLOR_MODULATE, 1352 PP_COLOR_ADD, 1353 1354 PP_LIGHT_FALLOFF_TQ = 20 // only for NV programs 1355 } programParameter_t; 1356 1357 1358 /* 1359 ============================================================ 1360 1361 TR_STENCILSHADOWS 1362 1363 "facing" should have one more element than tri->numIndexes / 3, which should be set to 1 1364 1365 ============================================================ 1366 */ 1367 1368 void R_MakeShadowFrustums( idRenderLightLocal *def ); 1369 1370 typedef enum { 1371 SG_DYNAMIC, // use infinite projections 1372 SG_STATIC, // clip to bounds 1373 SG_OFFLINE // perform very time consuming optimizations 1374 } shadowGen_t; 1375 1376 srfTriangles_t *R_CreateShadowVolume( const idRenderEntityLocal *ent, 1377 const srfTriangles_t *tri, const idRenderLightLocal *light, 1378 shadowGen_t optimize, srfCullInfo_t &cullInfo ); 1379 1380 /* 1381 ============================================================ 1382 1383 TR_TURBOSHADOW 1384 1385 Fast, non-clipped overshoot shadow volumes 1386 1387 "facing" should have one more element than tri->numIndexes / 3, which should be set to 1 1388 calling this function may modify "facing" based on culling 1389 1390 ============================================================ 1391 */ 1392 1393 srfTriangles_t *R_CreateVertexProgramTurboShadowVolume( const idRenderEntityLocal *ent, 1394 const srfTriangles_t *tri, const idRenderLightLocal *light, 1395 srfCullInfo_t &cullInfo ); 1396 1397 srfTriangles_t *R_CreateTurboShadowVolume( const idRenderEntityLocal *ent, 1398 const srfTriangles_t *tri, const idRenderLightLocal *light, 1399 srfCullInfo_t &cullInfo ); 1400 1401 /* 1402 ============================================================ 1403 1404 util/shadowopt3 1405 1406 dmap time optimization of shadow volumes, called from R_CreateShadowVolume 1407 1408 ============================================================ 1409 */ 1410 1411 1412 typedef struct { 1413 idVec3 *verts; // includes both front and back projections, caller should free 1414 int numVerts; 1415 glIndex_t *indexes; // caller should free 1416 1417 // indexes must be sorted frontCap, rearCap, silPlanes so the caps can be removed 1418 // when the viewer is in a position that they don't need to see them 1419 int numFrontCapIndexes; 1420 int numRearCapIndexes; 1421 int numSilPlaneIndexes; 1422 int totalIndexes; 1423 } optimizedShadow_t; 1424 1425 optimizedShadow_t SuperOptimizeOccluders( idVec4 *verts, glIndex_t *indexes, int numIndexes, 1426 idPlane projectionPlane, idVec3 projectionOrigin ); 1427 1428 void CleanupOptimizedShadowTris( srfTriangles_t *tri ); 1429 1430 /* 1431 ============================================================ 1432 1433 TRISURF 1434 1435 ============================================================ 1436 */ 1437 1438 #define USE_TRI_DATA_ALLOCATOR 1439 1440 void R_InitTriSurfData( void ); 1441 void R_ShutdownTriSurfData( void ); 1442 void R_PurgeTriSurfData( frameData_t *frame ); 1443 void R_ShowTriSurfMemory_f( const idCmdArgs &args ); 1444 1445 srfTriangles_t * R_AllocStaticTriSurf( void ); 1446 srfTriangles_t * R_CopyStaticTriSurf( const srfTriangles_t *tri ); 1447 void R_AllocStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ); 1448 void R_AllocStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ); 1449 void R_AllocStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ); 1450 void R_AllocStaticTriSurfPlanes( srfTriangles_t *tri, int numIndexes ); 1451 void R_ResizeStaticTriSurfVerts( srfTriangles_t *tri, int numVerts ); 1452 void R_ResizeStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes ); 1453 void R_ResizeStaticTriSurfShadowVerts( srfTriangles_t *tri, int numVerts ); 1454 void R_ReferenceStaticTriSurfVerts( srfTriangles_t *tri, const srfTriangles_t *reference ); 1455 void R_ReferenceStaticTriSurfIndexes( srfTriangles_t *tri, const srfTriangles_t *reference ); 1456 void R_FreeStaticTriSurfSilIndexes( srfTriangles_t *tri ); 1457 void R_FreeStaticTriSurf( srfTriangles_t *tri ); 1458 void R_FreeStaticTriSurfVertexCaches( srfTriangles_t *tri ); 1459 void R_ReallyFreeStaticTriSurf( srfTriangles_t *tri ); 1460 void R_FreeDeferredTriSurfs( frameData_t *frame ); 1461 int R_TriSurfMemory( const srfTriangles_t *tri ); 1462 1463 void R_BoundTriSurf( srfTriangles_t *tri ); 1464 void R_RemoveDuplicatedTriangles( srfTriangles_t *tri ); 1465 void R_CreateSilIndexes( srfTriangles_t *tri ); 1466 void R_RemoveDegenerateTriangles( srfTriangles_t *tri ); 1467 void R_RemoveUnusedVerts( srfTriangles_t *tri ); 1468 void R_RangeCheckIndexes( const srfTriangles_t *tri ); 1469 void R_CreateVertexNormals( srfTriangles_t *tri ); // also called by dmap 1470 void R_DeriveFacePlanes( srfTriangles_t *tri ); // also called by renderbump 1471 void R_CleanupTriangles( srfTriangles_t *tri, bool createNormals, bool identifySilEdges, bool useUnsmoothedTangents ); 1472 void R_ReverseTriangles( srfTriangles_t *tri ); 1473 1474 // Only deals with vertexes and indexes, not silhouettes, planes, etc. 1475 // Does NOT perform a cleanup triangles, so there may be duplicated verts in the result. 1476 srfTriangles_t * R_MergeSurfaceList( const srfTriangles_t **surfaces, int numSurfaces ); 1477 srfTriangles_t * R_MergeTriangles( const srfTriangles_t *tri1, const srfTriangles_t *tri2 ); 1478 1479 // if the deformed verts have significant enough texture coordinate changes to reverse the texture 1480 // polarity of a triangle, the tangents will be incorrect 1481 void R_DeriveTangents( srfTriangles_t *tri, bool allocFacePlanes = true ); 1482 1483 // deformable meshes precalculate as much as possible from a base frame, then generate 1484 // complete srfTriangles_t from just a new set of vertexes 1485 typedef struct deformInfo_s { 1486 int numSourceVerts; 1487 1488 // numOutputVerts may be smaller if the input had duplicated or degenerate triangles 1489 // it will often be larger if the input had mirrored texture seams that needed 1490 // to be busted for proper tangent spaces 1491 int numOutputVerts; 1492 1493 int numMirroredVerts; 1494 int * mirroredVerts; 1495 1496 int numIndexes; 1497 glIndex_t * indexes; 1498 1499 glIndex_t * silIndexes; 1500 1501 int numDupVerts; 1502 int * dupVerts; 1503 1504 int numSilEdges; 1505 silEdge_t * silEdges; 1506 1507 dominantTri_t * dominantTris; 1508 } deformInfo_t; 1509 1510 1511 deformInfo_t * R_BuildDeformInfo( int numVerts, const idDrawVert *verts, int numIndexes, const int *indexes, bool useUnsmoothedTangents ); 1512 void R_FreeDeformInfo( deformInfo_t *deformInfo ); 1513 int R_DeformInfoMemoryUsed( deformInfo_t *deformInfo ); 1514 1515 /* 1516 ============================================================ 1517 1518 SUBVIEW 1519 1520 ============================================================ 1521 */ 1522 1523 bool R_PreciseCullSurface( const drawSurf_t *drawSurf, idBounds &ndcBounds ); 1524 bool R_GenerateSubViews( void ); 1525 1526 /* 1527 ============================================================ 1528 1529 SCENE GENERATION 1530 1531 ============================================================ 1532 */ 1533 1534 void R_InitFrameData( void ); 1535 void R_ShutdownFrameData( void ); 1536 int R_CountFrameData( void ); 1537 void R_ToggleSmpFrame( void ); 1538 void *R_FrameAlloc( int bytes ); 1539 void *R_ClearedFrameAlloc( int bytes ); 1540 void R_FrameFree( void *data ); 1541 1542 void *R_StaticAlloc( int bytes ); // just malloc with error checking 1543 void *R_ClearedStaticAlloc( int bytes ); // with memset 1544 void R_StaticFree( void *data ); 1545 1546 1547 /* 1548 ============================================================= 1549 1550 RENDERER DEBUG TOOLS 1551 1552 ============================================================= 1553 */ 1554 1555 float RB_DrawTextLength( const char *text, float scale, int len ); 1556 void RB_AddDebugText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align, const int lifetime, const bool depthTest ); 1557 void RB_ClearDebugText( int time ); 1558 void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest ); 1559 void RB_ClearDebugLines( int time ); 1560 void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest ); 1561 void RB_ClearDebugPolygons( int time ); 1562 void RB_DrawBounds( const idBounds &bounds ); 1563 void RB_ShowLights( drawSurf_t **drawSurfs, int numDrawSurfs ); 1564 void RB_ShowLightCount( drawSurf_t **drawSurfs, int numDrawSurfs ); 1565 void RB_PolygonClear( void ); 1566 void RB_ScanStencilBuffer( void ); 1567 void RB_ShowDestinationAlpha( void ); 1568 void RB_ShowOverdraw( void ); 1569 void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs ); 1570 void RB_ShutdownDebugTools( void ); 1571 1572 /* 1573 ============================================================= 1574 1575 TR_BACKEND 1576 1577 ============================================================= 1578 */ 1579 1580 void RB_SetDefaultGLState( void ); 1581 void RB_SetGL2D( void ); 1582 1583 void RB_ShowImages( void ); 1584 1585 void RB_ExecuteBackEndCommands( const emptyCommand_t *cmds ); 1586 1587 1588 /* 1589 ============================================================= 1590 1591 TR_GUISURF 1592 1593 ============================================================= 1594 */ 1595 1596 void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] ); 1597 void R_RenderGuiSurf( idUserInterface *gui, drawSurf_t *drawSurf ); 1598 1599 /* 1600 ============================================================= 1601 1602 TR_ORDERINDEXES 1603 1604 ============================================================= 1605 */ 1606 1607 void R_OrderIndexes( int numIndexes, glIndex_t *indexes ); 1608 1609 /* 1610 ============================================================= 1611 1612 TR_DEFORM 1613 1614 ============================================================= 1615 */ 1616 1617 void R_DeformDrawSurf( drawSurf_t *drawSurf ); 1618 1619 /* 1620 ============================================================= 1621 1622 TR_TRACE 1623 1624 ============================================================= 1625 */ 1626 1627 typedef struct { 1628 float fraction; 1629 // only valid if fraction < 1.0 1630 idVec3 point; 1631 idVec3 normal; 1632 int indexes[3]; 1633 } localTrace_t; 1634 1635 localTrace_t R_LocalTrace( const idVec3 &start, const idVec3 &end, const float radius, const srfTriangles_t *tri ); 1636 void RB_ShowTrace( drawSurf_t **drawSurfs, int numDrawSurfs ); 1637 1638 /* 1639 ============================================================= 1640 1641 TR_SHADOWBOUNDS 1642 1643 ============================================================= 1644 */ 1645 idScreenRect R_CalcIntersectionScissor( const idRenderLightLocal * lightDef, 1646 const idRenderEntityLocal * entityDef, 1647 const viewDef_t * viewDef ); 1648 1649 //============================================= 1650 1651 #endif /* !__TR_LOCAL_H__ */ 1652