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