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