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 __RENDERWORLD_H__ 30 #define __RENDERWORLD_H__ 31 32 #include "idlib/geometry/Winding.h" 33 #include "idlib/bv/Box.h" 34 #include "idlib/bv/Frustum.h" 35 #include "framework/DeclParticle.h" 36 #include "renderer/Material.h" 37 38 class idDemoFile; 39 class idRenderModel; 40 41 /* 42 =============================================================================== 43 44 Render World 45 46 =============================================================================== 47 */ 48 49 #define PROC_FILE_EXT "proc" 50 #define PROC_FILE_ID "mapProcFile003" 51 52 // shader parms 53 const int MAX_GLOBAL_SHADER_PARMS = 12; 54 55 const int SHADERPARM_RED = 0; 56 const int SHADERPARM_GREEN = 1; 57 const int SHADERPARM_BLUE = 2; 58 const int SHADERPARM_ALPHA = 3; 59 const int SHADERPARM_TIMESCALE = 3; 60 const int SHADERPARM_TIMEOFFSET = 4; 61 const int SHADERPARM_DIVERSITY = 5; // random between 0.0 and 1.0 for some effects (muzzle flashes, etc) 62 const int SHADERPARM_MODE = 7; // for selecting which shader passes to enable 63 const int SHADERPARM_TIME_OF_DEATH = 7; // for the monster skin-burn-away effect enable and time offset 64 65 // model parms 66 const int SHADERPARM_MD5_SKINSCALE = 8; // for scaling vertex offsets on md5 models (jack skellington effect) 67 68 const int SHADERPARM_MD3_FRAME = 8; 69 const int SHADERPARM_MD3_LASTFRAME = 9; 70 const int SHADERPARM_MD3_BACKLERP = 10; 71 72 const int SHADERPARM_BEAM_END_X = 8; // for _beam models 73 const int SHADERPARM_BEAM_END_Y = 9; 74 const int SHADERPARM_BEAM_END_Z = 10; 75 const int SHADERPARM_BEAM_WIDTH = 11; 76 77 const int SHADERPARM_SPRITE_WIDTH = 8; 78 const int SHADERPARM_SPRITE_HEIGHT = 9; 79 80 const int SHADERPARM_PARTICLE_STOPTIME = 8; // don't spawn any more particles after this time 81 82 // guis 83 const int MAX_RENDERENTITY_GUI = 3; 84 85 86 typedef bool(*deferredEntityCallback_t)( renderEntity_s *, const renderView_s * ); 87 88 89 typedef struct renderEntity_s { 90 idRenderModel * hModel; // this can only be null if callback is set 91 92 int entityNum; 93 int bodyId; 94 95 // Entities that are expensive to generate, like skeletal models, can be 96 // deferred until their bounds are found to be in view, in the frustum 97 // of a shadowing light that is in view, or contacted by a trace / overlay test. 98 // This is also used to do visual cueing on items in the view 99 // The renderView may be NULL if the callback is being issued for a non-view related 100 // source. 101 // The callback function should clear renderEntity->callback if it doesn't 102 // want to be called again next time the entity is referenced (ie, if the 103 // callback has now made the entity valid until the next updateEntity) 104 idBounds bounds; // only needs to be set for deferred models and md5s 105 deferredEntityCallback_t callback; 106 107 void * callbackData; // used for whatever the callback wants 108 109 // player bodies and possibly player shadows should be suppressed in views from 110 // that player's eyes, but will show up in mirrors and other subviews 111 // security cameras could suppress their model in their subviews if we add a way 112 // of specifying a view number for a remoteRenderMap view 113 int suppressSurfaceInViewID; 114 int suppressShadowInViewID; 115 116 // world models for the player and weapons will not cast shadows from view weapon 117 // muzzle flashes 118 int suppressShadowInLightID; 119 120 // if non-zero, the surface and shadow (if it casts one) 121 // will only show up in the specific view, ie: player weapons 122 int allowSurfaceInViewID; 123 124 // positioning 125 // axis rotation vectors must be unit length for many 126 // R_LocalToGlobal functions to work, so don't scale models! 127 // axis vectors are [0] = forward, [1] = left, [2] = up 128 idVec3 origin; 129 idMat3 axis; 130 131 // texturing 132 const idMaterial * customShader; // if non-0, all surfaces will use this 133 const idMaterial * referenceShader; // used so flares can reference the proper light shader 134 const idDeclSkin * customSkin; // 0 for no remappings 135 class idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds 136 float shaderParms[ MAX_ENTITY_SHADER_PARMS ]; // can be used in any way by shader or model generation 137 138 // networking: see WriteGUIToSnapshot / ReadGUIFromSnapshot 139 class idUserInterface * gui[ MAX_RENDERENTITY_GUI ]; 140 141 struct renderView_s * remoteRenderView; // any remote camera surfaces will use this 142 143 int numJoints; 144 idJointMat * joints; // array of joints that will modify vertices. 145 // NULL if non-deformable model. NOT freed by renderer 146 147 float modelDepthHack; // squash depth range so particle effects don't clip into walls 148 149 // options to override surface shader flags (replace with material parameters?) 150 bool noSelfShadow; // cast shadows onto other objects,but not self 151 bool noShadow; // no shadow at all 152 153 bool noDynamicInteractions; // don't create any light / shadow interactions after 154 // the level load is completed. This is a performance hack 155 // for the gigantic outdoor meshes in the monorail map, so 156 // all the lights in the moving monorail don't touch the meshes 157 158 bool weaponDepthHack; // squash depth range so view weapons don't poke into walls 159 // this automatically implies noShadow 160 int forceUpdate; // force an update (NOTE: not a bool to keep this struct a multiple of 4 bytes) 161 int timeGroup; 162 int xrayIndex; 163 } renderEntity_t; 164 165 166 typedef struct renderLight_s { 167 idMat3 axis; // rotation vectors, must be unit length 168 idVec3 origin; 169 170 // if non-zero, the light will not show up in the specific view, 171 // which may be used if we want to have slightly different muzzle 172 // flash lights for the player and other views 173 int suppressLightInViewID; 174 175 // if non-zero, the light will only show up in the specific view 176 // which can allow player gun gui lights and such to not effect everyone 177 int allowLightInViewID; 178 179 // I am sticking the four bools together so there are no unused gaps in 180 // the padded structure, which could confuse the memcmp that checks for redundant 181 // updates 182 bool noShadows; // (should we replace this with material parameters on the shader?) 183 bool noSpecular; // (should we replace this with material parameters on the shader?) 184 185 bool pointLight; // otherwise a projection light (should probably invert the sense of this, because points are way more common) 186 bool parallel; // lightCenter gives the direction to the light at infinity 187 idVec3 lightRadius; // xyz radius for point lights 188 idVec3 lightCenter; // offset the lighting direction for shading and 189 // shadows, relative to origin 190 191 // frustum definition for projected lights, all reletive to origin 192 // FIXME: we should probably have real plane equations here, and offer 193 // a helper function for conversion from this format 194 idVec3 target; 195 idVec3 right; 196 idVec3 up; 197 idVec3 start; 198 idVec3 end; 199 200 // Dmap will generate an optimized shadow volume named _prelight_<lightName> 201 // for the light against all the _area* models in the map. The renderer will 202 // ignore this value if the light has been moved after initial creation 203 idRenderModel * prelightModel; 204 205 // muzzle flash lights will not cast shadows from player and weapon world models 206 int lightId; 207 208 209 const idMaterial * shader; // NULL = either lights/defaultPointLight or lights/defaultProjectedLight 210 float shaderParms[MAX_ENTITY_SHADER_PARMS]; // can be used in any way by shader 211 idSoundEmitter * referenceSound; // for shader sound tables, allowing effects to vary with sounds 212 } renderLight_t; 213 214 215 typedef struct renderView_s { 216 // player views will set this to a non-zero integer for model suppress / allow 217 // subviews (mirrors, cameras, etc) will always clear it to zero 218 int viewID; 219 220 // sized from 0 to SCREEN_WIDTH / SCREEN_HEIGHT (640/480), not actual resolution 221 int x, y, width, height; 222 223 float fov_x, fov_y; 224 idVec3 vieworg; 225 idMat3 viewaxis; // transformation matrix, view looks down the positive X axis 226 227 bool cramZNear; // for cinematics, we want to set ZNear much lower 228 bool forceUpdate; // for an update 229 230 // time in milliseconds for shader effects and other time dependent rendering issues 231 int time; 232 float shaderParms[MAX_GLOBAL_SHADER_PARMS]; // can be used in any way by shader 233 const idMaterial *globalMaterial; // used to override everything draw 234 } renderView_t; 235 236 237 // exitPortal_t is returned by idRenderWorld::GetPortal() 238 typedef struct { 239 int areas[2]; // areas connected by this portal 240 const idWinding * w; // winding points have counter clockwise ordering seen from areas[0] 241 int blockingBits; // PS_BLOCK_VIEW, PS_BLOCK_AIR, etc 242 qhandle_t portalHandle; 243 } exitPortal_t; 244 245 246 // guiPoint_t is returned by idRenderWorld::GuiTrace() 247 typedef struct { 248 float x, y; // 0.0 to 1.0 range if trace hit a gui, otherwise -1 249 int guiId; // id of gui ( 0, 1, or 2 ) that the trace happened against 250 } guiPoint_t; 251 252 253 // modelTrace_t is for tracing vs. visual geometry 254 typedef struct modelTrace_s { 255 float fraction; // fraction of trace completed 256 idVec3 point; // end point of trace in global space 257 idVec3 normal; // hit triangle normal vector in global space 258 const idMaterial * material; // material of hit surface 259 const renderEntity_t * entity; // render entity that was hit 260 int jointNumber; // md5 joint nearest to the hit triangle 261 } modelTrace_t; 262 263 264 static const int NUM_PORTAL_ATTRIBUTES = 3; 265 266 typedef enum { 267 PS_BLOCK_NONE = 0, 268 269 PS_BLOCK_VIEW = 1, 270 PS_BLOCK_LOCATION = 2, // game map location strings often stop in hallways 271 PS_BLOCK_AIR = 4, // windows between pressurized and unpresurized areas 272 273 PS_BLOCK_ALL = (1<<NUM_PORTAL_ATTRIBUTES)-1 274 } portalConnection_t; 275 276 277 class idRenderWorld { 278 public: ~idRenderWorld()279 virtual ~idRenderWorld() {}; 280 281 // The same render world can be reinitialized as often as desired 282 // a NULL or empty mapName will create an empty, single area world 283 virtual bool InitFromMap( const char *mapName ) = 0; 284 285 //-------------- Entity and Light Defs ----------------- 286 287 // entityDefs and lightDefs are added to a given world to determine 288 // what will be drawn for a rendered scene. Most update work is defered 289 // until it is determined that it is actually needed for a given view. 290 virtual qhandle_t AddEntityDef( const renderEntity_t *re ) = 0; 291 virtual void UpdateEntityDef( qhandle_t entityHandle, const renderEntity_t *re ) = 0; 292 virtual void FreeEntityDef( qhandle_t entityHandle ) = 0; 293 virtual const renderEntity_t *GetRenderEntity( qhandle_t entityHandle ) const = 0; 294 295 virtual qhandle_t AddLightDef( const renderLight_t *rlight ) = 0; 296 virtual void UpdateLightDef( qhandle_t lightHandle, const renderLight_t *rlight ) = 0; 297 virtual void FreeLightDef( qhandle_t lightHandle ) = 0; 298 virtual const renderLight_t *GetRenderLight( qhandle_t lightHandle ) const = 0; 299 300 // Force the generation of all light / surface interactions at the start of a level 301 // If this isn't called, they will all be dynamically generated 302 virtual void GenerateAllInteractions() = 0; 303 304 // returns true if this area model needs portal sky to draw 305 virtual bool CheckAreaForPortalSky( int areaNum ) = 0; 306 307 //-------------- Decals and Overlays ----------------- 308 309 // Creates decals on all world surfaces that the winding projects onto. 310 // The projection origin should be infront of the winding plane. 311 // The decals are projected onto world geometry between the winding plane and the projection origin. 312 // The decals are depth faded from the winding plane to a certain distance infront of the 313 // winding plane and the same distance from the projection origin towards the winding. 314 virtual void ProjectDecalOntoWorld( const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) = 0; 315 316 // Creates decals on static models. 317 virtual void ProjectDecal( qhandle_t entityHandle, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime ) = 0; 318 319 // Creates overlays on dynamic models. 320 virtual void ProjectOverlay( qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material ) = 0; 321 322 // Removes all decals and overlays from the given entity def. 323 virtual void RemoveDecals( qhandle_t entityHandle ) = 0; 324 325 //-------------- Scene Rendering ----------------- 326 327 // some calls to material functions use the current renderview time when servicing cinematics. this function 328 // ensures that any parms accessed (such as time) are properly set. 329 virtual void SetRenderView( const renderView_t *renderView ) = 0; 330 331 // rendering a scene may actually render multiple subviews for mirrors and portals, and 332 // may render composite textures for gui console screens and light projections 333 // It would also be acceptable to render a scene multiple times, for "rear view mirrors", etc 334 virtual void RenderScene( const renderView_t *renderView ) = 0; 335 336 //-------------- Portal Area Information ----------------- 337 338 // returns the number of portals 339 virtual int NumPortals( void ) const = 0; 340 341 // returns 0 if no portal contacts the bounds 342 // This is used by the game to identify portals that are contained 343 // inside doors, so the connection between areas can be topologically 344 // terminated when the door shuts. 345 virtual qhandle_t FindPortal( const idBounds &b ) const = 0; 346 347 // doors explicitly close off portals when shut 348 // multiple bits can be set to block multiple things, ie: ( PS_VIEW | PS_LOCATION | PS_AIR ) 349 virtual void SetPortalState( qhandle_t portal, int blockingBits ) = 0; 350 virtual int GetPortalState( qhandle_t portal ) = 0; 351 352 // returns true only if a chain of portals without the given connection bits set 353 // exists between the two areas (a door doesn't separate them, etc) 354 virtual bool AreasAreConnected( int areaNum1, int areaNum2, portalConnection_t connection ) = 0; 355 356 // returns the number of portal areas in a map, so game code can build information 357 // tables for the different areas 358 virtual int NumAreas( void ) const = 0; 359 360 // Will return -1 if the point is not in an area, otherwise 361 // it will return 0 <= value < NumAreas() 362 virtual int PointInArea( const idVec3 &point ) const = 0; 363 364 // fills the *areas array with the numbers of the areas the bounds cover 365 // returns the total number of areas the bounds cover 366 virtual int BoundsInAreas( const idBounds &bounds, int *areas, int maxAreas ) const = 0; 367 368 // Used by the sound system to do area flowing 369 virtual int NumPortalsInArea( int areaNum ) = 0; 370 371 // returns one portal from an area 372 virtual exitPortal_t GetPortal( int areaNum, int portalNum ) = 0; 373 374 //-------------- Tracing ----------------- 375 376 // Checks a ray trace against any gui surfaces in an entity, returning the 377 // fraction location of the trace on the gui surface, or -1,-1 if no hit. 378 // This doesn't do any occlusion testing, simply ignoring non-gui surfaces. 379 // start / end are in global world coordinates. 380 virtual guiPoint_t GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const = 0; 381 382 // Traces vs the render model, possibly instantiating a dynamic version, and returns true if something was hit 383 virtual bool ModelTrace( modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius ) const = 0; 384 385 // Traces vs the whole rendered world. FIXME: we need some kind of material flags. 386 virtual bool Trace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic = true, bool skipPlayer = false ) const = 0; 387 388 // Traces vs the world model bsp tree. 389 virtual bool FastWorldTrace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0; 390 391 //-------------- Demo Control ----------------- 392 393 // Writes a loadmap command to the demo, and clears archive counters. 394 virtual void StartWritingDemo( idDemoFile *demo ) = 0; 395 virtual void StopWritingDemo() = 0; 396 397 // Returns true when demoRenderView has been filled in. 398 // adds/updates/frees entityDefs and lightDefs based on the current demo file 399 // and returns the renderView to be used to render this frame. 400 // a demo file may need to be advanced multiple times if the framerate 401 // is less than 30hz 402 // demoTimeOffset will be set if a new map load command was processed before 403 // the next renderScene 404 virtual bool ProcessDemoCommand( idDemoFile *readDemo, renderView_t *demoRenderView, int *demoTimeOffset ) = 0; 405 406 // this is used to regenerate all interactions ( which is currently only done during influences ), there may be a less 407 // expensive way to do it 408 virtual void RegenerateWorld() = 0; 409 410 //-------------- Debug Visualization ----------------- 411 412 // Line drawing for debug visualization 413 virtual void DebugClearLines( int time ) = 0; // a time of 0 will clear all lines and text 414 virtual void DebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime = 0, const bool depthTest = false ) = 0; 415 virtual void DebugArrow( const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime = 0 ) = 0; 416 virtual void DebugWinding( const idVec4 &color, const idWinding &w, const idVec3 &origin, const idMat3 &axis, const int lifetime = 0, const bool depthTest = false ) = 0; 417 virtual void DebugCircle( const idVec4 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const int lifetime = 0, const bool depthTest = false ) = 0; 418 virtual void DebugSphere( const idVec4 &color, const idSphere &sphere, const int lifetime = 0, bool depthTest = false ) = 0; 419 virtual void DebugBounds( const idVec4 &color, const idBounds &bounds, const idVec3 &org = vec3_origin, const int lifetime = 0 ) = 0; 420 virtual void DebugBox( const idVec4 &color, const idBox &box, const int lifetime = 0 ) = 0; 421 virtual void DebugFrustum( const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin = false, const int lifetime = 0 ) = 0; 422 virtual void DebugCone( const idVec4 &color, const idVec3 &apex, const idVec3 &dir, float radius1, float radius2, const int lifetime = 0 ) = 0; 423 virtual void DebugAxis( const idVec3 &origin, const idMat3 &axis ) = 0; 424 425 // Polygon drawing for debug visualization. 426 virtual void DebugClearPolygons( int time ) = 0; // a time of 0 will clear all polygons 427 virtual void DebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime = 0, const bool depthTest = false ) = 0; 428 429 // Text drawing for debug visualization. 430 virtual void DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align = 1, const int lifetime = 0, bool depthTest = false ) = 0; 431 }; 432 433 #endif /* !__RENDERWORLD_H__ */ 434