1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: r_local.h 4354 2010-12-23 19:48:32Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 #ifndef _R_LOCAL_H
27 #define _R_LOCAL_H
28 
29 // HEADER FILES ------------------------------------------------------------
30 
31 #include "cl_local.h"
32 #include "r_shared.h"
33 
34 // MACROS ------------------------------------------------------------------
35 
36 #define MAX_SPRITE_MODELS	10*1024
37 
38 // TYPES -------------------------------------------------------------------
39 
40 //
41 //  Sprites are patches with a special naming convention
42 // so they can be recognized by R_InitSprites.
43 //  The base name is NNNNFx or NNNNFxFx, with
44 // x indicating the rotation, x = 0, 1-7.
45 //  The sprite and frame specified by a thing_t
46 // is range checked at run time.
47 //  A sprite is a patch_t that is assumed to represent
48 // a three dimensional object and may have multiple
49 // rotations pre drawn.
50 //  Horizontal flipping is used to save space,
51 // thus NNNNF2F5 defines a mirrored patch.
52 //  Some sprites will only have one picture used
53 // for all views: NNNNF0
54 //
55 struct spriteframe_t
56 {
57 	// If false use 0 for any position.
58 	// Note: as eight entries are available,
59 	//  we might as well insert the same name eight times.
60 	bool		rotate;
61 
62 	// Lump to use for view angles 0-7.
63 	short		lump[16];
64 
65 	// Flip bit (1 = flip) to use for view angles 0-7.
66 	bool		flip[16];
67 };
68 
69 //
70 // 	A sprite definition:
71 // a number of animation frames.
72 //
73 struct spritedef_t
74 {
75 	int				numframes;
76 	spriteframe_t*	spriteframes;
77 };
78 
79 struct segpart_t
80 {
81 	segpart_t*		next;
82 	texinfo_t		texinfo;
83 	surface_t*		surfs;
84 	float			frontTopDist;
85 	float			frontBotDist;
86 	float			backTopDist;
87 	float			backBotDist;
88 	float			TextureOffset;
89 	float			RowOffset;
90 };
91 
92 struct drawseg_t
93 {
94 	seg_t*			seg;
95 	drawseg_t*		next;
96 
97 	segpart_t*		top;
98 	segpart_t*		mid;
99 	segpart_t*		bot;
100 	segpart_t*		topsky;
101 	segpart_t*		extra;
102 
103 	surface_t*		HorizonTop;
104 	surface_t*		HorizonBot;
105 };
106 
107 struct sec_surface_t
108 {
109 	sec_plane_t*	secplane;
110 	texinfo_t		texinfo;
111 	float			dist;
112 	float			XScale;
113 	float			YScale;
114 	float			Angle;
115 	surface_t*		surfs;
116 };
117 
118 struct subregion_t
119 {
120 	sec_region_t*	secregion;
121 	subregion_t*	next;
122 	sec_plane_t*	floorplane;
123 	sec_plane_t*	ceilplane;
124 	sec_surface_t*	floor;
125 	sec_surface_t*	ceil;
126 	int				count;
127 	drawseg_t*		lines;
128 };
129 
130 struct fakefloor_t
131 {
132 	sec_plane_t		floorplane;
133 	sec_plane_t		ceilplane;
134 	sec_params_t	params;
135 };
136 
137 struct skysurface_t : surface_t
138 {
139 	TVec			__verts[3];
140 };
141 
142 struct sky_t
143 {
144 	int 			texture1;
145 	int 			texture2;
146 	float			columnOffset1;
147 	float			columnOffset2;
148 	float			scrollDelta1;
149 	float			scrollDelta2;
150 	skysurface_t	surf;
151 	TPlane			plane;
152 	texinfo_t		texinfo;
153 };
154 
155 class VSky
156 {
157 public:
158 	enum
159 	{
160 		VDIVS			= 8,
161 		HDIVS			= 16
162 	};
163 
164 	sky_t			sky[HDIVS * VDIVS];
165 	int				NumSkySurfs;
166 	int				SideTex;
167 	bool			bIsSkyBox;
168 	bool			SideFlip;
169 
170 	void InitOldSky(int, int, float, float, bool, bool, bool);
171 	void InitSkyBox(VName, VName);
172 	void Init(int, int, float, float, bool, bool, bool, bool);
173 	void Draw(int);
174 };
175 
176 class VSkyPortal : public VPortal
177 {
178 public:
179 	VSky*			Sky;
180 
VSkyPortal(VRenderLevelShared * ARLev,VSky * ASky)181 	VSkyPortal(VRenderLevelShared* ARLev, VSky* ASky)
182 	: VPortal(ARLev)
183 	, Sky(ASky)
184 	{}
185 	bool NeedsDepthBuffer() const;
186 	bool IsSky() const;
187 	bool MatchSky(VSky*) const;
188 	void DrawContents();
189 };
190 
191 class VSkyBoxPortal : public VPortal
192 {
193 public:
194 	VEntity*		Viewport;
195 
VSkyBoxPortal(VRenderLevelShared * ARLev,VEntity * AViewport)196 	VSkyBoxPortal(VRenderLevelShared* ARLev, VEntity* AViewport)
197 	: VPortal(ARLev)
198 	, Viewport(AViewport)
199 	{}
200 	bool IsSky() const;
201 	bool MatchSkyBox(VEntity*) const;
202 	void DrawContents();
203 };
204 
205 class VSectorStackPortal : public VPortal
206 {
207 public:
208 	VEntity*		Viewport;
209 
VSectorStackPortal(VRenderLevelShared * ARLev,VEntity * AViewport)210 	VSectorStackPortal(VRenderLevelShared* ARLev, VEntity* AViewport)
211 	: VPortal(ARLev)
212 	, Viewport(AViewport)
213 	{}
214 	bool MatchSkyBox(VEntity*) const;
215 	void DrawContents();
216 };
217 
218 class VMirrorPortal : public VPortal
219 {
220 public:
221 	TPlane*			Plane;
222 
VMirrorPortal(VRenderLevelShared * ARLev,TPlane * APlane)223 	VMirrorPortal(VRenderLevelShared* ARLev, TPlane* APlane)
224 	: VPortal(ARLev)
225 	, Plane(APlane)
226 	{}
227 	bool MatchMirror(TPlane*) const;
228 	void DrawContents();
229 };
230 
231 enum ERenderPass
232 {
233 	//	For regular renderer.
234 	RPASS_Normal,
235 	//	For advanced renderer.
236 	RPASS_Ambient,
237 	RPASS_ShadowVolumes,
238 	RPASS_Light,
239 	RPASS_Textures,
240 	RPASS_Fog,
241 	RPASS_NonShadow,
242 };
243 
244 class VRenderLevelShared : public VRenderLevelDrawer
245 {
246 protected:
247 	friend class VPortal;
248 	friend class VSkyPortal;
249 	friend class VSkyBoxPortal;
250 	friend class VSectorStackPortal;
251 	friend class VMirrorPortal;
252 
253 	enum
254 	{
255 		MAX_TRANS_SPRITES	= 256,
256 
257 		MAX_PARTICLES			= 2048,	// default max # of particles at one
258 										//  time
259 		ABSOLUTE_MIN_PARTICLES	= 512,	// no fewer than this no matter what's
260 										//  on the command line
261 		MAX_DLIGHTS	= 32,
262 	};
263 
264 	struct trans_sprite_t
265 	{
266 		TVec			Verts[4];
267 		union
268 		{
269 			surface_t*	surf;
270 			VEntity*	Ent;
271 		};
272 		int				lump;
273 		TVec			normal;
274 		union
275 		{
276 			float		pdist;
277 			float		TimeFrac;
278 		};
279 		TVec			saxis;
280 		TVec			taxis;
281 		TVec			texorg;
282 		float			Alpha;
283 		bool			Additive;
284 		int				translation;
285 		int				type;
286 		float			dist;
287 		vuint32			light;
288 		vuint32			Fade;
289 	};
290 
291 	struct world_surf_t
292 	{
293 		surface_t*		Surf;
294 		vuint8			Type;
295 	};
296 
297 	struct light_t
298 	{
299 		TVec			origin;
300 		float			radius;
301 		vuint32			colour;
302 		int				leafnum;
303 	};
304 
305 	VLevel*			Level;
306 
307 	VEntity*		ViewEnt;
308 
309 	int				FrustumIndexes[5][6];
310 	int				MirrorLevel;
311 	int				PortalLevel;
312 	int				VisSize;
313 	vuint8*			BspVis;
314 
315 	subsector_t*	r_viewleaf;
316 	subsector_t*	r_oldviewleaf;
317 	float			old_fov;
318 	int				prev_aspect_ratio;
319 
320 	//	Bumped light from gun blasts
321 	int				ExtraLight;
322 	int				FixedLight;
323 	int				ColourMap;
324 
325 	int				NumParticles;
326 	particle_t*		Particles;
327 	particle_t*		ActiveParticles;
328 	particle_t*		FreeParticles;
329 
330 	//	Sky variables
331 	int				CurrentSky1Texture;
332 	int				CurrentSky2Texture;
333 	bool			CurrentDoubleSky;
334 	bool			CurrentLightning;
335 	VSky			BaseSky;
336 
337 	//	World render variables
338 	VViewClipper			ViewClip;
339 	TArray<world_surf_t>	WorldSurfs;
340 	TArray<VPortal*>		Portals;
341 	TArray<VSky*>			SideSkies;
342 
343 	trans_sprite_t*	trans_sprites;
344 	trans_sprite_t	MainTransSprites[MAX_TRANS_SPRITES];
345 
346 	sec_plane_t		sky_plane;
347 	float			skyheight;
348 	surface_t*		free_wsurfs;
349 	void*			AllocatedWSurfBlocks;
350 	subregion_t*	AllocatedSubRegions;
351 	drawseg_t*		AllocatedDrawSegs;
352 	segpart_t*		AllocatedSegParts;
353 
354 	//	Light variables
355 	TArray<light_t>	Lights;
356 	dlight_t		DLights[MAX_DLIGHTS];
357 
358 	// Only regular renderer needs this.
359 	vuint32			cacheframecount;
360 
361 	//	Moved here so that model rendering methods can be merged.
362 	TVec			CurrLightPos;
363 	float			CurrLightRadius;
364 
365 	VRenderLevelShared(VLevel* ALevel);
366 	~VRenderLevelShared();
367 
368 	virtual void RenderScene(const refdef_t*, const VViewClipper*) = 0;
369 	virtual void PushDlights() = 0;
370 	virtual vuint32 LightPoint(const TVec &p) = 0;
371 	virtual void InitSurfs(surface_t*, texinfo_t*, TPlane*, subsector_t*) = 0;
372 	virtual surface_t* SubdivideFace(surface_t*, const TVec&, const TVec*) = 0;
373 	virtual surface_t* SubdivideSeg(surface_t*, const TVec&, const TVec*) = 0;
374 	virtual void QueueWorldSurface(surface_t*) = 0;
375 	virtual void FreeSurfCache(surfcache_t*);
376 
377 	//	General
378 	void ExecuteSetViewSize();
379 	void TransformFrustum();
380 	void SetupFrame();
381 	void SetupCameraFrame(VEntity*, VTexture*, int, refdef_t*);
382 	void MarkLeaves();
383 	void UpdateCameraTexture(VEntity*, int, int);
384 	vuint32 GetFade(sec_region_t*);
385 	void PrecacheLevel();
386 	VTextureTranslation* GetTranslation(int);
387 	void BuildPlayerTranslations();
388 
389 	//	Particles
390 	void InitParticles();
391 	void ClearParticles();
392 	void UpdateParticles(float);
393 	void DrawParticles();
394 
395 	//	Sky methods
396 	void InitSky();
397 	void AnimateSky(float);
398 
399 	//	World BSP rendering
400 	void SetUpFrustumIndexes();
401 	void QueueSimpleSurf(surface_t*);
402 	void QueueSkyPortal(surface_t*);
403 	void QueueHorizonPortal(surface_t*);
404 	void DrawSurfaces(surface_t*, texinfo_t*, VEntity*, int, int, bool, bool);
405 	void RenderHorizon(drawseg_t*);
406 	void RenderMirror(drawseg_t*);
407 	void RenderLine(drawseg_t*);
408 	void RenderSecSurface(sec_surface_t*, VEntity*);
409 	void RenderSubRegion(subregion_t*);
410 	void RenderSubsector(int);
411 	void RenderBSPNode(int, float*, int);
412 	void RenderBspWorld(const refdef_t*, const VViewClipper*);
413 	void RenderPortals();
414 
415 	//	Surf methods
416 	void SetupSky();
417 	void FlushSurfCaches(surface_t*);
418 	sec_surface_t* CreateSecSurface(subsector_t*, sec_plane_t*);
419 	void UpdateSecSurface(sec_surface_t*, sec_plane_t*, subsector_t*);
420 	surface_t* NewWSurf();
421 	void FreeWSurfs(surface_t*);
422 	surface_t* CreateWSurfs(TVec*, texinfo_t*, seg_t*, subsector_t*);
423 	int CountSegParts(seg_t*);
424 	void CreateSegParts(drawseg_t*, seg_t*);
425 	void UpdateRowOffset(segpart_t*, float);
426 	void UpdateTextureOffset(segpart_t*, float);
427 	void UpdateDrawSeg(drawseg_t*, bool);
428 	void CreateWorldSurfaces();
429 	void UpdateSubRegion(subregion_t*, bool);
430 	bool CopyPlaneIfValid(sec_plane_t*, const sec_plane_t*,
431 		const sec_plane_t*);
432 	void UpdateFakeFlats(sector_t*);
433 	void FreeSurfaces(surface_t*);
434 	void FreeSegParts(segpart_t*);
435 
436 	//	Models
437 	bool DrawAliasModel(const TVec&, const TAVec&, float, float, VModel*,
438 		int, int, VTextureTranslation*, int, vuint32, vuint32, float, bool,
439 		bool, float, bool, ERenderPass);
440 	bool DrawAliasModel(const TVec&, const TAVec&, float, float, VState*,
441 		VState*, VTextureTranslation*, int, vuint32, vuint32, float, bool,
442 		bool, float, bool, ERenderPass);
443 	bool DrawEntityModel(VEntity*, vuint32, vuint32, float, bool, float,
444 		ERenderPass);
445 	bool CheckAliasModelFrame(VEntity*, float);
446 
447 	//	Things
448 	void DrawTranslucentPoly(surface_t*, TVec*, int, int, float, bool, int,
449 		bool, vuint32, vuint32, const TVec&, float, const TVec&, const TVec&,
450 		const TVec&);
451 	void RenderSprite(VEntity*, vuint32, vuint32, float, bool);
452 	void RenderTranslucentAliasModel(VEntity*, vuint32, vuint32, float, bool,
453 		float);
454 	bool RenderAliasModel(VEntity*, vuint32, vuint32, float, bool,
455 		ERenderPass);
456 	void RenderThing(VEntity*, ERenderPass);
457 	void RenderMobjs(ERenderPass);
458 	void DrawTranslucentPolys();
459 	void RenderPSprite(VViewState*, float, vuint32, vuint32, float, bool);
460 	bool RenderViewModel(VViewState*, vuint32, vuint32, float, bool);
461 	void DrawPlayerSprites();
462 	void DrawCroshair();
463 
464 public:
465 	particle_t* NewParticle();
466 
467 	void RenderPlayerView();
468 
469 	void SegMoved(seg_t*);
470 	void SetupFakeFloors(sector_t*);
471 
472 	void AddStaticLight(const TVec&, float, vuint32);
473 	dlight_t* AllocDlight(VThinker*);
474 	void DecayLights(float);
475 };
476 
477 class VRenderLevel : public VRenderLevelShared
478 {
479 private:
480 	int				c_subdivides;
481 	int				c_seg_div;
482 
483 	//	Surface cache.
484 	surfcache_t*	freeblocks;
485 	surfcache_t*	cacheblocks[NUM_BLOCK_SURFS];
486 	surfcache_t		blockbuf[NUM_CACHE_BLOCKS];
487 
488 	//	General
489 	void RenderScene(const refdef_t*, const VViewClipper*);
490 
491 	//	Surf methods
492 	void InitSurfs(surface_t*, texinfo_t*, TPlane*, subsector_t*);
493 	surface_t* SubdivideFace(surface_t*, const TVec&, const TVec*);
494 	surface_t* SubdivideSeg(surface_t*, const TVec&, const TVec*);
495 	void UpdateSubsector(int, float*);
496 	void UpdateBSPNode(int, float*);
497 	void UpdateWorld(const refdef_t*, const VViewClipper*);
498 
499 	//	Light methods
500 	static void CalcMinMaxs(surface_t*);
501 	float CastRay(const TVec&, const TVec&, float);
502 	static void CalcFaceVectors(surface_t*);
503 	void CalcPoints(surface_t*);
504 	void SingleLightFace(light_t*, surface_t*);
505 	void LightFace(surface_t*, subsector_t*);
506 	void MarkLights(dlight_t*, int, int);
507 	void AddDynamicLights(surface_t*);
508 	void PushDlights();
509 	void FlushCaches();
510 	void FlushOldCaches();
511 	surfcache_t* AllocBlock(int, int);
512 	surfcache_t	*FreeBlock(surfcache_t*, bool);
513 	void FreeSurfCache(surfcache_t*);
514 	void CacheSurface(surface_t*);
515 
516 	//	World BSP rendering
517 	void QueueWorldSurface(surface_t*);
518 	void RenderWorld(const refdef_t*, const VViewClipper*);
519 
520 public:
521 	VRenderLevel(VLevel*);
522 
523 	void PreRender();
524 
525 	vuint32 LightPoint(const TVec &p);
526 	bool BuildLightMap(surface_t*, int);
527 };
528 
529 class VAdvancedRenderLevel : public VRenderLevelShared
530 {
531 private:
532 	VViewClipper			LightClip;
533 	byte*					LightVis;
534 	byte*					LightBspVis;
535 	vuint32					CurrLightColour;
536 
537 	//	General
538 	void RenderScene(const refdef_t*, const VViewClipper*);
539 
540 	//	Surf methods
541 	void InitSurfs(surface_t*, texinfo_t*, TPlane*, subsector_t*);
542 	surface_t* SubdivideFace(surface_t*, const TVec&, const TVec*);
543 	surface_t* SubdivideSeg(surface_t*, const TVec&, const TVec*);
544 	void UpdateSubsector(int, float*);
545 	void UpdateBSPNode(int, float*);
546 	void UpdateWorld();
547 
548 	//	Light methods
549 	void PushDlights();
550 	vuint32 LightPointAmbient(const TVec &p);
551 
552 	//	World BSP rendering
553 	void QueueWorldSurface(surface_t*);
554 	void RenderWorld(const refdef_t*, const VViewClipper*);
555 
556 	void BuildLightVis(int bspnum, float* bbox);
557 	void DrawShadowSurfaces(surface_t* InSurfs, texinfo_t *texinfo,
558 		bool CheckSkyBoxAlways);
559 	void RenderShadowLine(drawseg_t* dseg);
560 	void RenderShadowSecSurface(sec_surface_t* ssurf, VEntity* SkyBox);
561 	void RenderShadowSubRegion(subregion_t* region);
562 	void RenderShadowSubsector(int num);
563 	void RenderShadowBSPNode(int bspnum, float* bbox);
564 	void DrawLightSurfaces(surface_t* InSurfs, texinfo_t *texinfo,
565 		VEntity* SkyBox, bool CheckSkyBoxAlways);
566 	void RenderLightLine(drawseg_t* dseg);
567 	void RenderLightSecSurface(sec_surface_t* ssurf, VEntity* SkyBox);
568 	void RenderLightSubRegion(subregion_t* region);
569 	void RenderLightSubsector(int num);
570 	void RenderLightBSPNode(int bspnum, float* bbox);
571 	void RenderLightShadows(const refdef_t* RD, const VViewClipper* Range,
572 		TVec& Pos, float Radius, vuint32 Colour);
573 
574 	//	Things
575 	void RenderThingAmbient(VEntity*);
576 	void RenderMobjsAmbient();
577 	void RenderThingTextures(VEntity*);
578 	void RenderMobjsTextures();
579 	bool IsTouchedByLight(VEntity*);
580 	void RenderThingLight(VEntity*);
581 	void RenderMobjsLight();
582 	void RenderThingShadow(VEntity*);
583 	void RenderMobjsShadow();
584 	void RenderThingFog(VEntity*);
585 	void RenderMobjsFog();
586 
587 public:
588 	VAdvancedRenderLevel(VLevel*);
589 	~VAdvancedRenderLevel();
590 
591 	void PreRender();
592 
593 	vuint32 LightPoint(const TVec &p);
594 	bool BuildLightMap(surface_t*, int);
595 };
596 
597 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
598 
599 //
600 // R_Sky
601 //
602 void R_InitSkyBoxes();
603 
604 //
605 //	r_model
606 //
607 void R_InitModels();
608 void R_FreeModels();
609 
610 int R_SetMenuPlayerTrans(int, int, int);
611 
612 // PUBLIC DATA DECLARATIONS ------------------------------------------------
613 
614 extern spritedef_t		sprites[MAX_SPRITE_MODELS];
615 
616 //
617 // R_Main
618 //
619 extern int      		screenblocks;
620 extern int				r_visframecount;
621 
622 extern byte				light_remap[256];
623 extern VCvarI			r_darken;
624 extern VCvarI			r_dynamic;
625 extern VCvarI			r_static_lights;
626 
627 extern refdef_t			refdef;
628 
629 extern VCvarI			aspect_ratio;
630 extern VCvarI			r_interpolate_frames;
631 
632 extern VTextureTranslation**		TranslationTables;
633 extern int							NumTranslationTables;
634 extern VTextureTranslation			IceTranslation;
635 extern TArray<VTextureTranslation*>	DecorateTranslations;
636 extern TArray<VTextureTranslation*>	BloodTranslations;
637 
638 #endif
639