1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: r_things.cpp 4003 2009-03-04 20:08:00Z 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 //** Refresh of things, i.e. objects represented by sprites.
27 //**
28 //** Sprite rotation 0 is facing the viewer, rotation 1 is one angle turn
29 //** CLOCKWISE around the axis. This is not the same as the angle, which
30 //** increases counter clockwise (protractor). There was a lot of stuff
31 //** grabbed wrong, so I changed it...
32 //**
33 //**************************************************************************
34
35 // HEADER FILES ------------------------------------------------------------
36
37 #include "gamedefs.h"
38 #include "r_local.h"
39 #include "sv_local.h"
40
41 // MACROS ------------------------------------------------------------------
42
43 // TYPES -------------------------------------------------------------------
44
45 enum
46 {
47 SPR_VP_PARALLEL_UPRIGHT,
48 SPR_FACING_UPRIGHT,
49 SPR_VP_PARALLEL,
50 SPR_ORIENTED,
51 SPR_VP_PARALLEL_ORIENTED,
52 SPR_VP_PARALLEL_UPRIGHT_ORIENTED,
53 };
54
55 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
56
57 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
58
59 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
60
61 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
62
63 extern VCvarI r_chasecam;
64
65 // PUBLIC DATA DEFINITIONS -------------------------------------------------
66
67 // PRIVATE DATA DEFINITIONS ------------------------------------------------
68
69 extern VCvarI r_draw_mobjs;
70 extern VCvarI r_draw_psprites;
71 extern VCvarI r_models;
72 extern VCvarI r_hide_models;
73 extern VCvarI r_view_models;
74 extern VCvarI r_model_shadows;
75 extern VCvarI r_model_light;
76 extern VCvarI r_sort_sprites;
77 extern VCvarI r_fix_sprite_offsets;
78 extern VCvarI r_sprite_fix_delta;
79 extern VCvarI r_drawfuzz;
80 extern VCvarF transsouls;
81 extern VCvarI croshair;
82 extern VCvarF croshair_alpha;
83
84 // CODE --------------------------------------------------------------------
85
86 //==========================================================================
87 //
88 // VAdvancedRenderLevel::RenderThingAmbient
89 //
90 //==========================================================================
91
RenderThingAmbient(VEntity * mobj)92 void VAdvancedRenderLevel::RenderThingAmbient(VEntity* mobj)
93 {
94 guard(VAdvancedRenderLevel::RenderThingAmbient);
95 // Skip things in subsectors that are not visible.
96 int SubIdx = mobj->SubSector - Level->Subsectors;
97 if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
98 {
99 return;
100 }
101 if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
102 {
103 // Don't draw camera actor.
104 return;
105 }
106
107 if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
108 (mobj->EntityFlags & VEntity::EF_Invisible))
109 {
110 return;
111 }
112 if (!mobj->State)
113 {
114 return;
115 }
116
117 int RendStyle = mobj->RenderStyle;
118 float Alpha = mobj->Alpha;
119
120 if (RendStyle == STYLE_SoulTrans)
121 {
122 RendStyle = STYLE_Translucent;
123 Alpha = transsouls;
124 }
125 else if (RendStyle == STYLE_OptFuzzy)
126 {
127 RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
128 }
129
130 switch (RendStyle)
131 {
132 case STYLE_None:
133 return;
134
135 case STYLE_Normal:
136 Alpha = 1.0;
137 break;
138
139 case STYLE_Fuzzy:
140 return;
141
142 case STYLE_Add:
143 return;
144 }
145 Alpha = MID(0.0, Alpha, 1.0);
146
147 if (Alpha < 1.0)
148 {
149 return;
150 }
151
152 // Setup lighting
153 vuint32 light;
154 if ((mobj->State->Frame & VState::FF_FULLBRIGHT) ||
155 (mobj->EntityFlags & (VEntity::EF_FullBright | VEntity::EF_Bright)))
156 {
157 light = 0xffffffff;
158 }
159 else
160 {
161 light = LightPointAmbient(mobj->Origin);
162 }
163
164 float TimeFrac = 0;
165 if (mobj->State->Time > 0)
166 {
167 TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
168 TimeFrac = MID(0.0, TimeFrac, 1.0);
169 }
170
171 DrawEntityModel(mobj, light, 0, 1, false, TimeFrac, RPASS_Ambient);
172 unguard;
173 }
174
175 //==========================================================================
176 //
177 // VAdvancedRenderLevel::RenderMobjsAmbient
178 //
179 //==========================================================================
180
RenderMobjsAmbient()181 void VAdvancedRenderLevel::RenderMobjsAmbient()
182 {
183 guard(VAdvancedRenderLevel::RenderMobjsAmbient);
184 if (!r_draw_mobjs || !r_models)
185 {
186 return;
187 }
188
189 for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
190 {
191 RenderThingAmbient(*Ent);
192 }
193 unguard;
194 }
195
196 //==========================================================================
197 //
198 // VAdvancedRenderLevel::RenderThingTextures
199 //
200 //==========================================================================
201
RenderThingTextures(VEntity * mobj)202 void VAdvancedRenderLevel::RenderThingTextures(VEntity* mobj)
203 {
204 guard(VAdvancedRenderLevel::RenderThingAmbient);
205 // Skip things in subsectors that are not visible.
206 int SubIdx = mobj->SubSector - Level->Subsectors;
207 if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
208 {
209 return;
210 }
211 if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
212 {
213 // Don't draw camera actor.
214 return;
215 }
216
217 if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
218 (mobj->EntityFlags & VEntity::EF_Invisible))
219 {
220 return;
221 }
222 if (!mobj->State)
223 {
224 return;
225 }
226
227 int RendStyle = mobj->RenderStyle;
228 float Alpha = mobj->Alpha;
229
230 if (RendStyle == STYLE_SoulTrans)
231 {
232 RendStyle = STYLE_Translucent;
233 Alpha = transsouls;
234 }
235 else if (RendStyle == STYLE_OptFuzzy)
236 {
237 RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
238 }
239
240 switch (RendStyle)
241 {
242 case STYLE_None:
243 return;
244
245 case STYLE_Normal:
246 Alpha = 1.0;
247 break;
248
249 case STYLE_Fuzzy:
250 return;
251
252 case STYLE_Add:
253 return;
254 }
255 Alpha = MID(0.0, Alpha, 1.0);
256
257 if (Alpha < 1.0)
258 {
259 return;
260 }
261
262 float TimeFrac = 0;
263 if (mobj->State->Time > 0)
264 {
265 TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
266 TimeFrac = MID(0.0, TimeFrac, 1.0);
267 }
268
269 DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_Textures);
270 unguard;
271 }
272
273 //==========================================================================
274 //
275 // VAdvancedRenderLevel::RenderMobjsTextures
276 //
277 //==========================================================================
278
RenderMobjsTextures()279 void VAdvancedRenderLevel::RenderMobjsTextures()
280 {
281 guard(VAdvancedRenderLevel::RenderMobjsTextures);
282 if (!r_draw_mobjs || !r_models)
283 {
284 return;
285 }
286
287 for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
288 {
289 RenderThingTextures(*Ent);
290 }
291 unguard;
292 }
293
294 //==========================================================================
295 //
296 // VAdvancedRenderLevel::IsTouchedByLight
297 //
298 //==========================================================================
299
IsTouchedByLight(VEntity * Ent)300 bool VAdvancedRenderLevel::IsTouchedByLight(VEntity* Ent)
301 {
302 guard(VAdvancedRenderLevel::IsTouchedByLight);
303 TVec Delta = Ent->Origin - CurrLightPos;
304 float Dist = Ent->Radius + CurrLightRadius;
305 if (fabs(Delta.x) > Dist || Delta.y > Dist)
306 {
307 return false;
308 }
309 if (Delta.z < -CurrLightRadius)
310 {
311 return false;
312 }
313 if (Delta.z > CurrLightRadius + Ent->Height)
314 {
315 return false;
316 }
317 Delta.z = 0;
318 if (Delta.Length() > Dist)
319 {
320 return false;
321 }
322 return true;
323 unguard;
324 }
325
326 //==========================================================================
327 //
328 // VAdvancedRenderLevel::RenderThingLight
329 //
330 //==========================================================================
331
RenderThingLight(VEntity * mobj)332 void VAdvancedRenderLevel::RenderThingLight(VEntity* mobj)
333 {
334 guard(VAdvancedRenderLevel::RenderThingLight);
335 // Skip things in subsectors that are not visible.
336 int SubIdx = mobj->SubSector - Level->Subsectors;
337 if (!(LightBspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
338 {
339 return;
340 }
341 if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
342 {
343 // Don't draw camera actor.
344 return;
345 }
346
347 if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
348 (mobj->EntityFlags & VEntity::EF_Invisible))
349 {
350 return;
351 }
352 if (!mobj->State)
353 {
354 return;
355 }
356
357 if (!IsTouchedByLight(mobj))
358 {
359 return;
360 }
361
362 int RendStyle = mobj->RenderStyle;
363 float Alpha = mobj->Alpha;
364
365 if (RendStyle == STYLE_SoulTrans)
366 {
367 RendStyle = STYLE_Translucent;
368 Alpha = transsouls;
369 }
370 else if (RendStyle == STYLE_OptFuzzy)
371 {
372 RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
373 }
374
375 switch (RendStyle)
376 {
377 case STYLE_None:
378 return;
379
380 case STYLE_Normal:
381 Alpha = 1.0;
382 break;
383
384 case STYLE_Fuzzy:
385 return;
386
387 case STYLE_Add:
388 return;
389 }
390 Alpha = MID(0.0, Alpha, 1.0);
391
392 if (Alpha < 1.0)
393 {
394 return;
395 }
396
397 float TimeFrac = 0;
398 if (mobj->State->Time > 0)
399 {
400 TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
401 TimeFrac = MID(0.0, TimeFrac, 1.0);
402 }
403
404 DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_Light);
405 unguard;
406 }
407
408 //==========================================================================
409 //
410 // VAdvancedRenderLevel::RenderMobjsLight
411 //
412 //==========================================================================
413
RenderMobjsLight()414 void VAdvancedRenderLevel::RenderMobjsLight()
415 {
416 guard(VAdvancedRenderLevel::RenderMobjsLight);
417 if (!r_draw_mobjs || !r_models || !r_model_light)
418 {
419 return;
420 }
421
422 for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
423 {
424 RenderThingLight(*Ent);
425 }
426 unguard;
427 }
428
429 //==========================================================================
430 //
431 // VAdvancedRenderLevel::RenderThingShadow
432 //
433 //==========================================================================
434
RenderThingShadow(VEntity * mobj)435 void VAdvancedRenderLevel::RenderThingShadow(VEntity* mobj)
436 {
437 guard(VAdvancedRenderLevel::RenderThingShadow);
438 // Skip things in subsectors that are not visible.
439 int SubIdx = mobj->SubSector - Level->Subsectors;
440 if (!(LightVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
441 {
442 return;
443 }
444 if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
445 {
446 // Don't draw camera actor.
447 return;
448 }
449 if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
450 (mobj->EntityFlags & VEntity::EF_Invisible))
451 {
452 return;
453 }
454 if (!mobj->State)
455 {
456 return;
457 }
458 if (!IsTouchedByLight(mobj))
459 {
460 return;
461 }
462
463 int RendStyle = mobj->RenderStyle;
464 float Alpha = mobj->Alpha;
465
466 if (RendStyle == STYLE_SoulTrans)
467 {
468 RendStyle = STYLE_Translucent;
469 Alpha = transsouls;
470 }
471 else if (RendStyle == STYLE_OptFuzzy)
472 {
473 RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
474 }
475
476 switch (RendStyle)
477 {
478 case STYLE_None:
479 return;
480
481 case STYLE_Normal:
482 Alpha = 1.0;
483 break;
484
485 case STYLE_Fuzzy:
486 return;
487
488 case STYLE_Add:
489 return;
490 }
491 Alpha = MID(0.0, Alpha, 1.0);
492
493 if (Alpha < 1.0)
494 {
495 return;
496 }
497
498 float TimeFrac = 0;
499 if (mobj->State->Time > 0)
500 {
501 TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
502 TimeFrac = MID(0.0, TimeFrac, 1.0);
503 }
504
505 DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_ShadowVolumes);
506 unguard;
507 }
508
509 //==========================================================================
510 //
511 // VAdvancedRenderLevel::RenderMobjsShadow
512 //
513 //==========================================================================
514
RenderMobjsShadow()515 void VAdvancedRenderLevel::RenderMobjsShadow()
516 {
517 guard(VAdvancedRenderLevel::RenderMobjsShadow);
518 if (!r_draw_mobjs || !r_models || !r_model_shadows)
519 {
520 return;
521 }
522
523 for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
524 {
525 RenderThingShadow(*Ent);
526 }
527 unguard;
528 }
529
530 //==========================================================================
531 //
532 // VAdvancedRenderLevel::RenderThingFog
533 //
534 //==========================================================================
535
RenderThingFog(VEntity * mobj)536 void VAdvancedRenderLevel::RenderThingFog(VEntity* mobj)
537 {
538 guard(VAdvancedRenderLevel::RenderThingFog);
539 // Skip things in subsectors that are not visible.
540 int SubIdx = mobj->SubSector - Level->Subsectors;
541 if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
542 {
543 return;
544 }
545
546 if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
547 {
548 // Don't draw camera actor.
549 return;
550 }
551
552 if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
553 (mobj->EntityFlags & VEntity::EF_Invisible))
554 {
555 return;
556 }
557 if (!mobj->State)
558 {
559 return;
560 }
561
562 int RendStyle = mobj->RenderStyle;
563 float Alpha = mobj->Alpha;
564
565 if (RendStyle == STYLE_SoulTrans)
566 {
567 RendStyle = STYLE_Translucent;
568 Alpha = transsouls;
569 }
570 else if (RendStyle == STYLE_OptFuzzy)
571 {
572 RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
573 }
574
575 switch (RendStyle)
576 {
577 case STYLE_None:
578 return;
579
580 case STYLE_Normal:
581 Alpha = 1.0;
582 break;
583
584 case STYLE_Fuzzy:
585 return;
586
587 case STYLE_Add:
588 return;
589 }
590 Alpha = MID(0.0, Alpha, 1.0);
591
592 if (Alpha < 1.0)
593 {
594 return;
595 }
596 vuint32 Fade = GetFade(SV_PointInRegion(mobj->Sector, mobj->Origin));
597 if (!Fade)
598 {
599 return;
600 }
601
602 float TimeFrac = 0;
603 if (mobj->State->Time > 0)
604 {
605 TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
606 TimeFrac = MID(0.0, TimeFrac, 1.0);
607 }
608
609 DrawEntityModel(mobj, 0xffffffff, Fade, 1, false, TimeFrac, RPASS_Fog);
610 unguard;
611 }
612
613 //==========================================================================
614 //
615 // VAdvancedRenderLevel::RenderMobjsFog
616 //
617 //==========================================================================
618
RenderMobjsFog()619 void VAdvancedRenderLevel::RenderMobjsFog()
620 {
621 guard(VAdvancedRenderLevel::RenderMobjsFog);
622 if (!r_draw_mobjs || !r_models)
623 {
624 return;
625 }
626
627 for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
628 {
629 RenderThingFog(*Ent);
630 }
631 unguard;
632 }
633