1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: gl_poly.cpp 4349 2010-12-17 15:07:11Z 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 // HEADER FILES ------------------------------------------------------------
27
28 #include "gl_local.h"
29
30 // MACROS ------------------------------------------------------------------
31
32 // TYPES -------------------------------------------------------------------
33
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45
46 // CODE --------------------------------------------------------------------
47
48 //==========================================================================
49 //
50 // glVertex
51 //
52 //==========================================================================
53
glVertex(const TVec & v)54 inline void glVertex(const TVec &v)
55 {
56 glVertex3f(v.x, v.y, v.z);
57 }
58
59 //==========================================================================
60 //
61 // VOpenGLDrawer::WorldDrawing
62 //
63 //==========================================================================
64
WorldDrawing()65 void VOpenGLDrawer::WorldDrawing()
66 {
67 guard(VOpenGLDrawer::WorldDrawing);
68 if (HaveShaders)
69 {
70 WorldDrawingShaders();
71 return;
72 }
73
74 int lb, i;
75 surfcache_t *cache;
76 GLfloat s, t;
77 GLfloat lights, lightt;
78 surface_t *surf;
79 texinfo_t *tex;
80
81 // First draw horizons.
82 if (RendLev->HorizonPortalsHead)
83 {
84 for (surf = RendLev->HorizonPortalsHead; surf; surf = surf->DrawNext)
85 {
86 DoHorizonPolygon(surf);
87 }
88 }
89
90 // For sky areas we just write to the depth buffer to prevent drawing
91 // polygons behind the sky.
92 if (RendLev->SkyPortalsHead)
93 {
94 glDisable(GL_TEXTURE_2D);
95 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
96 for (surf = RendLev->SkyPortalsHead; surf; surf = surf->DrawNext)
97 {
98 glBegin(GL_POLYGON);
99 for (i = 0; i < surf->count; i++)
100 {
101 glVertex(surf->verts[i]);
102 }
103 glEnd();
104 }
105 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
106 glEnable(GL_TEXTURE_2D);
107 }
108
109 // Draw surfaces.
110 if (RendLev->SimpleSurfsHead)
111 {
112 for (surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
113 {
114 texinfo_t* tex = surf->texinfo;
115 SetTexture(tex->Tex, tex->ColourMap);
116
117 if (surf->lightmap != NULL ||
118 surf->dlightframe == r_dlightframecount)
119 {
120 glColor4f(1, 1, 1, 1);
121 }
122 else
123 {
124 float lev = float(surf->Light >> 24) / 255.0;
125 glColor4f(((surf->Light >> 16) & 255) * lev / 255.0,
126 ((surf->Light >> 8) & 255) * lev / 255.0,
127 (surf->Light & 255) * lev / 255.0, 1.0);
128 }
129 SetFade(surf->Fade);
130
131 glBegin(GL_POLYGON);
132 for (i = 0; i < surf->count; i++)
133 {
134 glTexCoord2f((DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
135 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
136 glVertex(surf->verts[i]);
137 }
138 glEnd();
139 }
140 }
141
142 if (HaveMultiTexture)
143 {
144 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
145 SelectTexture(1);
146 glEnable(GL_TEXTURE_2D);
147 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
148 SelectTexture(0);
149 glColor4f(1, 1, 1, 1);
150
151 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
152 {
153 if (!RendLev->light_chain[lb])
154 {
155 continue;
156 }
157
158 SelectTexture(1);
159 glBindTexture(GL_TEXTURE_2D, lmap_id[lb]);
160 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
161 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162
163 if (RendLev->block_changed[lb])
164 {
165 RendLev->block_changed[lb] = false;
166 glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT,
167 0, GL_RGBA, GL_UNSIGNED_BYTE, RendLev->light_block[lb]);
168 }
169 SelectTexture(0);
170
171 for (cache = RendLev->light_chain[lb]; cache; cache = cache->chain)
172 {
173 surf = cache->surf;
174 tex = surf->texinfo;
175
176 SetTexture(tex->Tex, tex->ColourMap);
177 SetFade(surf->Fade);
178 glBegin(GL_POLYGON);
179 for (i = 0; i < surf->count; i++)
180 {
181 s = DotProduct(surf->verts[i], tex->saxis) + tex->soffs;
182 t = DotProduct(surf->verts[i], tex->taxis) + tex->toffs;
183 lights = (s - surf->texturemins[0] +
184 cache->s * 16 + 8) / (BLOCK_WIDTH * 16);
185 lightt = (t - surf->texturemins[1] +
186 cache->t * 16 + 8) / (BLOCK_HEIGHT * 16);
187 MultiTexCoord(0, s * tex_iw, t * tex_ih);
188 MultiTexCoord(1, lights, lightt);
189 glVertex(surf->verts[i]);
190 }
191 glEnd();
192 }
193 }
194
195 SelectTexture(1);
196 glDisable(GL_TEXTURE_2D);
197 SelectTexture(0);
198 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
199 }
200 else
201 {
202 glDepthMask(0); // don't bother writing Z
203 glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
204 glEnable(GL_BLEND);
205 glColor4f(1, 1, 1, 1);
206
207 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
208 {
209 if (!RendLev->light_chain[lb])
210 {
211 continue;
212 }
213
214 glBindTexture(GL_TEXTURE_2D, lmap_id[lb]);
215 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
216 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
217
218 if (RendLev->block_changed[lb])
219 {
220 RendLev->block_changed[lb] = false;
221 glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT,
222 0, GL_RGBA, GL_UNSIGNED_BYTE, RendLev->light_block[lb]);
223 }
224
225 for (cache = RendLev->light_chain[lb]; cache; cache = cache->chain)
226 {
227 surf = cache->surf;
228 tex = surf->texinfo;
229
230 SetFade(surf->Fade);
231 glBegin(GL_POLYGON);
232 for (i = 0; i < surf->count; i++)
233 {
234 s = (DotProduct(surf->verts[i], tex->saxis) + tex->soffs -
235 surf->texturemins[0] + cache->s * 16 + 8) / (BLOCK_WIDTH * 16);
236 t = (DotProduct(surf->verts[i], tex->taxis) + tex->toffs -
237 surf->texturemins[1] + cache->t * 16 + 8) / (BLOCK_HEIGHT * 16);
238 glTexCoord2f(s, t);
239 glVertex(surf->verts[i]);
240 }
241 glEnd();
242 }
243 }
244
245 glDisable(GL_BLEND);
246 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
247 glDepthMask(1); // back to normal Z buffering
248 }
249
250 //
251 // Add specular lights
252 //
253 if (specular_highlights)
254 {
255 glDepthMask(0); // don't bother writing Z
256 glBlendFunc(GL_ONE, GL_ONE);
257 glEnable(GL_BLEND);
258 glColor4f(1, 1, 1, 1);
259 SetFade(0);
260
261 for (lb = 0; lb < NUM_BLOCK_SURFS; lb++)
262 {
263 if (!RendLev->add_chain[lb])
264 {
265 continue;
266 }
267
268 glBindTexture(GL_TEXTURE_2D, addmap_id[lb]);
269 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
270 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
271
272 if (RendLev->add_changed[lb])
273 {
274 RendLev->add_changed[lb] = false;
275 glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT,
276 0, GL_RGBA, GL_UNSIGNED_BYTE, RendLev->add_block[lb]);
277 }
278
279 for (cache = RendLev->add_chain[lb]; cache; cache = cache->addchain)
280 {
281 surf = cache->surf;
282 tex = surf->texinfo;
283
284 glBegin(GL_POLYGON);
285 for (i = 0; i < surf->count; i++)
286 {
287 s = (DotProduct(surf->verts[i], tex->saxis) + tex->soffs -
288 surf->texturemins[0] + cache->s * 16 + 8) / (BLOCK_WIDTH * 16);
289 t = (DotProduct(surf->verts[i], tex->taxis) + tex->toffs -
290 surf->texturemins[1] + cache->t * 16 + 8) / (BLOCK_HEIGHT * 16);
291 glTexCoord2f(s, t);
292 glVertex(surf->verts[i]);
293 }
294 glEnd();
295 }
296 }
297
298 glDisable(GL_BLEND);
299 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
300 glDepthMask(1); // back to normal Z buffering
301 }
302 unguard;
303 }
304
305 //==========================================================================
306 //
307 // VOpenGLDrawer::WorldDrawingShaders
308 //
309 //==========================================================================
310
WorldDrawingShaders()311 void VOpenGLDrawer::WorldDrawingShaders()
312 {
313 guard(VOpenGLDrawer::WorldDrawingShaders);
314 surfcache_t *cache;
315 surface_t *surf;
316 texinfo_t *tex;
317
318 // First draw horizons.
319 if (RendLev->HorizonPortalsHead)
320 {
321 for (surf = RendLev->HorizonPortalsHead; surf; surf = surf->DrawNext)
322 {
323 DoHorizonPolygon(surf);
324 }
325 }
326
327 // For sky areas we just write to the depth buffer to prevent drawing
328 // polygons behind the sky.
329 if (RendLev->SkyPortalsHead)
330 {
331 p_glUseProgramObjectARB(SurfZBufProgram);
332 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
333 for (surf = RendLev->SkyPortalsHead; surf; surf = surf->DrawNext)
334 {
335 glBegin(GL_POLYGON);
336 for (int i = 0; i < surf->count; i++)
337 {
338 glVertex(surf->verts[i]);
339 }
340 glEnd();
341 }
342 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
343 }
344
345 // Draw surfaces.
346 if (RendLev->SimpleSurfsHead)
347 {
348 p_glUseProgramObjectARB(SurfSimpleProgram);
349 p_glUniform1iARB(SurfSimpleTextureLoc, 0);
350 p_glUniform1iARB(SurfSimpleFogTypeLoc, r_fog & 3);
351
352 for (surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
353 {
354 texinfo_t* tex = surf->texinfo;
355 SetTexture(tex->Tex, tex->ColourMap);
356 p_glUniform3fvARB(SurfSimpleSAxisLoc, 1, &tex->saxis.x);
357 p_glUniform1fARB(SurfSimpleSOffsLoc, tex->soffs);
358 p_glUniform1fARB(SurfSimpleTexIWLoc, tex_iw);
359 p_glUniform3fvARB(SurfSimpleTAxisLoc, 1, &tex->taxis.x);
360 p_glUniform1fARB(SurfSimpleTOffsLoc, tex->toffs);
361 p_glUniform1fARB(SurfSimpleTexIHLoc, tex_ih);
362
363 float lev = float(surf->Light >> 24) / 255.0;
364 p_glUniform4fARB(SurfSimpleLightLoc,
365 ((surf->Light >> 16) & 255) * lev / 255.0,
366 ((surf->Light >> 8) & 255) * lev / 255.0,
367 (surf->Light & 255) * lev / 255.0, 1.0);
368 if (surf->Fade)
369 {
370 p_glUniform1iARB(SurfSimpleFogEnabledLoc, GL_TRUE);
371 p_glUniform4fARB(SurfSimpleFogColourLoc,
372 ((surf->Fade >> 16) & 255) / 255.0,
373 ((surf->Fade >> 8) & 255) / 255.0,
374 (surf->Fade & 255) / 255.0, 1.0);
375 p_glUniform1fARB(SurfSimpleFogDensityLoc, surf->Fade == FADE_LIGHT ? 0.3 : r_fog_density);
376 p_glUniform1fARB(SurfSimpleFogStartLoc, surf->Fade == FADE_LIGHT ? 1.0 : r_fog_start);
377 p_glUniform1fARB(SurfSimpleFogEndLoc, surf->Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
378 }
379 else
380 {
381 p_glUniform1iARB(SurfSimpleFogEnabledLoc, GL_FALSE);
382 }
383
384 glBegin(GL_POLYGON);
385 for (int i = 0; i < surf->count; i++)
386 {
387 glVertex(surf->verts[i]);
388 }
389 glEnd();
390 }
391 }
392
393 p_glUseProgramObjectARB(SurfLightmapProgram);
394 p_glUniform1iARB(SurfLightmapTextureLoc, 0);
395 p_glUniform1iARB(SurfLightmapLightMapLoc, 1);
396 p_glUniform1iARB(SurfLightmapSpecularMapLoc, 2);
397 p_glUniform1iARB(SurfLightmapFogTypeLoc, r_fog & 3);
398
399 for (int lb = 0; lb < NUM_BLOCK_SURFS; lb++)
400 {
401 if (!RendLev->light_chain[lb])
402 {
403 continue;
404 }
405
406 SelectTexture(1);
407 glBindTexture(GL_TEXTURE_2D, lmap_id[lb]);
408 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
410 if (RendLev->block_changed[lb])
411 {
412 RendLev->block_changed[lb] = false;
413 glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT,
414 0, GL_RGBA, GL_UNSIGNED_BYTE, RendLev->light_block[lb]);
415 RendLev->add_changed[lb] = true;
416 }
417
418 SelectTexture(2);
419 glBindTexture(GL_TEXTURE_2D, addmap_id[lb]);
420 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
421 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
422 if (RendLev->add_changed[lb])
423 {
424 RendLev->add_changed[lb] = false;
425 glTexImage2D(GL_TEXTURE_2D, 0, 4, BLOCK_WIDTH, BLOCK_HEIGHT,
426 0, GL_RGBA, GL_UNSIGNED_BYTE, RendLev->add_block[lb]);
427 }
428
429 SelectTexture(0);
430
431 for (cache = RendLev->light_chain[lb]; cache; cache = cache->chain)
432 {
433 surf = cache->surf;
434 tex = surf->texinfo;
435 SetTexture(tex->Tex, tex->ColourMap);
436
437 p_glUniform3fvARB(SurfLightmapSAxisLoc, 1, &tex->saxis.x);
438 p_glUniform1fARB(SurfLightmapSOffsLoc, tex->soffs);
439 p_glUniform1fARB(SurfLightmapTexIWLoc, tex_iw);
440 p_glUniform3fvARB(SurfLightmapTAxisLoc, 1, &tex->taxis.x);
441 p_glUniform1fARB(SurfLightmapTOffsLoc, tex->toffs);
442 p_glUniform1fARB(SurfLightmapTexIHLoc, tex_ih);
443 p_glUniform1fARB(SurfLightmapTexMinSLoc, surf->texturemins[0]);
444 p_glUniform1fARB(SurfLightmapTexMinTLoc, surf->texturemins[1]);
445 p_glUniform1fARB(SurfLightmapCacheSLoc, cache->s);
446 p_glUniform1fARB(SurfLightmapCacheTLoc, cache->t);
447
448 if (surf->Fade)
449 {
450 p_glUniform1iARB(SurfLightmapFogEnabledLoc, GL_TRUE);
451 p_glUniform4fARB(SurfLightmapFogColourLoc,
452 ((surf->Fade >> 16) & 255) / 255.0,
453 ((surf->Fade >> 8) & 255) / 255.0,
454 (surf->Fade & 255) / 255.0, 1.0);
455 p_glUniform1fARB(SurfLightmapFogDensityLoc, surf->Fade == FADE_LIGHT ? 0.3 : r_fog_density);
456 p_glUniform1fARB(SurfLightmapFogStartLoc, surf->Fade == FADE_LIGHT ? 1.0 : r_fog_start);
457 p_glUniform1fARB(SurfLightmapFogEndLoc, surf->Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
458 }
459 else
460 {
461 p_glUniform1iARB(SurfLightmapFogEnabledLoc, GL_FALSE);
462 }
463
464 glBegin(GL_POLYGON);
465 for (int i = 0; i < surf->count; i++)
466 {
467 glVertex(surf->verts[i]);
468 }
469 glEnd();
470 }
471 }
472 unguard;
473 }
474
475 //==========================================================================
476 //
477 // VOpenGLDrawer::DrawWorldAmbientPass
478 //
479 //==========================================================================
480
DrawWorldAmbientPass()481 void VOpenGLDrawer::DrawWorldAmbientPass()
482 {
483 guard(VOpenGLDrawer::DrawWorldAmbientPass);
484 // First draw horizons.
485 if (RendLev->HorizonPortalsHead)
486 {
487 for (surface_t* surf = RendLev->HorizonPortalsHead; surf; surf = surf->DrawNext)
488 {
489 DoHorizonPolygon(surf);
490 }
491 }
492
493 if (RendLev->SkyPortalsHead)
494 {
495 p_glUseProgramObjectARB(SurfZBufProgram);
496 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
497 for (surface_t* surf = RendLev->SkyPortalsHead; surf; surf = surf->DrawNext)
498 {
499 glBegin(GL_POLYGON);
500 for (int i = 0; i < surf->count; i++)
501 {
502 glVertex(surf->verts[i]);
503 }
504 glEnd();
505 }
506 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
507 }
508
509 p_glUseProgramObjectARB(ShadowsAmbientProgram);
510 for (surface_t* surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
511 {
512 float lev = float(surf->Light >> 24) / 255.0;
513 p_glUniform4fARB(ShadowsAmbientLightLoc,
514 ((surf->Light >> 16) & 255) * lev / 255.0,
515 ((surf->Light >> 8) & 255) * lev / 255.0,
516 (surf->Light & 255) * lev / 255.0, 1.0);
517 glBegin(GL_POLYGON);
518 for (int i = 0; i < surf->count; i++)
519 {
520 glVertex(surf->verts[i]);
521 }
522 glEnd();
523 }
524 unguard;
525 }
526
527
528 //==========================================================================
529 //
530 // VOpenGLDrawer::BeginShadowVolumesPass
531 //
532 //==========================================================================
533
BeginShadowVolumesPass()534 void VOpenGLDrawer::BeginShadowVolumesPass()
535 {
536 guard(VOpenGLDrawer::BeginShadowVolumesPass);
537 // Set up for shadow volume rendering.
538 glEnable(GL_STENCIL_TEST);
539 glDepthMask(GL_FALSE);
540 unguard;
541 }
542
543 //==========================================================================
544 //
545 // VOpenGLDrawer::BeginLightShadowVolumes
546 //
547 //==========================================================================
548
BeginLightShadowVolumes()549 void VOpenGLDrawer::BeginLightShadowVolumes()
550 {
551 guard(VOpenGLDrawer::BeginLightShadowVolumes);
552 // Set up for shadow volume rendering.
553 glClear(GL_STENCIL_BUFFER_BIT);
554 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
555 //glEnable(GL_POLYGON_OFFSET_FILL);
556 //glPolygonOffset(0.0f, 10.0f);
557 glDepthFunc(GL_LESS);
558
559 glDisable(GL_BLEND);
560 glDisable(GL_CULL_FACE);
561 glStencilFunc(GL_ALWAYS, 0x0, 0xff);
562 p_glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
563 p_glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);
564
565 p_glUseProgramObjectARB(SurfZBufProgram);
566 unguard;
567 }
568
569 //==========================================================================
570 //
571 // VOpenGLDrawer::RenderSurfaceShadowVolume
572 //
573 //==========================================================================
574
RenderSurfaceShadowVolume(surface_t * surf,TVec & LightPos,float Radius)575 void VOpenGLDrawer::RenderSurfaceShadowVolume(surface_t *surf, TVec& LightPos, float Radius)
576 {
577 guard(VOpenGLDrawer::RenderSurfaceShadowVolume);
578 float dist = DotProduct(LightPos, surf->plane->normal) - surf->plane->dist;
579 if (dist <= 0)
580 {
581 // Viewer is in back side or on plane
582 return;
583 }
584
585 int i;
586 TArray<TVec> v;
587 v.SetNum(surf->count);
588
589 for (int i = 0; i < surf->count; i++)
590 {
591 v[i] = Normalise(surf->verts[i] - LightPos);
592 v[i] *= M_INFINITY;
593 v[i] += LightPos;
594 }
595
596 glBegin(GL_POLYGON);
597 for (i = surf->count - 1; i >= 0; i--)
598 {
599 glVertex(v[i]);
600 }
601 glEnd();
602
603 glBegin(GL_POLYGON);
604 for (i = 0; i < surf->count; i++)
605 {
606 glVertex(surf->verts[i]);
607 }
608 glEnd();
609
610 glBegin(GL_TRIANGLE_STRIP);
611 for (i = 0; i < surf->count; i++)
612 {
613 glVertex(surf->verts[i]);
614 glVertex(v[i]);
615 }
616 glVertex(surf->verts[0]);
617 glVertex(v[0]);
618 glEnd();
619 unguard;
620 }
621
622 //==========================================================================
623 //
624 // VOpenGLDrawer::BeginLightPass
625 //
626 //==========================================================================
627
BeginLightPass(TVec & LightPos,float Radius,vuint32 Colour)628 void VOpenGLDrawer::BeginLightPass(TVec& LightPos, float Radius, vuint32 Colour)
629 {
630 guard(VOpenGLDrawer::BeginLightPass);
631 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
632 glDisable(GL_POLYGON_OFFSET_FILL);
633 glDepthFunc(GL_LEQUAL);
634
635 glStencilFunc(GL_EQUAL, 0x0, 0xff);
636 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
637
638 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
639 glEnable(GL_BLEND);
640
641 p_glUseProgramObjectARB(ShadowsLightProgram);
642 p_glUniform3fARB(ShadowsLightLightPosLoc, LightPos.x, LightPos.y, LightPos.z);
643 p_glUniform1fARB(ShadowsLightLightRadiusLoc, Radius);
644 p_glUniform3fARB(ShadowsLightLightColourLoc,
645 ((Colour >> 16) & 255) / 255.0,
646 ((Colour >> 8) & 255) / 255.0,
647 (Colour & 255) / 255.0);
648 unguard;
649 }
650
651 //==========================================================================
652 //
653 // VOpenGLDrawer::DrawSurfaceLight
654 //
655 //==========================================================================
656
DrawSurfaceLight(surface_t * Surf)657 void VOpenGLDrawer::DrawSurfaceLight(surface_t* Surf)
658 {
659 guard(VOpenGLDrawer::DrawSurfaceLight);
660 glBegin(GL_POLYGON);
661 for (int i = 0; i < Surf->count; i++)
662 {
663 p_glVertexAttrib3fvARB(ShadowsLightSurfNormalLoc, &Surf->plane->normal.x);
664 p_glVertexAttrib1fvARB(ShadowsLightSurfDistLoc, &Surf->plane->dist);
665 glVertex(Surf->verts[i]);
666 }
667 glEnd();
668 unguard;
669 }
670
671 //==========================================================================
672 //
673 // VOpenGLDrawer::DrawWorldTexturesPass
674 //
675 //==========================================================================
676
DrawWorldTexturesPass()677 void VOpenGLDrawer::DrawWorldTexturesPass()
678 {
679 guard(VOpenGLDrawer::DrawWorldTexturesPass);
680 // Stop stenciling now.
681 glDisable(GL_STENCIL_TEST);
682
683 glBlendFunc(GL_DST_COLOR, GL_ZERO);
684 glEnable(GL_BLEND);
685
686 p_glUseProgramObjectARB(ShadowsTextureProgram);
687 p_glUniform1iARB(ShadowsTextureTextureLoc, 0);
688
689 for (surface_t* surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
690 {
691 texinfo_t* tex = surf->texinfo;
692 SetTexture(tex->Tex, tex->ColourMap);
693 glBegin(GL_POLYGON);
694 for (int i = 0; i < surf->count; i++)
695 {
696 p_glVertexAttrib2fARB(ShadowsTextureTexCoordLoc,
697 (DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
698 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
699 glVertex(surf->verts[i]);
700 }
701 glEnd();
702 }
703 unguard;
704 }
705
706 //==========================================================================
707 //
708 // VOpenGLDrawer::DrawWorldFogPass
709 //
710 //==========================================================================
711
DrawWorldFogPass()712 void VOpenGLDrawer::DrawWorldFogPass()
713 {
714 guard(VOpenGLDrawer::DrawWorldFogPass);
715 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
716
717 // Draw surfaces.
718 p_glUseProgramObjectARB(ShadowsFogProgram);
719 p_glUniform1iARB(ShadowsFogFogTypeLoc, r_fog & 3);
720
721 for (surface_t* surf = RendLev->SimpleSurfsHead; surf; surf = surf->DrawNext)
722 {
723 if (!surf->Fade)
724 {
725 continue;
726 }
727
728 p_glUniform4fARB(ShadowsFogFogColourLoc,
729 ((surf->Fade >> 16) & 255) / 255.0,
730 ((surf->Fade >> 8) & 255) / 255.0,
731 (surf->Fade & 255) / 255.0, 1.0);
732 p_glUniform1fARB(ShadowsFogFogDensityLoc, surf->Fade == FADE_LIGHT ? 0.3 : r_fog_density);
733 p_glUniform1fARB(ShadowsFogFogStartLoc, surf->Fade == FADE_LIGHT ? 1.0 : r_fog_start);
734 p_glUniform1fARB(ShadowsFogFogEndLoc, surf->Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
735
736 glBegin(GL_POLYGON);
737 for (int i = 0; i < surf->count; i++)
738 {
739 glVertex(surf->verts[i]);
740 }
741 glEnd();
742 }
743 unguard;
744 }
745
746 //==========================================================================
747 //
748 // VOpenGLDrawer::EndFogPass
749 //
750 //==========================================================================
751
EndFogPass()752 void VOpenGLDrawer::EndFogPass()
753 {
754 guard(VOpenGLDrawer::EndFogPass);
755 glDisable(GL_BLEND);
756
757 // Back to normal z-buffering.
758 glDepthMask(GL_TRUE);
759 unguard;
760 }
761
762 //==========================================================================
763 //
764 // VOpenGLDrawer::DoHorizonPolygon
765 //
766 //==========================================================================
767
DoHorizonPolygon(surface_t * Surf)768 void VOpenGLDrawer::DoHorizonPolygon(surface_t* Surf)
769 {
770 guard(VOpenGLDrawer::DoHorizonPolygon);
771 float Dist = 4096.0;
772 TVec v[4];
773 if (Surf->HorizonPlane->normal.z > 0.0)
774 {
775 v[0] = Surf->verts[0];
776 v[3] = Surf->verts[3];
777 TVec HDir = -Surf->plane->normal;
778
779 TVec Dir1 = Normalise(vieworg - Surf->verts[1]);
780 TVec Dir2 = Normalise(vieworg - Surf->verts[2]);
781 float Mul1 = 1.0 / DotProduct(HDir, Dir1);
782 v[1] = Surf->verts[1] + Dir1 * Mul1 * Dist;
783 float Mul2 = 1.0 / DotProduct(HDir, Dir2);
784 v[2] = Surf->verts[2] + Dir2 * Mul2 * Dist;
785 if (v[1].z < v[0].z)
786 {
787 v[1] = Surf->verts[1] + Dir1 * Mul1 * Dist * (Surf->verts[1].z -
788 Surf->verts[0].z) / (Surf->verts[1].z - v[1].z);
789 v[2] = Surf->verts[2] + Dir2 * Mul2 * Dist * (Surf->verts[2].z -
790 Surf->verts[3].z) / (Surf->verts[2].z - v[2].z);
791 }
792 }
793 else
794 {
795 v[1] = Surf->verts[1];
796 v[2] = Surf->verts[2];
797 TVec HDir = -Surf->plane->normal;
798
799 TVec Dir1 = Normalise(vieworg - Surf->verts[0]);
800 TVec Dir2 = Normalise(vieworg - Surf->verts[3]);
801 float Mul1 = 1.0 / DotProduct(HDir, Dir1);
802 v[0] = Surf->verts[0] + Dir1 * Mul1 * Dist;
803 float Mul2 = 1.0 / DotProduct(HDir, Dir2);
804 v[3] = Surf->verts[3] + Dir2 * Mul2 * Dist;
805 if (v[1].z < v[0].z)
806 {
807 v[0] = Surf->verts[0] + Dir1 * Mul1 * Dist * (Surf->verts[1].z -
808 Surf->verts[0].z) / (v[0].z - Surf->verts[0].z);
809 v[3] = Surf->verts[3] + Dir2 * Mul2 * Dist * (Surf->verts[2].z -
810 Surf->verts[3].z) / (v[3].z - Surf->verts[3].z);
811 }
812 }
813
814 texinfo_t* Tex = Surf->texinfo;
815 SetTexture(Tex->Tex, Tex->ColourMap);
816
817 if (HaveShaders)
818 {
819 p_glUseProgramObjectARB(SurfSimpleProgram);
820 p_glUniform1iARB(SurfSimpleTextureLoc, 0);
821 p_glUniform1iARB(SurfSimpleFogTypeLoc, r_fog & 3);
822
823 p_glUniform3fvARB(SurfSimpleSAxisLoc, 1, &Tex->saxis.x);
824 p_glUniform1fARB(SurfSimpleSOffsLoc, Tex->soffs);
825 p_glUniform1fARB(SurfSimpleTexIWLoc, tex_iw);
826 p_glUniform3fvARB(SurfSimpleTAxisLoc, 1, &Tex->taxis.x);
827 p_glUniform1fARB(SurfSimpleTOffsLoc, Tex->toffs);
828 p_glUniform1fARB(SurfSimpleTexIHLoc, tex_ih);
829
830 float lev = float(Surf->Light >> 24) / 255.0;
831 p_glUniform4fARB(SurfSimpleLightLoc,
832 ((Surf->Light >> 16) & 255) * lev / 255.0,
833 ((Surf->Light >> 8) & 255) * lev / 255.0,
834 (Surf->Light & 255) * lev / 255.0, 1.0);
835 if (Surf->Fade)
836 {
837 p_glUniform1iARB(SurfSimpleFogEnabledLoc, GL_TRUE);
838 p_glUniform4fARB(SurfSimpleFogColourLoc,
839 ((Surf->Fade >> 16) & 255) / 255.0,
840 ((Surf->Fade >> 8) & 255) / 255.0,
841 (Surf->Fade & 255) / 255.0, 1.0);
842 p_glUniform1fARB(SurfSimpleFogDensityLoc, Surf->Fade == FADE_LIGHT ? 0.3 : r_fog_density);
843 p_glUniform1fARB(SurfSimpleFogStartLoc, Surf->Fade == FADE_LIGHT ? 1.0 : r_fog_start);
844 p_glUniform1fARB(SurfSimpleFogEndLoc, Surf->Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
845 }
846 else
847 {
848 p_glUniform1iARB(SurfSimpleFogEnabledLoc, GL_FALSE);
849 }
850
851 // Draw it
852 glDepthMask(GL_FALSE);
853 glBegin(GL_POLYGON);
854 for (int i = 0; i < 4; i++)
855 {
856 glVertex(v[i]);
857 }
858 glEnd();
859 glDepthMask(GL_TRUE);
860
861 // Write to the depth buffer.
862 p_glUseProgramObjectARB(SurfZBufProgram);
863 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
864 glBegin(GL_POLYGON);
865 for (int i = 0; i < Surf->count; i++)
866 {
867 glVertex(Surf->verts[i]);
868 }
869 glEnd();
870 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
871 }
872 else
873 {
874 float lev = float(Surf->Light >> 24) / 255.0;
875 glColor4f(((Surf->Light >> 16) & 255) * lev / 255.0,
876 ((Surf->Light >> 8) & 255) * lev / 255.0,
877 (Surf->Light & 255) * lev / 255.0, 1.0);
878 SetFade(Surf->Fade);
879
880 // Draw it
881 glDepthMask(GL_FALSE);
882 glBegin(GL_POLYGON);
883 for (int i = 0; i < 4; i++)
884 {
885 glTexCoord2f((DotProduct(v[i], Tex->saxis) + Tex->soffs) * tex_iw,
886 (DotProduct(v[i], Tex->taxis) + Tex->toffs) * tex_ih);
887 glVertex(v[i]);
888 }
889 glEnd();
890 glDepthMask(GL_TRUE);
891
892 // Write to the depth buffer.
893 glDisable(GL_TEXTURE_2D);
894 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
895 glBegin(GL_POLYGON);
896 for (int i = 0; i < Surf->count; i++)
897 {
898 glVertex(Surf->verts[i]);
899 }
900 glEnd();
901 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
902 glEnable(GL_TEXTURE_2D);
903 }
904 unguard;
905 }
906
907 //==========================================================================
908 //
909 // VOpenGLDrawer::DrawSkyPolygon
910 //
911 //==========================================================================
912
DrawSkyPolygon(surface_t * surf,bool bIsSkyBox,VTexture * Texture1,float offs1,VTexture * Texture2,float offs2,int CMap)913 void VOpenGLDrawer::DrawSkyPolygon(surface_t* surf, bool bIsSkyBox,
914 VTexture* Texture1, float offs1, VTexture* Texture2, float offs2,
915 int CMap)
916 {
917 guard(VOpenGLDrawer::DrawSkyPolygon);
918 int i;
919 int sidx[4];
920
921 SetFade(surf->Fade);
922 sidx[0] = 0;
923 sidx[1] = 1;
924 sidx[2] = 2;
925 sidx[3] = 3;
926 if (!bIsSkyBox)
927 {
928 if (surf->verts[1].z > 0)
929 {
930 sidx[1] = 0;
931 sidx[2] = 3;
932 }
933 else
934 {
935 sidx[0] = 1;
936 sidx[3] = 2;
937 }
938 }
939 texinfo_t *tex = surf->texinfo;
940 if (HaveShaders)
941 {
942 if (Texture2->Type != TEXTYPE_Null)
943 {
944 SetTexture(Texture1, CMap);
945 SelectTexture(1);
946 SetTexture(Texture2, CMap);
947 SelectTexture(0);
948
949 p_glUseProgramObjectARB(SurfDSkyProgram);
950 p_glUniform1iARB(SurfDSkyTextureLoc, 0);
951 p_glUniform1iARB(SurfDSkyTexture2Loc, 1);
952 p_glUniform1fARB(SurfDSkyBrightnessLoc, r_sky_bright_factor);
953
954 glBegin(GL_POLYGON);
955 for (i = 0; i < surf->count; i++)
956 {
957 p_glVertexAttrib2fARB(SurfDSkyTexCoordLoc,
958 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
959 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
960 p_glVertexAttrib2fARB(SurfDSkyTexCoord2Loc,
961 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs2) * tex_iw,
962 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
963 glVertex(surf->verts[i]);
964 }
965 glEnd();
966 }
967 else
968 {
969 SetTexture(Texture1, CMap);
970
971 p_glUseProgramObjectARB(SurfSkyProgram);
972 p_glUniform1iARB(SurfSkyTextureLoc, 0);
973 p_glUniform1fARB(SurfSkyBrightnessLoc, r_sky_bright_factor);
974
975 glBegin(GL_POLYGON);
976 for (i = 0; i < surf->count; i++)
977 {
978 p_glVertexAttrib2fARB(SurfSkyTexCoordLoc,
979 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
980 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
981 glVertex(surf->verts[i]);
982 }
983 glEnd();
984 }
985 }
986 else
987 {
988 if (HaveMultiTexture && Texture2->Type != TEXTYPE_Null)
989 {
990 SetTexture(Texture1, CMap);
991 SelectTexture(1);
992 glEnable(GL_TEXTURE_2D);
993 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
994 SetTexture(Texture2, CMap);
995 SelectTexture(0);
996
997 glColor4f(r_sky_bright_factor * 1, r_sky_bright_factor * 1, r_sky_bright_factor * 1, 1);
998 glBegin(GL_POLYGON);
999 for (i = 0; i < surf->count; i++)
1000 {
1001 MultiTexCoord(0,
1002 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
1003 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1004 MultiTexCoord(1,
1005 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs2) * tex_iw,
1006 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1007 glVertex(surf->verts[i]);
1008 }
1009 glEnd();
1010
1011 SelectTexture(1);
1012 glDisable(GL_TEXTURE_2D);
1013 SelectTexture(0);
1014 }
1015 else
1016 {
1017 SetTexture(Texture1, CMap);
1018 glBegin(GL_POLYGON);
1019 glColor4f(r_sky_bright_factor * 1, r_sky_bright_factor * 1, r_sky_bright_factor * 1, 1);
1020 for (i = 0; i < surf->count; i++)
1021 {
1022 glTexCoord2f(
1023 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs1) * tex_iw,
1024 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1025 glVertex(surf->verts[i]);
1026 }
1027 glEnd();
1028
1029 if (Texture2->Type != TEXTYPE_Null)
1030 {
1031 SetTexture(Texture2, CMap);
1032 glEnable(GL_BLEND);
1033 glBegin(GL_POLYGON);
1034 glColor4f(1, 1, 1, 1);
1035 for (i = 0; i < surf->count; i++)
1036 {
1037 glTexCoord2f(
1038 (DotProduct(surf->verts[sidx[i]], tex->saxis) + tex->soffs - offs2) * tex_iw,
1039 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1040 glVertex(surf->verts[i]);
1041 }
1042 glEnd();
1043 glDisable(GL_BLEND);
1044 }
1045 }
1046 }
1047 unguard;
1048 }
1049
1050 //==========================================================================
1051 //
1052 // VOpenGLDrawer::DrawMaskedPolygon
1053 //
1054 //==========================================================================
1055
DrawMaskedPolygon(surface_t * surf,float Alpha,bool Additive)1056 void VOpenGLDrawer::DrawMaskedPolygon(surface_t* surf, float Alpha,
1057 bool Additive)
1058 {
1059 guard(VOpenGLDrawer::DrawMaskedPolygon);
1060 texinfo_t* tex = surf->texinfo;
1061 SetTexture(tex->Tex, tex->ColourMap);
1062
1063 if (HaveShaders)
1064 {
1065 p_glUseProgramObjectARB(SurfMaskedProgram);
1066 p_glUniform1iARB(SurfMaskedTextureLoc, 0);
1067 p_glUniform1iARB(SurfMaskedFogTypeLoc, r_fog & 3);
1068
1069 if (surf->lightmap != NULL ||
1070 surf->dlightframe == r_dlightframecount)
1071 {
1072 RendLev->BuildLightMap(surf, 0);
1073 int w = (surf->extents[0] >> 4) + 1;
1074 int h = (surf->extents[1] >> 4) + 1;
1075 int size = w * h;
1076 int r = 0;
1077 int g = 0;
1078 int b = 0;
1079 for (int i = 0; i < size; i++)
1080 {
1081 r += 255 * 256 - blocklightsr[i];
1082 g += 255 * 256 - blocklightsg[i];
1083 b += 255 * 256 - blocklightsb[i];
1084 }
1085 double iscale = 1.0 / (size * 255 * 256);
1086 p_glUniform4fARB(SurfMaskedLightLoc, r * iscale, g * iscale, b * iscale, Alpha);
1087 }
1088 else
1089 {
1090 float lev = float(surf->Light >> 24) / 255.0;
1091 p_glUniform4fARB(SurfMaskedLightLoc,
1092 ((surf->Light >> 16) & 255) * lev / 255.0,
1093 ((surf->Light >> 8) & 255) * lev / 255.0,
1094 (surf->Light & 255) * lev / 255.0, 1.0);
1095 }
1096 if (surf->Fade)
1097 {
1098 p_glUniform1iARB(SurfMaskedFogEnabledLoc, GL_TRUE);
1099 p_glUniform4fARB(SurfMaskedFogColourLoc,
1100 ((surf->Fade >> 16) & 255) / 255.0,
1101 ((surf->Fade >> 8) & 255) / 255.0,
1102 (surf->Fade & 255) / 255.0, 1.0);
1103 p_glUniform1fARB(SurfMaskedFogDensityLoc, surf->Fade == FADE_LIGHT ? 0.3 : r_fog_density);
1104 p_glUniform1fARB(SurfMaskedFogStartLoc, surf->Fade == FADE_LIGHT ? 1.0 : r_fog_start);
1105 p_glUniform1fARB(SurfMaskedFogEndLoc, surf->Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
1106 }
1107 else
1108 {
1109 p_glUniform1iARB(SurfMaskedFogEnabledLoc, GL_FALSE);
1110 }
1111
1112 if (blend_sprites || Additive || Alpha < 1.0)
1113 {
1114 p_glUniform1fARB(SurfMaskedAlphaRefLoc, 0.0);
1115 glEnable(GL_BLEND);
1116 }
1117 else
1118 {
1119 p_glUniform1fARB(SurfMaskedAlphaRefLoc, 0.66);
1120 }
1121 if (Additive)
1122 {
1123 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1124 }
1125
1126 glBegin(GL_POLYGON);
1127 for (int i = 0; i < surf->count; i++)
1128 {
1129 p_glVertexAttrib2fARB(SurfMaskedTexCoordLoc,
1130 (DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
1131 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1132 glVertex(surf->verts[i]);
1133 }
1134 glEnd();
1135
1136 if (blend_sprites || Additive || Alpha < 1.0)
1137 {
1138 glDisable(GL_BLEND);
1139 }
1140 if (Additive)
1141 {
1142 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1143 }
1144 }
1145 else
1146 {
1147 glEnable(GL_ALPHA_TEST);
1148 if (blend_sprites || Additive || Alpha < 1.0)
1149 {
1150 glAlphaFunc(GL_GREATER, 0.0);
1151 glEnable(GL_BLEND);
1152 }
1153 if (Additive)
1154 {
1155 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1156 }
1157
1158 if (surf->lightmap != NULL ||
1159 surf->dlightframe == r_dlightframecount)
1160 {
1161 RendLev->BuildLightMap(surf, 0);
1162 int w = (surf->extents[0] >> 4) + 1;
1163 int h = (surf->extents[1] >> 4) + 1;
1164 int size = w * h;
1165 int r = 0;
1166 int g = 0;
1167 int b = 0;
1168 for (int i = 0; i < size; i++)
1169 {
1170 r += 255 * 256 - blocklightsr[i];
1171 g += 255 * 256 - blocklightsg[i];
1172 b += 255 * 256 - blocklightsb[i];
1173 }
1174 double iscale = 1.0 / (size * 255 * 256);
1175 glColor4f(r * iscale, g * iscale, b * iscale, Alpha);
1176 }
1177 else
1178 {
1179 float lev = float(surf->Light >> 24) / 255.0;
1180 glColor4f(((surf->Light >> 16) & 255) * lev / 255.0,
1181 ((surf->Light >> 8) & 255) * lev / 255.0,
1182 (surf->Light & 255) * lev / 255.0, Alpha);
1183 }
1184 SetFade(surf->Fade);
1185
1186 glBegin(GL_POLYGON);
1187 for (int i = 0; i < surf->count; i++)
1188 {
1189 glTexCoord2f((DotProduct(surf->verts[i], tex->saxis) + tex->soffs) * tex_iw,
1190 (DotProduct(surf->verts[i], tex->taxis) + tex->toffs) * tex_ih);
1191 glVertex(surf->verts[i]);
1192 }
1193 glEnd();
1194
1195 if (blend_sprites || Additive || Alpha < 1.0)
1196 {
1197 glAlphaFunc(GL_GREATER, 0.666);
1198 glDisable(GL_BLEND);
1199 }
1200 if (Additive)
1201 {
1202 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1203 }
1204 glDisable(GL_ALPHA_TEST);
1205 }
1206 unguard;
1207 }
1208
1209 //==========================================================================
1210 //
1211 // VOpenGLDrawer::DrawSpritePolygon
1212 //
1213 //==========================================================================
1214
DrawSpritePolygon(TVec * cv,VTexture * Tex,float Alpha,bool Additive,VTextureTranslation * Translation,int CMap,vuint32 light,vuint32 Fade,const TVec &,float,const TVec & saxis,const TVec & taxis,const TVec & texorg)1215 void VOpenGLDrawer::DrawSpritePolygon(TVec *cv, VTexture* Tex, float Alpha,
1216 bool Additive, VTextureTranslation* Translation, int CMap, vuint32 light,
1217 vuint32 Fade, const TVec&, float, const TVec& saxis, const TVec& taxis,
1218 const TVec& texorg)
1219 {
1220 guard(VOpenGLDrawer::DrawSpritePolygon);
1221 TVec texpt;
1222
1223 SetSpriteLump(Tex, Translation, CMap);
1224
1225 if (HaveShaders)
1226 {
1227 p_glUseProgramObjectARB(SurfMaskedProgram);
1228 p_glUniform1iARB(SurfMaskedTextureLoc, 0);
1229 p_glUniform1iARB(SurfMaskedFogTypeLoc, r_fog & 3);
1230
1231 p_glUniform4fARB(SurfMaskedLightLoc,
1232 ((light >> 16) & 255) / 255.0,
1233 ((light >> 8) & 255) / 255.0,
1234 (light & 255) / 255.0, Alpha);
1235 if (Fade)
1236 {
1237 p_glUniform1iARB(SurfMaskedFogEnabledLoc, GL_TRUE);
1238 p_glUniform4fARB(SurfMaskedFogColourLoc,
1239 ((Fade >> 16) & 255) / 255.0,
1240 ((Fade >> 8) & 255) / 255.0,
1241 (Fade & 255) / 255.0, 1.0);
1242 p_glUniform1fARB(SurfMaskedFogDensityLoc, Fade == FADE_LIGHT ? 0.3 : r_fog_density);
1243 p_glUniform1fARB(SurfMaskedFogStartLoc, Fade == FADE_LIGHT ? 1.0 : r_fog_start);
1244 p_glUniform1fARB(SurfMaskedFogEndLoc, Fade == FADE_LIGHT ? 1024.0 * r_fade_factor : r_fog_end);
1245 }
1246 else
1247 {
1248 p_glUniform1iARB(SurfMaskedFogEnabledLoc, GL_FALSE);
1249 }
1250
1251 if (blend_sprites || Additive || Alpha < 1.0)
1252 {
1253 p_glUniform1fARB(SurfMaskedAlphaRefLoc, 0.0);
1254 glEnable(GL_BLEND);
1255 }
1256 else
1257 {
1258 p_glUniform1fARB(SurfMaskedAlphaRefLoc, 0.66);
1259 }
1260 if (Additive)
1261 {
1262 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1263 }
1264
1265 glBegin(GL_QUADS);
1266
1267 texpt = cv[0] - texorg;
1268 p_glVertexAttrib2fARB(SurfMaskedTexCoordLoc,
1269 DotProduct(texpt, saxis) * tex_iw,
1270 DotProduct(texpt, taxis) * tex_ih);
1271 glVertex(cv[0]);
1272
1273 texpt = cv[1] - texorg;
1274 p_glVertexAttrib2fARB(SurfMaskedTexCoordLoc,
1275 DotProduct(texpt, saxis) * tex_iw,
1276 DotProduct(texpt, taxis) * tex_ih);
1277 glVertex(cv[1]);
1278
1279 texpt = cv[2] - texorg;
1280 p_glVertexAttrib2fARB(SurfMaskedTexCoordLoc,
1281 DotProduct(texpt, saxis) * tex_iw,
1282 DotProduct(texpt, taxis) * tex_ih);
1283 glVertex(cv[2]);
1284
1285 texpt = cv[3] - texorg;
1286 p_glVertexAttrib2fARB(SurfMaskedTexCoordLoc,
1287 DotProduct(texpt, saxis) * tex_iw,
1288 DotProduct(texpt, taxis) * tex_ih);
1289 glVertex(cv[3]);
1290
1291 glEnd();
1292
1293 if (blend_sprites || Additive || Alpha < 1.0)
1294 {
1295 glDisable(GL_BLEND);
1296 }
1297 if (Additive)
1298 {
1299 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1300 }
1301 }
1302 else
1303 {
1304 glEnable(GL_ALPHA_TEST);
1305 if (blend_sprites || Additive || Alpha < 1.0)
1306 {
1307 glAlphaFunc(GL_GREATER, 0.0);
1308 glEnable(GL_BLEND);
1309 }
1310 if (Additive)
1311 {
1312 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1313 }
1314
1315 vuint32 alpha = (int)(255 * Alpha);
1316 SetColour((light & 0x00ffffff) | (alpha << 24));
1317 SetFade(Fade);
1318
1319 glBegin(GL_QUADS);
1320
1321 texpt = cv[0] - texorg;
1322 glTexCoord2f(DotProduct(texpt, saxis) * tex_iw,
1323 DotProduct(texpt, taxis) * tex_ih);
1324 glVertex(cv[0]);
1325
1326 texpt = cv[1] - texorg;
1327 glTexCoord2f(DotProduct(texpt, saxis) * tex_iw,
1328 DotProduct(texpt, taxis) * tex_ih);
1329 glVertex(cv[1]);
1330
1331 texpt = cv[2] - texorg;
1332 glTexCoord2f(DotProduct(texpt, saxis) * tex_iw,
1333 DotProduct(texpt, taxis) * tex_ih);
1334 glVertex(cv[2]);
1335
1336 texpt = cv[3] - texorg;
1337 glTexCoord2f(DotProduct(texpt, saxis) * tex_iw,
1338 DotProduct(texpt, taxis) * tex_ih);
1339 glVertex(cv[3]);
1340
1341 glEnd();
1342
1343 if (blend_sprites || Additive || Alpha < 1.0)
1344 {
1345 glAlphaFunc(GL_GREATER, 0.666);
1346 glDisable(GL_BLEND);
1347 }
1348 if (Additive)
1349 {
1350 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1351 }
1352 glDisable(GL_ALPHA_TEST);
1353 }
1354 unguard;
1355 }
1356
1357 //==========================================================================
1358 //
1359 // VOpenGLDrawer::StartParticles
1360 //
1361 //==========================================================================
1362
StartParticles()1363 void VOpenGLDrawer::StartParticles()
1364 {
1365 guard(VOpenGLDrawer::StartParticles);
1366 glEnable(GL_BLEND);
1367 if (HaveShaders)
1368 {
1369 p_glUseProgramObjectARB(SurfPartProgram);
1370 glBegin(GL_QUADS);
1371 }
1372 else
1373 {
1374 glEnable(GL_ALPHA_TEST);
1375 glAlphaFunc(GL_GREATER, 0.0);
1376 if (pointparmsable)
1377 {
1378 GLfloat parms[3] = { 0.0, 1.0, 0.0 };
1379 p_glPointParameterfvEXT(GLenum(GL_DISTANCE_ATTENUATION_EXT), parms);
1380 p_glPointParameterfEXT(GLenum(GL_POINT_FADE_THRESHOLD_SIZE_EXT), 1.0);
1381 glDisable(GL_TEXTURE_2D);
1382 glEnable(GL_POINT_SMOOTH);
1383 glBegin(GL_POINTS);
1384 }
1385 else
1386 {
1387 glBindTexture(GL_TEXTURE_2D, particle_texture);
1388 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxfilter);
1389 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
1390 glBegin(GL_QUADS);
1391 }
1392 }
1393 unguard;
1394 }
1395
1396 //==========================================================================
1397 //
1398 // VOpenGLDrawer::DrawParticle
1399 //
1400 //==========================================================================
1401
DrawParticle(particle_t * p)1402 void VOpenGLDrawer::DrawParticle(particle_t *p)
1403 {
1404 guard(VOpenGLDrawer::DrawParticle);
1405 if (HaveShaders)
1406 {
1407 float r = ((p->colour >> 16) & 255) / 255.0;
1408 float g = ((p->colour >> 8) & 255) / 255.0;
1409 float b = (p->colour & 255) / 255.0;
1410 float a = ((p->colour >> 24) & 255) / 255.0;
1411 p_glVertexAttrib4fARB(SurfPartLightValLoc, r, g, b, a);
1412 p_glVertexAttrib2fARB(SurfPartTexCoordLoc, -1, -1);
1413 glVertex(p->org - viewright * p->Size + viewup * p->Size);
1414 p_glVertexAttrib4fARB(SurfPartLightValLoc, r, g, b, a);
1415 p_glVertexAttrib2fARB(SurfPartTexCoordLoc, 1, -1);
1416 glVertex(p->org + viewright * p->Size + viewup * p->Size);
1417 p_glVertexAttrib4fARB(SurfPartLightValLoc, r, g, b, a);
1418 p_glVertexAttrib2fARB(SurfPartTexCoordLoc, 1, 1);
1419 glVertex(p->org + viewright * p->Size - viewup * p->Size);
1420 p_glVertexAttrib4fARB(SurfPartLightValLoc, r, g, b, a);
1421 p_glVertexAttrib2fARB(SurfPartTexCoordLoc, -1, 1);
1422 glVertex(p->org - viewright * p->Size - viewup * p->Size);
1423 }
1424 else
1425 {
1426 SetColour(p->colour);
1427 if (pointparmsable)
1428 {
1429 glVertex(p->org);
1430 }
1431 else
1432 {
1433 glTexCoord2f(0, 0); glVertex(p->org - viewright * p->Size + viewup * p->Size);
1434 glTexCoord2f(1, 0); glVertex(p->org + viewright * p->Size + viewup * p->Size);
1435 glTexCoord2f(1, 1); glVertex(p->org + viewright * p->Size - viewup * p->Size);
1436 glTexCoord2f(0, 1); glVertex(p->org - viewright * p->Size - viewup * p->Size);
1437 }
1438 }
1439 unguard;
1440 }
1441
1442 //==========================================================================
1443 //
1444 // VOpenGLDrawer::EndParticles
1445 //
1446 //==========================================================================
1447
EndParticles()1448 void VOpenGLDrawer::EndParticles()
1449 {
1450 guard(VOpenGLDrawer::EndParticles);
1451 glEnd();
1452 if (!HaveShaders)
1453 {
1454 glDisable(GL_ALPHA_TEST);
1455 glAlphaFunc(GL_GREATER, 0.666);
1456 if (pointparmsable)
1457 {
1458 glDisable(GL_POINT_SMOOTH);
1459 glEnable(GL_TEXTURE_2D);
1460 }
1461 }
1462 glDisable(GL_BLEND);
1463 unguard;
1464 }
1465
1466 //==========================================================================
1467 //
1468 // VOpenGLDrawer::StartPortal
1469 //
1470 //==========================================================================
1471
StartPortal(VPortal * Portal,bool UseStencil)1472 bool VOpenGLDrawer::StartPortal(VPortal* Portal, bool UseStencil)
1473 {
1474 guard(VOpenGLDrawer::StartPortal);
1475 if (UseStencil)
1476 {
1477 // Doesn't work for now.
1478 if (RendLev->NeedsInfiniteFarClip)
1479 {
1480 return false;
1481 }
1482
1483 // Disable drawing
1484 if (HaveShaders)
1485 {
1486 p_glUseProgramObjectARB(SurfZBufProgram);
1487 }
1488 else
1489 {
1490 glDisable(GL_TEXTURE_2D);
1491 }
1492 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1493 glDepthMask(GL_FALSE);
1494
1495 // Set up stencil test.
1496 if (!RendLev->PortalDepth)
1497 {
1498 glEnable(GL_STENCIL_TEST);
1499 }
1500 glStencilFunc(GL_EQUAL, RendLev->PortalDepth, ~0);
1501 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
1502
1503 // Mark the portal area.
1504 DrawPortalArea(Portal);
1505
1506 // Set up stencil test for portal
1507 glStencilFunc(GL_EQUAL, RendLev->PortalDepth + 1, ~0);
1508 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1509
1510 if (Portal->NeedsDepthBuffer())
1511 {
1512 glDepthMask(GL_TRUE);
1513 // Clear depth buffer
1514 glDepthRange(1, 1);
1515 glDepthFunc(GL_ALWAYS);
1516 DrawPortalArea(Portal);
1517 glDepthFunc(GL_LEQUAL);
1518 glDepthRange(0, 1);
1519 }
1520 else
1521 {
1522 glDepthMask(GL_FALSE);
1523 glDisable(GL_DEPTH_TEST);
1524 }
1525
1526 // Enable drawing.
1527 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1528 if (!HaveShaders)
1529 {
1530 glEnable(GL_TEXTURE_2D);
1531 }
1532
1533 RendLev->PortalDepth++;
1534 }
1535 else
1536 {
1537 if (!Portal->NeedsDepthBuffer())
1538 {
1539 glDepthMask(GL_FALSE);
1540 glDisable(GL_DEPTH_TEST);
1541 }
1542 }
1543 return true;
1544 unguard;
1545 }
1546
1547 //==========================================================================
1548 //
1549 // VOpenGLDrawer::DrawPortalArea
1550 //
1551 //==========================================================================
1552
DrawPortalArea(VPortal * Portal)1553 void VOpenGLDrawer::DrawPortalArea(VPortal* Portal)
1554 {
1555 guard(VOpenGLDrawer::DrawPortalArea);
1556 for (int i = 0; i < Portal->Surfs.Num(); i++)
1557 {
1558 const surface_t* Surf = Portal->Surfs[i];
1559 glBegin(GL_POLYGON);
1560 for (int i = 0; i < Surf->count; i++)
1561 {
1562 glVertex(Surf->verts[i]);
1563 }
1564 glEnd();
1565 }
1566 unguard;
1567 }
1568
1569 //==========================================================================
1570 //
1571 // VSoftwareDrawer::EndPortal
1572 //
1573 //==========================================================================
1574
EndPortal(VPortal * Portal,bool UseStencil)1575 void VOpenGLDrawer::EndPortal(VPortal* Portal, bool UseStencil)
1576 {
1577 guard(VOpenGLDrawer::EndPortal);
1578 if (HaveShaders)
1579 {
1580 p_glUseProgramObjectARB(SurfZBufProgram);
1581 }
1582 else
1583 {
1584 glDisable(GL_TEXTURE_2D);
1585 }
1586 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1587
1588 if (UseStencil)
1589 {
1590 if (Portal->NeedsDepthBuffer())
1591 {
1592 // Clear depth buffer
1593 glDepthRange(1, 1);
1594 glDepthFunc(GL_ALWAYS);
1595 DrawPortalArea(Portal);
1596 glDepthFunc(GL_LEQUAL);
1597 glDepthRange(0, 1);
1598 }
1599 else
1600 {
1601 glDepthMask(GL_TRUE);
1602 glEnable(GL_DEPTH_TEST);
1603 }
1604
1605 glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
1606
1607 // Draw proper z-buffer for the portal area.
1608 glDepthFunc(GL_ALWAYS);
1609 DrawPortalArea(Portal);
1610 glDepthFunc(GL_LEQUAL);
1611
1612 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1613
1614 RendLev->PortalDepth--;
1615 glStencilFunc(GL_EQUAL, RendLev->PortalDepth, ~0);
1616 if (!RendLev->PortalDepth)
1617 {
1618 glDisable(GL_STENCIL_TEST);
1619 }
1620 }
1621 else
1622 {
1623 if (Portal->NeedsDepthBuffer())
1624 {
1625 // Clear depth buffer
1626 glClear(GL_DEPTH_BUFFER_BIT);
1627 }
1628 else
1629 {
1630 glDepthMask(GL_TRUE);
1631 glEnable(GL_DEPTH_TEST);
1632 }
1633
1634 // Draw proper z-buffer for the portal area.
1635 DrawPortalArea(Portal);
1636 }
1637
1638 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1639 if (!HaveShaders)
1640 {
1641 glEnable(GL_TEXTURE_2D);
1642 }
1643 unguard;
1644 }
1645