mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-11-21 20:01:13 +00:00
1366 lines
53 KiB
C++
1366 lines
53 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
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.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __TR_LOCAL_H__
|
|
#define __TR_LOCAL_H__
|
|
|
|
#include "../idlib/precompiled.h"
|
|
|
|
#include "GLState.h"
|
|
#include "ScreenRect.h"
|
|
#include "ImageOpts.h"
|
|
#include "Image.h"
|
|
#include "RenderTexture.h"
|
|
#include "Font.h"
|
|
|
|
// everything that is needed by the backend needs
|
|
// to be double buffered to allow it to run in
|
|
// parallel on a dual cpu machine
|
|
const int SMP_FRAMES = 1;
|
|
|
|
// maximum texture units
|
|
const int MAX_PROG_TEXTURE_PARMS = 16;
|
|
|
|
const int FALLOFF_TEXTURE_SIZE = 64;
|
|
|
|
const float DEFAULT_FOG_DISTANCE = 500.0f;
|
|
|
|
// picky to get the bilerp correct at terminator
|
|
const int FOG_ENTER_SIZE = 64;
|
|
const float FOG_ENTER = (FOG_ENTER_SIZE+1.0f)/(FOG_ENTER_SIZE*2);
|
|
|
|
enum demoCommand_t {
|
|
DC_BAD,
|
|
DC_RENDERVIEW,
|
|
DC_UPDATE_ENTITYDEF,
|
|
DC_DELETE_ENTITYDEF,
|
|
DC_UPDATE_LIGHTDEF,
|
|
DC_DELETE_LIGHTDEF,
|
|
DC_LOADMAP,
|
|
DC_CROP_RENDER,
|
|
DC_UNCROP_RENDER,
|
|
DC_CAPTURE_RENDER,
|
|
DC_END_FRAME,
|
|
DC_DEFINE_MODEL,
|
|
DC_SET_PORTAL_STATE,
|
|
DC_UPDATE_SOUNDOCCLUSION,
|
|
DC_GUI_MODEL
|
|
};
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
SURFACES
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "ModelDecal.h"
|
|
#include "ModelOverlay.h"
|
|
#include "Interaction.h"
|
|
|
|
class idRenderWorldLocal;
|
|
struct viewEntity_t;
|
|
struct viewLight_t;
|
|
|
|
// drawSurf_t structures command the back end to render surfaces
|
|
// a given srfTriangles_t may be used with multiple viewEntity_t,
|
|
// as when viewed in a subview or multiple viewport render, or
|
|
// with multiple shaders when skinned, or, possibly with multiple
|
|
// lights, although currently each lighting interaction creates
|
|
// unique srfTriangles_t
|
|
// drawSurf_t are always allocated and freed every frame, they are never cached
|
|
|
|
struct drawSurf_t {
|
|
const srfTriangles_t * frontEndGeo; // don't use on the back end, it may be updated by the front end!
|
|
int numIndexes;
|
|
vertCacheHandle_t indexCache; // triIndex_t
|
|
vertCacheHandle_t ambientCache; // idDrawVert
|
|
vertCacheHandle_t shadowCache; // idShadowVert / idShadowVertSkinned
|
|
vertCacheHandle_t jointCache; // idJointMat
|
|
const viewEntity_t * space;
|
|
const idMaterial * material; // may be NULL for shadow volumes
|
|
uint64 extraGLState; // Extra GL state |'d with material->stage[].drawStateBits
|
|
float sort; // material->sort, modified by gui / entity sort offsets
|
|
const float * shaderRegisters; // evaluated and adjusted for referenceShaders
|
|
drawSurf_t * nextOnLight; // viewLight chains
|
|
drawSurf_t ** linkChain; // defer linking to lights to a serial section to avoid a mutex
|
|
idScreenRect scissorRect; // for scissor clipping, local inside renderView viewport
|
|
int renderZFail;
|
|
volatile shadowVolumeState_t shadowVolumeState;
|
|
};
|
|
|
|
// areas have references to hold all the lights and entities in them
|
|
struct areaReference_t {
|
|
areaReference_t * areaNext; // chain in the area
|
|
areaReference_t * areaPrev;
|
|
areaReference_t * ownerNext; // chain on either the entityDef or lightDef
|
|
idRenderEntityLocal * entity; // only one of entity / light will be non-NULL
|
|
idRenderLightLocal * light; // only one of entity / light will be non-NULL
|
|
struct portalArea_s * area; // so owners can find all the areas they are in
|
|
};
|
|
|
|
|
|
// idRenderLight should become the new public interface replacing the qhandle_t to light defs in the idRenderWorld interface
|
|
class idRenderLight {
|
|
public:
|
|
virtual ~idRenderLight() {}
|
|
|
|
virtual void FreeRenderLight() = 0;
|
|
virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false ) = 0;
|
|
virtual void GetRenderLight( renderLight_t *re ) = 0;
|
|
virtual void ForceUpdate() = 0;
|
|
virtual int GetIndex() = 0;
|
|
};
|
|
|
|
|
|
// idRenderEntity should become the new public interface replacing the qhandle_t to entity defs in the idRenderWorld interface
|
|
class idRenderEntity {
|
|
public:
|
|
virtual ~idRenderEntity() {}
|
|
|
|
virtual void FreeRenderEntity() = 0;
|
|
virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false ) = 0;
|
|
virtual void GetRenderEntity( renderEntity_t *re ) = 0;
|
|
virtual void ForceUpdate() = 0;
|
|
virtual int GetIndex() = 0;
|
|
|
|
// overlays are extra polygons that deform with animating models for blood and damage marks
|
|
virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material ) = 0;
|
|
virtual void RemoveDecals() = 0;
|
|
};
|
|
|
|
|
|
class idRenderLightLocal : public idRenderLight {
|
|
public:
|
|
idRenderLightLocal();
|
|
|
|
virtual void FreeRenderLight();
|
|
virtual void UpdateRenderLight( const renderLight_t *re, bool forceUpdate = false );
|
|
virtual void GetRenderLight( renderLight_t *re );
|
|
virtual void ForceUpdate();
|
|
virtual int GetIndex();
|
|
|
|
bool LightCastsShadows() const { return parms.forceShadows || ( !parms.noShadows && lightShader->LightCastsShadows() ); }
|
|
|
|
renderLight_t parms; // specification
|
|
|
|
bool lightHasMoved; // the light has changed its position since it was
|
|
// first added, so the prelight model is not valid
|
|
idRenderWorldLocal * world;
|
|
int index; // in world lightdefs
|
|
|
|
int areaNum; // if not -1, we may be able to cull all the light's
|
|
// interactions if !viewDef->connectedAreas[areaNum]
|
|
|
|
int lastModifiedFrameNum; // to determine if it is constantly changing,
|
|
// and should go in the dynamic frame memory, or kept
|
|
// in the cached memory
|
|
bool archived; // for demo writing
|
|
|
|
|
|
// derived information
|
|
idPlane lightProject[4]; // old style light projection where Z and W are flipped and projected lights lightProject[3] is divided by ( zNear + zFar )
|
|
idRenderMatrix baseLightProject; // global xyz1 to projected light strq
|
|
idRenderMatrix inverseBaseLightProject;// transforms the zero-to-one cube to exactly cover the light in world space
|
|
|
|
const idMaterial * lightShader; // guaranteed to be valid, even if parms.shader isn't
|
|
idImage * falloffImage;
|
|
|
|
idVec3 globalLightOrigin; // accounting for lightCenter and parallel
|
|
idBounds globalLightBounds;
|
|
|
|
int viewCount; // if == tr.viewCount, the light is on the viewDef->viewLights list
|
|
viewLight_t * viewLight;
|
|
|
|
areaReference_t * references; // each area the light is present in will have a lightRef
|
|
idInteraction * firstInteraction; // doubly linked list
|
|
idInteraction * lastInteraction;
|
|
|
|
struct doublePortal_s * foggedPortals;
|
|
};
|
|
|
|
|
|
class idRenderEntityLocal : public idRenderEntity {
|
|
public:
|
|
idRenderEntityLocal();
|
|
|
|
virtual void FreeRenderEntity();
|
|
virtual void UpdateRenderEntity( const renderEntity_t *re, bool forceUpdate = false );
|
|
virtual void GetRenderEntity( renderEntity_t *re );
|
|
virtual void ForceUpdate();
|
|
virtual int GetIndex();
|
|
|
|
// overlays are extra polygons that deform with animating models for blood and damage marks
|
|
virtual void ProjectOverlay( const idPlane localTextureAxis[2], const idMaterial *material );
|
|
virtual void RemoveDecals();
|
|
|
|
bool IsDirectlyVisible() const;
|
|
|
|
renderEntity_t parms;
|
|
|
|
float modelMatrix[16]; // this is just a rearrangement of parms.axis and parms.origin
|
|
idRenderMatrix modelRenderMatrix;
|
|
idRenderMatrix inverseBaseModelProject;// transforms the unit cube to exactly cover the model in world space
|
|
|
|
idRenderWorldLocal * world;
|
|
int index; // in world entityDefs
|
|
|
|
int lastModifiedFrameNum; // to determine if it is constantly changing,
|
|
// and should go in the dynamic frame memory, or kept
|
|
// in the cached memory
|
|
bool archived; // for demo writing
|
|
|
|
idRenderModel * dynamicModel; // if parms.model->IsDynamicModel(), this is the generated data
|
|
int dynamicModelFrameCount; // continuously animating dynamic models will recreate
|
|
// dynamicModel if this doesn't == tr.viewCount
|
|
idRenderModel * cachedDynamicModel;
|
|
|
|
|
|
// the local bounds used to place entityRefs, either from parms for dynamic entities, or a model bounds
|
|
idBounds localReferenceBounds;
|
|
|
|
// axis aligned bounding box in world space, derived from refernceBounds and
|
|
// modelMatrix in R_CreateEntityRefs()
|
|
idBounds globalReferenceBounds;
|
|
|
|
// a viewEntity_t is created whenever a idRenderEntityLocal is considered for inclusion
|
|
// in a given view, even if it turns out to not be visible
|
|
int viewCount; // if tr.viewCount == viewCount, viewEntity is valid,
|
|
// but the entity may still be off screen
|
|
viewEntity_t * viewEntity; // in frame temporary memory
|
|
|
|
idRenderModelDecal * decals; // decals that have been projected on this model
|
|
idRenderModelOverlay * overlays; // blood overlays on animated models
|
|
|
|
areaReference_t * entityRefs; // chain of all references
|
|
idInteraction * firstInteraction; // doubly linked list
|
|
idInteraction * lastInteraction;
|
|
|
|
bool needsPortalSky;
|
|
};
|
|
|
|
struct shadowOnlyEntity_t {
|
|
shadowOnlyEntity_t * next;
|
|
idRenderEntityLocal * edef;
|
|
};
|
|
|
|
// viewLights are allocated on the frame temporary stack memory
|
|
// a viewLight contains everything that the back end needs out of an idRenderLightLocal,
|
|
// which the front end may be modifying simultaniously if running in SMP mode.
|
|
// a viewLight may exist even without any surfaces, and may be relevent for fogging,
|
|
// but should never exist if its volume does not intersect the view frustum
|
|
struct viewLight_t {
|
|
viewLight_t * next;
|
|
|
|
// back end should NOT reference the lightDef, because it can change when running SMP
|
|
idRenderLightLocal * lightDef;
|
|
|
|
// for scissor clipping, local inside renderView viewport
|
|
// scissorRect.Empty() is true if the viewEntity_t was never actually
|
|
// seen through any portals
|
|
idScreenRect scissorRect;
|
|
|
|
// R_AddSingleLight() determined that the light isn't actually needed
|
|
bool removeFromList;
|
|
|
|
// R_AddSingleLight builds this list of entities that need to be added
|
|
// to the viewEntities list because they potentially cast shadows into
|
|
// the view, even though the aren't directly visible
|
|
shadowOnlyEntity_t * shadowOnlyViewEntities;
|
|
|
|
enum interactionState_t {
|
|
INTERACTION_UNCHECKED,
|
|
INTERACTION_NO,
|
|
INTERACTION_YES
|
|
};
|
|
byte * entityInteractionState; // [numEntities]
|
|
|
|
idVec3 globalLightOrigin; // global light origin used by backend
|
|
idPlane lightProject[4]; // light project used by backend
|
|
idPlane fogPlane; // fog plane for backend fog volume rendering
|
|
idRenderMatrix inverseBaseLightProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the light volume in world space
|
|
const idMaterial * lightShader; // light shader used by backend
|
|
const float * shaderRegisters; // shader registers used by backend
|
|
idImage * falloffImage; // falloff image used by backend
|
|
|
|
drawSurf_t * globalShadows; // shadow everything
|
|
drawSurf_t * localInteractions; // don't get local shadows
|
|
drawSurf_t * localShadows; // don't shadow local surfaces
|
|
drawSurf_t * globalInteractions; // get shadows from everything
|
|
drawSurf_t * translucentInteractions; // translucent interactions don't get shadows
|
|
|
|
// R_AddSingleLight will build a chain of parameters here to setup shadow volumes
|
|
preLightShadowVolumeParms_t * preLightShadowVolumes;
|
|
};
|
|
|
|
// a viewEntity is created whenever a idRenderEntityLocal is considered for inclusion
|
|
// in the current view, but it may still turn out to be culled.
|
|
// viewEntity are allocated on the frame temporary stack memory
|
|
// a viewEntity contains everything that the back end needs out of a idRenderEntityLocal,
|
|
// which the front end may be modifying simultaneously if running in SMP mode.
|
|
// A single entityDef can generate multiple viewEntity_t in a single frame, as when seen in a mirror
|
|
struct viewEntity_t {
|
|
viewEntity_t * next;
|
|
|
|
// back end should NOT reference the entityDef, because it can change when running SMP
|
|
idRenderEntityLocal * entityDef;
|
|
|
|
// for scissor clipping, local inside renderView viewport
|
|
// scissorRect.Empty() is true if the viewEntity_t was never actually
|
|
// seen through any portals, but was created for shadow casting.
|
|
// a viewEntity can have a non-empty scissorRect, meaning that an area
|
|
// that it is in is visible, and still not be visible.
|
|
idScreenRect scissorRect;
|
|
|
|
bool isGuiSurface; // force two sided and vertex colors regardless of material setting
|
|
|
|
bool skipMotionBlur;
|
|
|
|
bool weaponDepthHack;
|
|
float modelDepthHack;
|
|
|
|
float modelMatrix[16]; // local coords to global coords
|
|
float modelViewMatrix[16]; // local coords to eye coords
|
|
|
|
idRenderMatrix mvp;
|
|
|
|
// parallelAddModels will build a chain of surfaces here that will need to
|
|
// be linked to the lights or added to the drawsurf list in a serial code section
|
|
drawSurf_t * drawSurfs;
|
|
|
|
// R_AddSingleModel will build a chain of parameters here to setup shadow volumes
|
|
staticShadowVolumeParms_t * staticShadowVolumes;
|
|
dynamicShadowVolumeParms_t * dynamicShadowVolumes;
|
|
};
|
|
|
|
|
|
const int MAX_CLIP_PLANES = 1; // we may expand this to six for some subview issues
|
|
|
|
// viewDefs are allocated on the frame temporary stack memory
|
|
struct viewDef_t {
|
|
// specified in the call to DrawScene()
|
|
renderView_t renderView;
|
|
|
|
float projectionMatrix[16];
|
|
idRenderMatrix projectionRenderMatrix; // tech5 version of projectionMatrix
|
|
viewEntity_t worldSpace;
|
|
|
|
idRenderWorldLocal *renderWorld;
|
|
|
|
idVec3 initialViewAreaOrigin;
|
|
// Used to find the portalArea that view flooding will take place from.
|
|
// for a normal view, the initialViewOrigin will be renderView.viewOrg,
|
|
// but a mirror may put the projection origin outside
|
|
// of any valid area, or in an unconnected area of the map, so the view
|
|
// area must be based on a point just off the surface of the mirror / subview.
|
|
// It may be possible to get a failed portal pass if the plane of the
|
|
// mirror intersects a portal, and the initialViewAreaOrigin is on
|
|
// a different side than the renderView.viewOrg is.
|
|
|
|
bool isSubview; // true if this view is not the main view
|
|
bool isMirror; // the portal is a mirror, invert the face culling
|
|
bool isXraySubview;
|
|
|
|
bool isEditor;
|
|
bool is2Dgui;
|
|
|
|
int numClipPlanes; // mirrors will often use a single clip plane
|
|
idPlane clipPlanes[MAX_CLIP_PLANES]; // in world space, the positive side
|
|
// of the plane is the visible side
|
|
idScreenRect viewport; // in real pixels and proper Y flip
|
|
|
|
idScreenRect scissor;
|
|
// for scissor clipping, local inside renderView viewport
|
|
// subviews may only be rendering part of the main view
|
|
// these are real physical pixel values, possibly scaled and offset from the
|
|
// renderView x/y/width/height
|
|
|
|
viewDef_t * superView; // never go into an infinite subview loop
|
|
const drawSurf_t * subviewSurface;
|
|
|
|
// drawSurfs are the visible surfaces of the viewEntities, sorted
|
|
// by the material sort parameter
|
|
drawSurf_t ** drawSurfs; // we don't use an idList for this, because
|
|
int numDrawSurfs; // it is allocated in frame temporary memory
|
|
int maxDrawSurfs; // may be resized
|
|
|
|
viewLight_t * viewLights; // chain of all viewLights effecting view
|
|
viewEntity_t * viewEntitys; // chain of all viewEntities effecting view, including off screen ones casting shadows
|
|
// we use viewEntities as a check to see if a given view consists solely
|
|
// of 2D rendering, which we can optimize in certain ways. A 2D view will
|
|
// not have any viewEntities
|
|
|
|
idPlane frustum[6]; // positive sides face outward, [4] is the front clip plane
|
|
|
|
int areaNum; // -1 = not in a valid area
|
|
|
|
// An array in frame temporary memory that lists if an area can be reached without
|
|
// crossing a closed door. This is used to avoid drawing interactions
|
|
// when the light is behind a closed door.
|
|
bool * connectedAreas;
|
|
};
|
|
|
|
|
|
// complex light / surface interactions are broken up into multiple passes of a
|
|
// simple interaction shader
|
|
struct drawInteraction_t {
|
|
const drawSurf_t * surf;
|
|
|
|
idImage * bumpImage;
|
|
idImage * diffuseImage;
|
|
idImage * specularImage;
|
|
|
|
idVec4 diffuseColor; // may have a light color baked into it
|
|
idVec4 specularColor; // may have a light color baked into it
|
|
stageVertexColor_t vertexColor; // applies to both diffuse and specular
|
|
|
|
int ambientLight; // use tr.ambientNormalMap instead of normalization cube map
|
|
|
|
// these are loaded into the vertex program
|
|
idVec4 bumpMatrix[2];
|
|
idVec4 diffuseMatrix[2];
|
|
idVec4 specularMatrix[2];
|
|
};
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
RENDERER BACK END COMMAND QUEUE
|
|
|
|
TR_CMDS
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
enum renderCommand_t {
|
|
RC_NOP,
|
|
RC_DRAW_VIEW_3D, // may be at a reduced resolution, will be upsampled before 2D GUIs
|
|
RC_DRAW_VIEW_GUI, // not resolution scaled
|
|
RC_SET_BUFFER,
|
|
RC_COPY_RENDER,
|
|
RC_POST_PROCESS,
|
|
};
|
|
|
|
struct emptyCommand_t {
|
|
renderCommand_t commandId;
|
|
renderCommand_t * next;
|
|
};
|
|
|
|
struct setBufferCommand_t {
|
|
renderCommand_t commandId;
|
|
renderCommand_t * next;
|
|
GLenum buffer;
|
|
};
|
|
|
|
struct drawSurfsCommand_t {
|
|
renderCommand_t commandId;
|
|
renderCommand_t * next;
|
|
viewDef_t * viewDef;
|
|
};
|
|
|
|
struct copyRenderCommand_t {
|
|
renderCommand_t commandId;
|
|
renderCommand_t * next;
|
|
int x;
|
|
int y;
|
|
int imageWidth;
|
|
int imageHeight;
|
|
idImage * image;
|
|
int cubeFace; // when copying to a cubeMap
|
|
bool clearColorAfterCopy;
|
|
};
|
|
|
|
struct postProcessCommand_t {
|
|
renderCommand_t commandId;
|
|
renderCommand_t * next;
|
|
viewDef_t * viewDef;
|
|
};
|
|
|
|
//=======================================================================
|
|
|
|
// this is the inital allocation for max number of drawsurfs
|
|
// in a given view, but it will automatically grow if needed
|
|
const int INITIAL_DRAWSURFS = 2048;
|
|
|
|
enum frameAllocType_t {
|
|
FRAME_ALLOC_VIEW_DEF,
|
|
FRAME_ALLOC_VIEW_ENTITY,
|
|
FRAME_ALLOC_VIEW_LIGHT,
|
|
FRAME_ALLOC_SURFACE_TRIANGLES,
|
|
FRAME_ALLOC_DRAW_SURFACE,
|
|
FRAME_ALLOC_INTERACTION_STATE,
|
|
FRAME_ALLOC_SHADOW_ONLY_ENTITY,
|
|
FRAME_ALLOC_SHADOW_VOLUME_PARMS,
|
|
FRAME_ALLOC_SHADER_REGISTER,
|
|
FRAME_ALLOC_DRAW_SURFACE_POINTER,
|
|
FRAME_ALLOC_DRAW_COMMAND,
|
|
FRAME_ALLOC_UNKNOWN,
|
|
FRAME_ALLOC_MAX
|
|
};
|
|
|
|
// all of the information needed by the back end must be
|
|
// contained in a idFrameData. This entire structure is
|
|
// duplicated so the front and back end can run in parallel
|
|
// on an SMP machine.
|
|
class idFrameData {
|
|
public:
|
|
idSysInterlockedInteger frameMemoryAllocated;
|
|
idSysInterlockedInteger frameMemoryUsed;
|
|
byte * frameMemory;
|
|
|
|
int highWaterAllocated; // max used on any frame
|
|
int highWaterUsed;
|
|
|
|
// the currently building command list commands can be inserted
|
|
// at the front if needed, as required for dynamically generated textures
|
|
emptyCommand_t * cmdHead; // may be of other command type based on commandId
|
|
emptyCommand_t * cmdTail;
|
|
};
|
|
|
|
extern idFrameData *frameData;
|
|
|
|
//=======================================================================
|
|
|
|
void R_AddDrawViewCmd( viewDef_t *parms, bool guiOnly );
|
|
void R_AddDrawPostProcess( viewDef_t *parms );
|
|
|
|
void R_ReloadGuis_f( const idCmdArgs &args );
|
|
void R_ListGuis_f( const idCmdArgs &args );
|
|
|
|
void *R_GetCommandBuffer( int bytes );
|
|
|
|
// this allows a global override of all materials
|
|
bool R_GlobalShaderOverride( const idMaterial **shader );
|
|
|
|
// this does various checks before calling the idDeclSkin
|
|
const idMaterial *R_RemapShaderBySkin( const idMaterial *shader, const idDeclSkin *customSkin, const idMaterial *customShader );
|
|
|
|
|
|
//====================================================
|
|
|
|
|
|
/*
|
|
** performanceCounters_t
|
|
*/
|
|
struct performanceCounters_t {
|
|
int c_box_cull_in;
|
|
int c_box_cull_out;
|
|
int c_createInteractions; // number of calls to idInteraction::CreateInteraction
|
|
int c_createShadowVolumes;
|
|
int c_generateMd5;
|
|
int c_entityDefCallbacks;
|
|
int c_alloc; // counts for R_StaticAllc/R_StaticFree
|
|
int c_free;
|
|
int c_visibleViewEntities;
|
|
int c_shadowViewEntities;
|
|
int c_viewLights;
|
|
int c_numViews; // number of total views rendered
|
|
int c_deformedSurfaces; // idMD5Mesh::GenerateSurface
|
|
int c_deformedVerts; // idMD5Mesh::GenerateSurface
|
|
int c_deformedIndexes; // idMD5Mesh::GenerateSurface
|
|
int c_tangentIndexes; // R_DeriveTangents()
|
|
int c_entityUpdates;
|
|
int c_lightUpdates;
|
|
int c_entityReferences;
|
|
int c_lightReferences;
|
|
int c_guiSurfs;
|
|
int frontEndMicroSec; // sum of time in all RE_RenderScene's in a frame
|
|
};
|
|
|
|
|
|
struct tmu_t {
|
|
unsigned int current2DMap;
|
|
unsigned int currentCubeMap;
|
|
};
|
|
|
|
|
|
const int MAX_MULTITEXTURE_UNITS = 8;
|
|
|
|
enum vertexLayoutType_t {
|
|
LAYOUT_UNKNOWN = 0,
|
|
LAYOUT_DRAW_VERT,
|
|
LAYOUT_DRAW_SHADOW_VERT,
|
|
LAYOUT_DRAW_SHADOW_VERT_SKINNED
|
|
};
|
|
|
|
struct glstate_t {
|
|
tmu_t tmu[MAX_MULTITEXTURE_UNITS];
|
|
|
|
int currenttmu;
|
|
|
|
int faceCulling;
|
|
|
|
vertexLayoutType_t vertexLayout;
|
|
unsigned int currentVertexBuffer;
|
|
unsigned int currentIndexBuffer;
|
|
|
|
float polyOfsScale;
|
|
float polyOfsBias;
|
|
|
|
uint64 glStateBits;
|
|
};
|
|
|
|
struct backEndCounters_t {
|
|
int c_surfaces;
|
|
int c_shaders;
|
|
|
|
int c_drawElements;
|
|
int c_drawIndexes;
|
|
|
|
int c_shadowElements;
|
|
int c_shadowIndexes;
|
|
|
|
int c_copyFrameBuffer;
|
|
|
|
float c_overDraw;
|
|
|
|
int totalMicroSec; // total microseconds for backend run
|
|
int shadowMicroSec;
|
|
};
|
|
|
|
// all state modified by the back end is separated
|
|
// from the front end state
|
|
struct backEndState_t {
|
|
const viewDef_t * viewDef;
|
|
backEndCounters_t pc;
|
|
|
|
const viewEntity_t *currentSpace; // for detecting when a matrix must change
|
|
idScreenRect currentScissor; // for scissor clipping, local inside renderView viewport
|
|
glstate_t glState; // for OpenGL state deltas
|
|
|
|
bool currentRenderCopied; // true if any material has already referenced _currentRender
|
|
|
|
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur, per-eye
|
|
|
|
// surfaces used for code-based drawing
|
|
drawSurf_t unitSquareSurface;
|
|
drawSurf_t zeroOneCubeSurface;
|
|
drawSurf_t testImageSurface;
|
|
};
|
|
|
|
class idParallelJobList;
|
|
|
|
const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for guis, will
|
|
// be automatically expanded as needed
|
|
|
|
static const int MAX_RENDER_CROPS = 8;
|
|
|
|
/*
|
|
** Most renderer globals are defined here.
|
|
** backend functions should never modify any of these fields,
|
|
** but may read fields that aren't dynamically modified
|
|
** by the frontend.
|
|
*/
|
|
class idRenderSystemLocal : public idRenderSystem {
|
|
public:
|
|
// external functions
|
|
virtual void Init();
|
|
virtual void Shutdown();
|
|
virtual void ResetGuiModels();
|
|
virtual void InitOpenGL();
|
|
virtual void ShutdownOpenGL();
|
|
virtual bool IsOpenGLRunning() const;
|
|
virtual bool IsFullScreen() const;
|
|
virtual stereo3DMode_t GetStereo3DMode() const;
|
|
virtual bool HasQuadBufferSupport() const;
|
|
virtual bool IsStereoScopicRenderingSupported() const;
|
|
virtual stereo3DMode_t GetStereoScopicRenderingMode() const;
|
|
virtual void EnableStereoScopicRendering( const stereo3DMode_t mode ) const;
|
|
virtual int GetWidth() const;
|
|
virtual int GetHeight() const;
|
|
virtual float GetPixelAspect() const;
|
|
virtual float GetPhysicalScreenWidthInCentimeters() const;
|
|
virtual idRenderWorld * AllocRenderWorld();
|
|
virtual void FreeRenderWorld( idRenderWorld *rw );
|
|
virtual void BeginLevelLoad();
|
|
virtual void EndLevelLoad();
|
|
virtual void LoadLevelImages();
|
|
virtual void Preload( const idPreloadManifest &manifest, const char *mapName );
|
|
virtual void BeginAutomaticBackgroundSwaps( autoRenderIconType_t icon = AUTORENDER_DEFAULTICON );
|
|
virtual void EndAutomaticBackgroundSwaps();
|
|
virtual bool AreAutomaticBackgroundSwapsRunning( autoRenderIconType_t * usingAlternateIcon = NULL ) const;
|
|
|
|
virtual idFont * RegisterFont( const char * fontName );
|
|
virtual void ResetFonts();
|
|
virtual void PrintMemInfo( MemInfo_t *mi );
|
|
|
|
virtual void SetColor( const idVec4 & color );
|
|
virtual uint32 GetColor();
|
|
virtual void SetGLState( const uint64 glState ) ;
|
|
virtual void DrawFilled( const idVec4 & color, float x, float y, float w, float h );
|
|
virtual void DrawStretchPic ( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material );
|
|
virtual void DrawStretchPic( const idVec4 & topLeft, const idVec4 & topRight, const idVec4 & bottomRight, const idVec4 & bottomLeft, const idMaterial * material );
|
|
virtual void DrawStretchTri ( const idVec2 & p1, const idVec2 & p2, const idVec2 & p3, const idVec2 & t1, const idVec2 & t2, const idVec2 & t3, const idMaterial *material );
|
|
virtual idDrawVert * AllocTris( int numVerts, const triIndex_t * indexes, int numIndexes, const idMaterial * material, const stereoDepthType_t stereoType = STEREO_DEPTH_TYPE_NONE );
|
|
virtual void DrawSmallChar( int x, int y, int ch );
|
|
virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor );
|
|
virtual void DrawBigChar( int x, int y, int ch );
|
|
virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor );
|
|
|
|
virtual void WriteDemoPics();
|
|
virtual void DrawDemoPics();
|
|
virtual const emptyCommand_t * SwapCommandBuffers( uint64 *frontEndMicroSec, uint64 *backEndMicroSec, uint64 *shadowMicroSec, uint64 *gpuMicroSec );
|
|
|
|
virtual void SwapCommandBuffers_FinishRendering( uint64 *frontEndMicroSec, uint64 *backEndMicroSec, uint64 *shadowMicroSec, uint64 *gpuMicroSec );
|
|
virtual const emptyCommand_t * SwapCommandBuffers_FinishCommandBuffers();
|
|
|
|
virtual void RenderCommandBuffers( const emptyCommand_t * commandBuffers );
|
|
virtual void TakeScreenshot( int width, int height, const char *fileName, int downSample, renderView_t *ref );
|
|
virtual void CropRenderSize( int width, int height );
|
|
virtual void CaptureRenderToImage( const char *imageName, bool clearColorAfterCopy = false );
|
|
virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha );
|
|
virtual void UnCrop();
|
|
virtual bool UploadImage( const char *imageName, const byte *data, int width, int height );
|
|
|
|
|
|
|
|
public:
|
|
// internal functions
|
|
idRenderSystemLocal();
|
|
~idRenderSystemLocal();
|
|
|
|
void Clear();
|
|
void GetCroppedViewport( idScreenRect * viewport );
|
|
void PerformResolutionScaling( int& newWidth, int& newHeight );
|
|
int GetFrameCount() const { return frameCount; };
|
|
|
|
public:
|
|
// renderer globals
|
|
bool registered; // cleared at shutdown, set at InitOpenGL
|
|
|
|
bool takingScreenshot;
|
|
|
|
int frameCount; // incremented every frame
|
|
int viewCount; // incremented every view (twice a scene if subviewed)
|
|
// and every R_MarkFragments call
|
|
|
|
float frameShaderTime; // shader time for all non-world 2D rendering
|
|
|
|
idVec4 ambientLightVector; // used for "ambient bump mapping"
|
|
|
|
idList<idRenderWorldLocal*>worlds;
|
|
|
|
idRenderWorldLocal * primaryWorld;
|
|
renderView_t primaryRenderView;
|
|
viewDef_t * primaryView;
|
|
// many console commands need to know which world they should operate on
|
|
|
|
const idMaterial * whiteMaterial;
|
|
const idMaterial * charSetMaterial;
|
|
const idMaterial * defaultPointLight;
|
|
const idMaterial * defaultProjectedLight;
|
|
const idMaterial * defaultMaterial;
|
|
idImage * testImage;
|
|
idCinematic * testVideo;
|
|
int testVideoStartTime;
|
|
|
|
idImage * ambientCubeImage; // hack for testing dependent ambient lighting
|
|
|
|
viewDef_t * viewDef;
|
|
|
|
performanceCounters_t pc; // performance counters
|
|
|
|
viewEntity_t identitySpace; // can use if we don't know viewDef->worldSpace is valid
|
|
|
|
idScreenRect renderCrops[MAX_RENDER_CROPS];
|
|
int currentRenderCrop;
|
|
|
|
// GUI drawing variables for surface creation
|
|
int guiRecursionLevel; // to prevent infinite overruns
|
|
uint32 currentColorNativeBytesOrder;
|
|
uint64 currentGLState;
|
|
class idGuiModel * guiModel;
|
|
|
|
idList<idFont *, TAG_FONT> fonts;
|
|
|
|
unsigned short gammaTable[256]; // brightness / gamma modify this
|
|
|
|
srfTriangles_t * unitSquareTriangles;
|
|
srfTriangles_t * zeroOneCubeTriangles;
|
|
srfTriangles_t * testImageTriangles;
|
|
|
|
// these are allocated at buffer swap time, but
|
|
// the back end should only use the ones in the backEnd stucture,
|
|
// which are copied over from the frame that was just swapped.
|
|
drawSurf_t unitSquareSurface_;
|
|
drawSurf_t zeroOneCubeSurface_;
|
|
drawSurf_t testImageSurface_;
|
|
|
|
idParallelJobList * frontEndJobList;
|
|
|
|
unsigned timerQueryId; // for GL_TIME_ELAPSED_EXT queries
|
|
};
|
|
|
|
extern backEndState_t backEnd;
|
|
extern idRenderSystemLocal tr;
|
|
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
|
|
|
|
//
|
|
// cvars
|
|
//
|
|
extern idCVar r_debugContext; // enable various levels of context debug
|
|
extern idCVar r_glDriver; // "opengl32", etc
|
|
extern idCVar r_skipIntelWorkarounds; // skip work arounds for Intel driver bugs
|
|
extern idCVar r_vidMode; // video mode number
|
|
extern idCVar r_displayRefresh; // optional display refresh rate option for vid mode
|
|
extern idCVar r_fullscreen; // 0 = windowed, 1 = full screen
|
|
extern idCVar r_multiSamples; // number of antialiasing samples
|
|
|
|
extern idCVar r_znear; // near Z clip plane
|
|
|
|
extern idCVar r_swapInterval; // changes wglSwapIntarval
|
|
extern idCVar r_offsetFactor; // polygon offset parameter
|
|
extern idCVar r_offsetUnits; // polygon offset parameter
|
|
extern idCVar r_singleTriangle; // only draw a single triangle per primitive
|
|
extern idCVar r_logFile; // number of frames to emit GL logs
|
|
extern idCVar r_clear; // force screen clear every frame
|
|
extern idCVar r_subviewOnly; // 1 = don't render main view, allowing subviews to be debugged
|
|
extern idCVar r_lightScale; // all light intensities are multiplied by this, which is normally 2
|
|
extern idCVar r_flareSize; // scale the flare deforms from the material def
|
|
|
|
extern idCVar r_gamma; // changes gamma tables
|
|
extern idCVar r_brightness; // changes gamma tables
|
|
|
|
extern idCVar r_checkBounds; // compare all surface bounds with precalculated ones
|
|
extern idCVar r_maxAnisotropicFiltering; // texture filtering parameter
|
|
extern idCVar r_useTrilinearFiltering; // Extra quality filtering
|
|
extern idCVar r_lodBias; // lod bias
|
|
|
|
extern idCVar r_useLightPortalFlow; // 1 = do a more precise area reference determination
|
|
extern idCVar r_useShadowSurfaceScissor; // 1 = scissor shadows by the scissor rect of the interaction surfaces
|
|
extern idCVar r_useConstantMaterials; // 1 = use pre-calculated material registers if possible
|
|
extern idCVar r_useNodeCommonChildren; // stop pushing reference bounds early when possible
|
|
extern idCVar r_useSilRemap; // 1 = consider verts with the same XYZ, but different ST the same for shadows
|
|
extern idCVar r_useLightPortalCulling; // 0 = none, 1 = box, 2 = exact clip of polyhedron faces, 3 MVP to plane culling
|
|
extern idCVar r_useLightAreaCulling; // 0 = off, 1 = on
|
|
extern idCVar r_useLightScissors; // 1 = use custom scissor rectangle for each light
|
|
extern idCVar r_useEntityPortalCulling; // 0 = none, 1 = box
|
|
extern idCVar r_skipPrelightShadows; // 1 = skip the dmap generated static shadow volumes
|
|
extern idCVar r_useCachedDynamicModels; // 1 = cache snapshots of dynamic models
|
|
extern idCVar r_useScissor; // 1 = scissor clip as portals and lights are processed
|
|
extern idCVar r_usePortals; // 1 = use portals to perform area culling, otherwise draw everything
|
|
extern idCVar r_useStateCaching; // avoid redundant state changes in GL_*() calls
|
|
extern idCVar r_useEntityCallbacks; // if 0, issue the callback immediately at update time, rather than defering
|
|
extern idCVar r_lightAllBackFaces; // light all the back faces, even when they would be shadowed
|
|
extern idCVar r_useLightDepthBounds; // use depth bounds test on lights to reduce both shadow and interaction fill
|
|
extern idCVar r_useShadowDepthBounds; // use depth bounds test on individual shadows to reduce shadow fill
|
|
|
|
extern idCVar r_skipStaticInteractions; // skip interactions created at level load
|
|
extern idCVar r_skipDynamicInteractions; // skip interactions created after level load
|
|
extern idCVar r_skipPostProcess; // skip all post-process renderings
|
|
extern idCVar r_skipSuppress; // ignore the per-view suppressions
|
|
extern idCVar r_skipInteractions; // skip all light/surface interaction drawing
|
|
extern idCVar r_skipFrontEnd; // bypasses all front end work, but 2D gui rendering still draws
|
|
extern idCVar r_skipBackEnd; // don't draw anything
|
|
extern idCVar r_skipCopyTexture; // do all rendering, but don't actually copyTexSubImage2D
|
|
extern idCVar r_skipRender; // skip 3D rendering, but pass 2D
|
|
extern idCVar r_skipRenderContext; // NULL the rendering context during backend 3D rendering
|
|
extern idCVar r_skipTranslucent; // skip the translucent interaction rendering
|
|
extern idCVar r_skipAmbient; // bypasses all non-interaction drawing
|
|
extern idCVar r_skipNewAmbient; // bypasses all vertex/fragment program ambients
|
|
extern idCVar r_skipBlendLights; // skip all blend lights
|
|
extern idCVar r_skipFogLights; // skip all fog lights
|
|
extern idCVar r_skipSubviews; // 1 = don't render any mirrors / cameras / etc
|
|
extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
|
|
extern idCVar r_skipParticles; // 1 = don't render any particles
|
|
extern idCVar r_skipUpdates; // 1 = don't accept any entity or light updates, making everything static
|
|
extern idCVar r_skipDeforms; // leave all deform materials in their original state
|
|
extern idCVar r_skipDynamicTextures; // don't dynamically create textures
|
|
extern idCVar r_skipBump; // uses a flat surface instead of the bump map
|
|
extern idCVar r_skipSpecular; // use black for specular
|
|
extern idCVar r_skipDiffuse; // use black for diffuse
|
|
extern idCVar r_skipDecals; // skip decal surfaces
|
|
extern idCVar r_skipOverlays; // skip overlay surfaces
|
|
extern idCVar r_skipShadows; // disable shadows
|
|
|
|
extern idCVar r_ignoreGLErrors;
|
|
|
|
extern idCVar r_screenFraction; // for testing fill rate, the resolution of the entire screen can be changed
|
|
extern idCVar r_showUnsmoothedTangents; // highlight geometry rendered with unsmoothed tangents
|
|
extern idCVar r_showSilhouette; // highlight edges that are casting shadow planes
|
|
extern idCVar r_showVertexColor; // draws all triangles with the solid vertex color
|
|
extern idCVar r_showUpdates; // report entity and light updates and ref counts
|
|
extern idCVar r_showDemo; // report reads and writes to the demo file
|
|
extern idCVar r_showDynamic; // report stats on dynamic surface generation
|
|
extern idCVar r_showIntensity; // draw the screen colors based on intensity, red = 0, green = 128, blue = 255
|
|
extern idCVar r_showTrace; // show the intersection of an eye trace with the world
|
|
extern idCVar r_showDepth; // display the contents of the depth buffer and the depth range
|
|
extern idCVar r_showTris; // enables wireframe rendering of the world
|
|
extern idCVar r_showSurfaceInfo; // show surface material name under crosshair
|
|
extern idCVar r_showNormals; // draws wireframe normals
|
|
extern idCVar r_showEdges; // draw the sil edges
|
|
extern idCVar r_showViewEntitys; // displays the bounding boxes of all view models and optionally the index
|
|
extern idCVar r_showTexturePolarity; // shade triangles by texture area polarity
|
|
extern idCVar r_showTangentSpace; // shade triangles by tangent space
|
|
extern idCVar r_showDominantTri; // draw lines from vertexes to center of dominant triangles
|
|
extern idCVar r_showTextureVectors; // draw each triangles texture (tangent) vectors
|
|
extern idCVar r_showLights; // 1 = print light info, 2 = also draw volumes
|
|
extern idCVar r_showLightCount; // colors surfaces based on light count
|
|
extern idCVar r_showShadows; // visualize the stencil shadow volumes
|
|
extern idCVar r_showLightScissors; // show light scissor rectangles
|
|
extern idCVar r_showMemory; // print frame memory utilization
|
|
extern idCVar r_showCull; // report sphere and box culling stats
|
|
extern idCVar r_showAddModel; // report stats from tr_addModel
|
|
extern idCVar r_showSurfaces; // report surface/light/shadow counts
|
|
extern idCVar r_showPrimitives; // report vertex/index/draw counts
|
|
extern idCVar r_showPortals; // draw portal outlines in color based on passed / not passed
|
|
extern idCVar r_showSkel; // draw the skeleton when model animates
|
|
extern idCVar r_showOverDraw; // show overdraw
|
|
extern idCVar r_jointNameScale; // size of joint names when r_showskel is set to 1
|
|
extern idCVar r_jointNameOffset; // offset of joint names when r_showskel is set to 1
|
|
|
|
extern idCVar r_testGamma; // draw a grid pattern to test gamma levels
|
|
extern idCVar r_testGammaBias; // draw a grid pattern to test gamma levels
|
|
|
|
extern idCVar r_singleLight; // suppress all but one light
|
|
extern idCVar r_singleEntity; // suppress all but one entity
|
|
extern idCVar r_singleArea; // only draw the portal area the view is actually in
|
|
extern idCVar r_singleSurface; // suppress all but one surface on each entity
|
|
extern idCVar r_shadowPolygonOffset; // bias value added to depth test for stencil shadow drawing
|
|
extern idCVar r_shadowPolygonFactor; // scale value for stencil shadow drawing
|
|
|
|
extern idCVar r_jitter; // randomly subpixel jitter the projection matrix
|
|
extern idCVar r_orderIndexes; // perform index reorganization to optimize vertex use
|
|
|
|
extern idCVar r_debugLineDepthTest; // perform depth test on debug lines
|
|
extern idCVar r_debugLineWidth; // width of debug lines
|
|
extern idCVar r_debugArrowStep; // step size of arrow cone line rotation in degrees
|
|
extern idCVar r_debugPolygonFilled;
|
|
|
|
extern idCVar r_materialOverride; // override all materials
|
|
|
|
extern idCVar r_debugRenderToTexture;
|
|
|
|
extern idCVar stereoRender_deGhost; // subtract from opposite eye to reduce ghosting
|
|
|
|
extern idCVar r_useGPUSkinning;
|
|
|
|
/*
|
|
====================================================================
|
|
|
|
INITIALIZATION
|
|
|
|
====================================================================
|
|
*/
|
|
|
|
void R_Init();
|
|
void R_InitOpenGL();
|
|
|
|
void R_SetColorMappings();
|
|
|
|
void R_ScreenShot_f( const idCmdArgs &args );
|
|
void R_StencilShot();
|
|
|
|
/*
|
|
====================================================================
|
|
|
|
IMPLEMENTATION SPECIFIC FUNCTIONS
|
|
|
|
====================================================================
|
|
*/
|
|
|
|
struct vidMode_t {
|
|
int width;
|
|
int height;
|
|
int displayHz;
|
|
|
|
bool operator==( const vidMode_t & a ) {
|
|
return a.width == width && a.height == height && a.displayHz == displayHz;
|
|
}
|
|
};
|
|
|
|
// the number of displays can be found by itterating this until it returns false
|
|
// displayNum is the 0 based value passed to EnumDisplayDevices(), you must add
|
|
// 1 to this to get an r_fullScreen value.
|
|
bool R_GetModeListForDisplay( const int displayNum, idList<vidMode_t> & modeList );
|
|
|
|
struct glimpParms_t {
|
|
int x; // ignored in fullscreen
|
|
int y; // ignored in fullscreen
|
|
int width;
|
|
int height;
|
|
int fullScreen; // 0 = windowed, otherwise 1 based monitor number to go full screen on
|
|
// -1 = borderless window for spanning multiple displays
|
|
bool stereo;
|
|
int displayHz;
|
|
int multiSamples;
|
|
};
|
|
|
|
bool GLimp_Init( glimpParms_t parms );
|
|
// If the desired mode can't be set satisfactorily, false will be returned.
|
|
// If succesful, sets glConfig.nativeScreenWidth, glConfig.nativeScreenHeight, and glConfig.pixelAspect
|
|
|
|
// The renderer will then reset the glimpParms to "safe mode" of 640x480
|
|
// fullscreen and try again. If that also fails, the error will be fatal.
|
|
|
|
bool GLimp_SetScreenParms( glimpParms_t parms );
|
|
// will set up gl up with the new parms
|
|
|
|
void GLimp_Shutdown();
|
|
// Destroys the rendering context, closes the window, resets the resolution,
|
|
// and resets the gamma ramps.
|
|
|
|
void GLimp_SetGamma( unsigned short red[256],
|
|
unsigned short green[256],
|
|
unsigned short blue[256] );
|
|
// Sets the hardware gamma ramps for gamma and brightness adjustment.
|
|
// These are now taken as 16 bit values, so we can take full advantage
|
|
// of dacs with >8 bits of precision
|
|
|
|
|
|
bool GLimp_SpawnRenderThread( void (*function)() );
|
|
// Returns false if the system only has a single processor
|
|
|
|
void * GLimp_BackEndSleep();
|
|
void GLimp_FrontEndSleep();
|
|
void GLimp_WakeBackEnd( void *data );
|
|
// these functions implement the dual processor syncronization
|
|
|
|
void GLimp_ActivateContext();
|
|
void GLimp_DeactivateContext();
|
|
// These are used for managing SMP handoffs of the OpenGL context
|
|
// between threads, and as a performance tunining aid. Setting
|
|
// 'r_skipRenderContext 1' will call GLimp_DeactivateContext() before
|
|
// the 3D rendering code, and GLimp_ActivateContext() afterwards. On
|
|
// most OpenGL implementations, this will result in all OpenGL calls
|
|
// being immediate returns, which lets us guage how much time is
|
|
// being spent inside OpenGL.
|
|
|
|
void GLimp_EnableLogging( bool enable );
|
|
|
|
|
|
/*
|
|
============================================================
|
|
|
|
RENDERWORLD_DEFS
|
|
|
|
============================================================
|
|
*/
|
|
|
|
void R_DeriveEntityData( idRenderEntityLocal *def );
|
|
void R_CreateEntityRefs( idRenderEntityLocal *def );
|
|
void R_FreeEntityDefDerivedData( idRenderEntityLocal *def, bool keepDecals, bool keepCachedDynamicModel );
|
|
void R_FreeEntityDefCachedDynamicModel( idRenderEntityLocal *def );
|
|
void R_FreeEntityDefDecals( idRenderEntityLocal *def );
|
|
void R_FreeEntityDefOverlay( idRenderEntityLocal *def );
|
|
void R_FreeEntityDefFadedDecals( idRenderEntityLocal *def, int time );
|
|
|
|
void R_CreateLightRefs( idRenderLightLocal *light );
|
|
void R_FreeLightDefDerivedData( idRenderLightLocal *light );
|
|
|
|
void R_FreeDerivedData();
|
|
void R_ReCreateWorldReferences();
|
|
void R_CheckForEntityDefsUsingModel( idRenderModel *model );
|
|
void R_ModulateLights_f( const idCmdArgs &args );
|
|
|
|
/*
|
|
============================================================
|
|
|
|
RENDERWORLD_PORTALS
|
|
|
|
============================================================
|
|
*/
|
|
|
|
viewEntity_t *R_SetEntityDefViewEntity( idRenderEntityLocal *def );
|
|
viewLight_t *R_SetLightDefViewLight( idRenderLightLocal *def );
|
|
|
|
/*
|
|
====================================================================
|
|
|
|
TR_FRONTEND_MAIN
|
|
|
|
====================================================================
|
|
*/
|
|
|
|
void R_InitFrameData();
|
|
void R_ShutdownFrameData();
|
|
void R_ToggleSmpFrame();
|
|
void *R_FrameAlloc( int bytes, frameAllocType_t type = FRAME_ALLOC_UNKNOWN );
|
|
void *R_ClearedFrameAlloc( int bytes, frameAllocType_t type = FRAME_ALLOC_UNKNOWN );
|
|
|
|
void *R_StaticAlloc( int bytes, const memTag_t tag = TAG_RENDER_STATIC ); // just malloc with error checking
|
|
void *R_ClearedStaticAlloc( int bytes ); // with memset
|
|
void R_StaticFree( void *data );
|
|
|
|
void R_RenderView( viewDef_t *parms );
|
|
void R_RenderPostProcess( viewDef_t *parms );
|
|
|
|
/*
|
|
============================================================
|
|
|
|
TR_FRONTEND_ADDLIGHTS
|
|
|
|
============================================================
|
|
*/
|
|
|
|
void R_ShadowBounds( const idBounds & modelBounds, const idBounds & lightBounds, const idVec3 & lightOrigin, idBounds & shadowBounds );
|
|
|
|
ID_INLINE bool R_CullModelBoundsToLight( const idRenderLightLocal * light, const idBounds & localBounds, const idRenderMatrix & modelRenderMatrix ) {
|
|
idRenderMatrix modelLightProject;
|
|
idRenderMatrix::Multiply( light->baseLightProject, modelRenderMatrix, modelLightProject );
|
|
return idRenderMatrix::CullBoundsToMVP( modelLightProject, localBounds, true );
|
|
}
|
|
|
|
void R_AddLights();
|
|
void R_OptimizeViewLightsList();
|
|
|
|
/*
|
|
============================================================
|
|
|
|
TR_FRONTEND_ADDMODELS
|
|
|
|
============================================================
|
|
*/
|
|
|
|
bool R_IssueEntityDefCallback( idRenderEntityLocal *def );
|
|
idRenderModel *R_EntityDefDynamicModel( idRenderEntityLocal *def );
|
|
void R_ClearEntityDefDynamicModel( idRenderEntityLocal *def );
|
|
|
|
void R_SetupDrawSurfShader( drawSurf_t * drawSurf, const idMaterial * shader, const renderEntity_t * renderEntity );
|
|
void R_SetupDrawSurfJoints( drawSurf_t * drawSurf, const srfTriangles_t * tri, const idMaterial * shader );
|
|
void R_LinkDrawSurfToView( drawSurf_t * drawSurf, viewDef_t * viewDef );
|
|
|
|
void R_AddModels();
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
TR_FRONTEND_DEFORM
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
drawSurf_t * R_DeformDrawSurf( drawSurf_t * drawSurf );
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
TR_FRONTEND_GUISURF
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
void R_SurfaceToTextureAxis( const srfTriangles_t *tri, idVec3 &origin, idVec3 axis[3] );
|
|
void R_AddInGameGuis( const drawSurf_t * const drawSurfs[], const int numDrawSurfs );
|
|
|
|
/*
|
|
============================================================
|
|
|
|
TR_FRONTEND_SUBVIEW
|
|
|
|
============================================================
|
|
*/
|
|
|
|
bool R_PreciseCullSurface( const drawSurf_t *drawSurf, idBounds &ndcBounds );
|
|
bool R_GenerateSubViews( const drawSurf_t * const drawSurfs[], const int numDrawSurfs );
|
|
|
|
/*
|
|
============================================================
|
|
|
|
TR_TRISURF
|
|
|
|
============================================================
|
|
*/
|
|
|
|
srfTriangles_t * R_AllocStaticTriSurf();
|
|
void R_AllocStaticTriSurfVerts( srfTriangles_t *tri, int numVerts );
|
|
void R_AllocStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes );
|
|
void R_AllocStaticTriSurfPreLightShadowVerts( srfTriangles_t *tri, int numVerts );
|
|
void R_AllocStaticTriSurfSilIndexes( srfTriangles_t *tri, int numIndexes );
|
|
void R_AllocStaticTriSurfDominantTris( srfTriangles_t *tri, int numVerts );
|
|
void R_AllocStaticTriSurfSilEdges( srfTriangles_t *tri, int numSilEdges );
|
|
void R_AllocStaticTriSurfMirroredVerts( srfTriangles_t *tri, int numMirroredVerts );
|
|
void R_AllocStaticTriSurfDupVerts( srfTriangles_t *tri, int numDupVerts );
|
|
|
|
srfTriangles_t * R_CopyStaticTriSurf( const srfTriangles_t *tri );
|
|
|
|
void R_ResizeStaticTriSurfVerts( srfTriangles_t *tri, int numVerts );
|
|
void R_ResizeStaticTriSurfIndexes( srfTriangles_t *tri, int numIndexes );
|
|
void R_ReferenceStaticTriSurfVerts( srfTriangles_t *tri, const srfTriangles_t *reference );
|
|
void R_ReferenceStaticTriSurfIndexes( srfTriangles_t *tri, const srfTriangles_t *reference );
|
|
|
|
void R_FreeStaticTriSurfSilIndexes( srfTriangles_t *tri );
|
|
void R_FreeStaticTriSurf( srfTriangles_t *tri );
|
|
void R_FreeStaticTriSurfVerts( srfTriangles_t *tri );
|
|
void R_FreeStaticTriSurfVertexCaches( srfTriangles_t *tri );
|
|
int R_TriSurfMemory( const srfTriangles_t *tri );
|
|
|
|
void R_BoundTriSurf( srfTriangles_t *tri );
|
|
void R_RemoveDuplicatedTriangles( srfTriangles_t *tri );
|
|
void R_CreateSilIndexes( srfTriangles_t *tri );
|
|
void R_RemoveDegenerateTriangles( srfTriangles_t *tri );
|
|
void R_RemoveUnusedVerts( srfTriangles_t *tri );
|
|
void R_RangeCheckIndexes( const srfTriangles_t *tri );
|
|
void R_CreateVertexNormals( srfTriangles_t *tri ); // also called by dmap
|
|
void R_CleanupTriangles( srfTriangles_t *tri, bool createNormals, bool identifySilEdges, bool useUnsmoothedTangents );
|
|
void R_ReverseTriangles( srfTriangles_t *tri );
|
|
|
|
// Only deals with vertexes and indexes, not silhouettes, planes, etc.
|
|
// Does NOT perform a cleanup triangles, so there may be duplicated verts in the result.
|
|
srfTriangles_t * R_MergeSurfaceList( const srfTriangles_t **surfaces, int numSurfaces );
|
|
srfTriangles_t * R_MergeTriangles( const srfTriangles_t *tri1, const srfTriangles_t *tri2 );
|
|
|
|
// if the deformed verts have significant enough texture coordinate changes to reverse the texture
|
|
// polarity of a triangle, the tangents will be incorrect
|
|
void R_DeriveTangents( srfTriangles_t *tri );
|
|
|
|
// copy data from a front-end srfTriangles_t to a back-end drawSurf_t
|
|
void R_InitDrawSurfFromTri( drawSurf_t & ds, srfTriangles_t & tri );
|
|
|
|
// For static surfaces, the indexes, ambient, and shadow buffers can be pre-created at load
|
|
// time, rather than being re-created each frame in the frame temporary buffers.
|
|
void R_CreateStaticBuffersForTri( srfTriangles_t & tri );
|
|
|
|
// deformable meshes precalculate as much as possible from a base frame, then generate
|
|
// complete srfTriangles_t from just a new set of vertexes
|
|
struct deformInfo_t {
|
|
int numSourceVerts;
|
|
|
|
// numOutputVerts may be smaller if the input had duplicated or degenerate triangles
|
|
// it will often be larger if the input had mirrored texture seams that needed
|
|
// to be busted for proper tangent spaces
|
|
int numOutputVerts;
|
|
idDrawVert * verts;
|
|
|
|
int numIndexes;
|
|
triIndex_t * indexes;
|
|
|
|
triIndex_t * silIndexes; // indexes changed to be the first vertex with same XYZ, ignoring normal and texcoords
|
|
|
|
int numMirroredVerts; // this many verts at the end of the vert list are tangent mirrors
|
|
int * mirroredVerts; // tri->mirroredVerts[0] is the mirror of tri->numVerts - tri->numMirroredVerts + 0
|
|
|
|
int numDupVerts; // number of duplicate vertexes
|
|
int * dupVerts; // pairs of the number of the first vertex and the number of the duplicate vertex
|
|
|
|
int numSilEdges; // number of silhouette edges
|
|
silEdge_t * silEdges; // silhouette edges
|
|
|
|
vertCacheHandle_t staticIndexCache; // GL_INDEX_TYPE
|
|
vertCacheHandle_t staticAmbientCache; // idDrawVert
|
|
vertCacheHandle_t staticShadowCache; // idShadowCacheSkinned
|
|
};
|
|
|
|
|
|
// if outputVertexes is not NULL, it will point to a newly allocated set of verts that includes the mirrored ones
|
|
deformInfo_t * R_BuildDeformInfo( int numVerts, const idDrawVert *verts, int numIndexes, const int *indexes,
|
|
bool useUnsmoothedTangents );
|
|
void R_FreeDeformInfo( deformInfo_t *deformInfo );
|
|
int R_DeformInfoMemoryUsed( deformInfo_t *deformInfo );
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
TR_TRACE
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
struct localTrace_t {
|
|
float fraction;
|
|
// only valid if fraction < 1.0
|
|
idVec3 point;
|
|
idVec3 normal;
|
|
int indexes[3];
|
|
};
|
|
|
|
localTrace_t R_LocalTrace( const idVec3 &start, const idVec3 &end, const float radius, const srfTriangles_t *tri );
|
|
void RB_ShowTrace( drawSurf_t **drawSurfs, int numDrawSurfs );
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
BACKEND
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
void RB_ExecuteBackEndCommands( const emptyCommand_t *cmds );
|
|
|
|
/*
|
|
============================================================
|
|
|
|
TR_BACKEND_DRAW
|
|
|
|
============================================================
|
|
*/
|
|
|
|
void RB_DrawElementsWithCounters( const drawSurf_t *surf );
|
|
void RB_DrawViewInternal( const viewDef_t * viewDef, const int stereoEye );
|
|
void RB_DrawView( const void *data, const int stereoEye );
|
|
void RB_CopyRender( const void *data );
|
|
void RB_PostProcess( const void *data );
|
|
|
|
/*
|
|
=============================================================
|
|
|
|
TR_BACKEND_RENDERTOOLS
|
|
|
|
=============================================================
|
|
*/
|
|
|
|
float RB_DrawTextLength( const char *text, float scale, int len );
|
|
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 );
|
|
void RB_ClearDebugText( int time );
|
|
void RB_AddDebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifeTime, const bool depthTest );
|
|
void RB_ClearDebugLines( int time );
|
|
void RB_AddDebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime, const bool depthTest );
|
|
void RB_ClearDebugPolygons( int time );
|
|
void RB_DrawBounds( const idBounds &bounds );
|
|
void RB_ShowLights( drawSurf_t **drawSurfs, int numDrawSurfs );
|
|
void RB_ShowLightCount( drawSurf_t **drawSurfs, int numDrawSurfs );
|
|
void RB_PolygonClear();
|
|
void RB_ScanStencilBuffer();
|
|
void RB_ShowDestinationAlpha();
|
|
void RB_ShowOverdraw();
|
|
void RB_RenderDebugTools( drawSurf_t **drawSurfs, int numDrawSurfs );
|
|
void RB_ShutdownDebugTools();
|
|
|
|
//=============================================
|
|
|
|
#include "ResolutionScale.h"
|
|
#include "RenderLog.h"
|
|
#include "AutoRender.h"
|
|
#include "AutoRenderBink.h"
|
|
#include "jobs/ShadowShared.h"
|
|
#include "jobs/prelightshadowvolume/PreLightShadowVolume.h"
|
|
#include "jobs/staticshadowvolume/StaticShadowVolume.h"
|
|
#include "jobs/dynamicshadowvolume/DynamicShadowVolume.h"
|
|
#include "GraphicsAPIWrapper.h"
|
|
#include "GLMatrix.h"
|
|
|
|
|
|
|
|
#include "BufferObject.h"
|
|
#include "RenderProgs.h"
|
|
#include "RenderWorld_local.h"
|
|
#include "GuiModel.h"
|
|
#include "VertexCache.h"
|
|
|
|
#endif /* !__TR_LOCAL_H__ */
|