1 /*
2 Copyright (C) 2009 COR Entertainment
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "r_local.h"
26 
27 #define EXPLOSION 1
28 #define PAIN 2
29 
30 extern int KillFlags;
31 extern float v_blend[4];
32 extern void R_TransformVectorToScreen( refdef_t *rd, vec3_t in, vec2_t out );
33 void R_DrawBloodEffect (void);
34 
35 image_t *r_framebuffer;
36 image_t *r_distortwave;
37 image_t *r_droplets;
38 image_t	*r_blooddroplets;
39 image_t	*r_blooddroplets_nm;
40 
41 vec3_t r_explosionOrigin;
42 int r_drawing_fbeffect;
43 int	r_fbFxType;
44 float r_fbeffectTime;
45 int frames;
46 
47 extern  cvar_t	*cl_raindist;
48 
R_GLSLDistortion(void)49 void R_GLSLDistortion(void)
50 {
51 	vec2_t fxScreenPos;
52 	int offsetX, offsetY;
53 	vec3_t	vec;
54 	float	dot, r_fbeffectLen;
55 	vec3_t	forward, mins, maxs;
56 	trace_t r_trace;
57 	float hScissor, wScissor;
58 
59 	if(!gl_glsl_shaders->integer || vid.width > 2048 || !gl_state.glsl_shaders)
60 		return;
61 
62 	if(r_fbFxType == EXPLOSION)
63 	{
64 		//is it in our view?
65 		AngleVectors (r_newrefdef.viewangles, forward, NULL, NULL);
66 		VectorSubtract (r_explosionOrigin, r_newrefdef.vieworg, vec);
67 		VectorNormalize (vec);
68 		dot = DotProduct (vec, forward);
69 		if (dot <= 0.3)
70 			r_drawing_fbeffect = false;
71 
72 		//is anything blocking it from view?
73 		VectorSet(mins, 0, 0, 0);
74 		VectorSet(maxs,	0, 0, 0);
75 
76 		r_trace = CM_BoxTrace(r_origin, r_explosionOrigin, maxs, mins, r_worldmodel->firstnode, MASK_VISIBILILITY);
77 		if (r_trace.fraction != 1.0)
78 			r_drawing_fbeffect = false;
79 	}
80 
81 	//if not doing stuff, return
82 	if(!r_drawing_fbeffect)
83 		return;
84 
85 	frames++;
86 
87 	if(r_fbFxType == PAIN)
88 	{
89 		r_fbeffectLen = 0.1;
90 		R_DrawBloodEffect();
91 	}
92 	else
93 		r_fbeffectLen = 0.2;
94 
95 	//set up full screen workspace
96 	qglViewport( 0, 0, viddef.width, viddef.height );
97 	qglDisable( GL_DEPTH_TEST );
98 	qglMatrixMode( GL_PROJECTION );
99     qglLoadIdentity ();
100 	qglOrtho(0, viddef.width, viddef.height, 0, -10, 100);
101 	qglMatrixMode( GL_MODELVIEW );
102     qglLoadIdentity ();
103 	qglDisable(GL_CULL_FACE);
104 
105 	qglDisable( GL_BLEND );
106 	qglEnable( GL_TEXTURE_2D );
107 
108 	qglViewport(0,0,FB_texture_width,FB_texture_height);
109 
110 	//we need to grab the frame buffer
111 	qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum);
112 	qglCopyTexSubImage2D(GL_TEXTURE_2D, 0,
113 				0, 0, 0, 0, FB_texture_width, FB_texture_height);
114 
115 	qglViewport(0,0,viddef.width, viddef.height);
116 
117 	//render quad on screen
118 
119 	offsetY = viddef.height - FB_texture_height;
120 	offsetX = viddef.width - FB_texture_width;
121 
122 	hScissor = (float)viddef.height/(float)FB_texture_height;
123 	wScissor = (float)viddef.width/(float)FB_texture_width;
124 
125 	qglEnableClientState (GL_VERTEX_ARRAY);
126 	qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
127 
128 	qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
129 	qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
130 	qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
131 
132 	VA_SetElem2(vert_array[0],0, viddef.height);
133 	VA_SetElem2(vert_array[1],viddef.width-offsetX, viddef.height);
134 	VA_SetElem2(vert_array[2],viddef.width-offsetX, offsetY);
135 	VA_SetElem2(vert_array[3],0, offsetY);
136 
137 	VA_SetElem2(tex_array[0],r_framebuffer->sl, r_framebuffer->tl);
138 	VA_SetElem2(tex_array[1],r_framebuffer->sh, r_framebuffer->tl);
139 	VA_SetElem2(tex_array[2],r_framebuffer->sh, r_framebuffer->th);
140 	VA_SetElem2(tex_array[3],r_framebuffer->sl, r_framebuffer->th);
141 
142 	if(r_fbFxType == EXPLOSION)
143 	{
144 		//create a distortion wave effect at point of explosion
145 		glUseProgramObjectARB( g_fbprogramObj );
146 
147 		qglActiveTextureARB(GL_TEXTURE1);
148 		qglBindTexture (GL_TEXTURE_2D,r_framebuffer->texnum);
149 		glUniform1iARB( g_location_framebuffTex, 1);
150 		KillFlags |= KILL_TMU1_POINTER;
151 
152 		qglActiveTextureARB(GL_TEXTURE0);
153 
154 		if(r_distortwave)
155 			qglBindTexture(GL_TEXTURE_2D, r_distortwave->texnum);
156 		glUniform1iARB( g_location_distortTex, 0);
157 		KillFlags |= KILL_TMU0_POINTER;
158 
159 		glUniform2fARB( g_location_dParams, wScissor, hScissor);
160 
161 		fxScreenPos[0] = fxScreenPos[1] = 0;
162 
163 		//get position of focal point of warp
164 		R_TransformVectorToScreen(&r_newrefdef, r_explosionOrigin, fxScreenPos);
165 
166 		fxScreenPos[0] /= viddef.width;
167 		fxScreenPos[1] /= viddef.height;
168 
169 		fxScreenPos[0] -= (0.5 + (abs((float)offsetX)/1024.0)*0.25);
170 		fxScreenPos[1] -= (0.5 + (abs((float)offsetY)/1024.0)*0.15);
171 
172 		fxScreenPos[0] -= (float)frames*.001;
173 		fxScreenPos[1] -= (float)frames*.001;
174 		glUniform2fARB( g_location_fxPos, fxScreenPos[0], fxScreenPos[1]);
175 
176 		R_DrawVarrays(GL_QUADS, 0, 4);
177 
178 		glUseProgramObjectARB( 0 );
179 	}
180 	else
181 	{
182 		//do a radial blur
183 		glUseProgramObjectARB( g_rblurprogramObj );
184 
185 		qglActiveTextureARB(GL_TEXTURE0);
186 		qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum);
187 		KillFlags |= KILL_TMU0_POINTER;
188 
189 		glUniform1iARB( g_location_rsource, 0);
190 
191 		glUniform3fARB( g_location_rscale, 1.0, wScissor, hScissor);
192 
193 		glUniform3fARB( g_location_rparams, viddef.width/2.0, viddef.height/2.0, 0.25);
194 
195 		R_DrawVarrays(GL_QUADS, 0, 4);
196 
197 		glUseProgramObjectARB( 0 );
198 	}
199 
200 	R_KillVArrays();
201 
202 	if(rs_realtime > r_fbeffectTime+r_fbeffectLen)
203 	{
204 		frames = 0;
205 		r_drawing_fbeffect = false; //done effect
206 	}
207 
208 	return;
209 }
210 
R_GLSLWaterDroplets(void)211 void R_GLSLWaterDroplets(void)
212 {
213 	int offsetX, offsetY;
214 	float hScissor, wScissor;
215 	trace_t tr;
216 	vec3_t end;
217 	static float r_drTime;
218 
219 	if(!(r_weather == 1) || !cl_raindist->integer || !gl_glsl_shaders->integer || vid.width > 2048 || !gl_state.glsl_shaders)
220 		return;
221 
222 	VectorCopy(r_newrefdef.vieworg, end);
223 	end[2] += 8192;
224 
225 	// trace up looking for sky
226 	tr = CM_BoxTrace(r_newrefdef.vieworg, end, vec3_origin, vec3_origin, 0, MASK_SHOT);
227 
228 	if((tr.surface->flags & SURF_SKY))
229 	{
230 		r_drTime = rs_realtime;
231 	}
232 
233 	if(rs_realtime - r_drTime > 0.5)
234 		return; //been out of the rain long enough for effect to dry up
235 
236 	//set up full screen workspace
237 	qglViewport( 0, 0, viddef.width, viddef.height );
238 	qglDisable( GL_DEPTH_TEST );
239 	qglMatrixMode( GL_PROJECTION );
240     qglLoadIdentity ();
241 	qglOrtho(0, viddef.width, viddef.height, 0, -10, 100);
242 	qglMatrixMode( GL_MODELVIEW );
243     qglLoadIdentity ();
244 	qglDisable(GL_CULL_FACE);
245 
246 	qglDisable( GL_BLEND );
247 	qglEnable( GL_TEXTURE_2D );
248 
249 	qglViewport(0,0,FB_texture_width,FB_texture_height);
250 
251 	//we need to grab the frame buffer
252 	qglBindTexture(GL_TEXTURE_2D, r_framebuffer->texnum);
253 	qglCopyTexSubImage2D(GL_TEXTURE_2D, 0,
254 				0, 0, 0, 0, FB_texture_width, FB_texture_height);
255 
256 	qglViewport(0,0,viddef.width, viddef.height);
257 
258 	//render quad on screen
259 
260 	offsetY = viddef.height - FB_texture_height;
261 	offsetX = viddef.width - FB_texture_width;
262 
263 	hScissor = (float)viddef.height/(float)FB_texture_height;
264 	wScissor = (float)viddef.width/(float)FB_texture_width;
265 
266 	qglEnableClientState (GL_VERTEX_ARRAY);
267 	qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
268 
269 	qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
270 	qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
271 	qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
272 
273 	VA_SetElem2(vert_array[0],0, viddef.height);
274 	VA_SetElem2(vert_array[1],viddef.width-offsetX, viddef.height);
275 	VA_SetElem2(vert_array[2],viddef.width-offsetX, offsetY);
276 	VA_SetElem2(vert_array[3],0, offsetY);
277 
278 	VA_SetElem2(tex_array[0],r_framebuffer->sl, r_framebuffer->tl);
279 	VA_SetElem2(tex_array[1],r_framebuffer->sh, r_framebuffer->tl);
280 	VA_SetElem2(tex_array[2],r_framebuffer->sh, r_framebuffer->th);
281 	VA_SetElem2(tex_array[3],r_framebuffer->sl, r_framebuffer->th);
282 
283 	//draw water droplets
284 	glUseProgramObjectARB( g_dropletsprogramObj ); //this program will have two or three of the normalmap scrolling over the buffer
285 
286 	qglActiveTextureARB(GL_TEXTURE1);
287 	qglBindTexture (GL_TEXTURE_2D,r_framebuffer->texnum);
288 	glUniform1iARB( g_location_drSource, 1);
289 	KillFlags |= KILL_TMU1_POINTER;
290 
291 	qglActiveTextureARB(GL_TEXTURE0);
292 	qglBindTexture(GL_TEXTURE_2D, r_droplets->texnum);
293 	glUniform1iARB( g_location_drTex, 0);
294 	KillFlags |= KILL_TMU0_POINTER;
295 
296 	glUniform1fARB( g_location_drTime, rs_realtime);
297 
298 	glUniform2fARB( g_location_drParams, wScissor, hScissor);
299 
300 	R_DrawVarrays(GL_QUADS, 0, 4);
301 
302 	glUseProgramObjectARB( 0 );
303 
304 	R_KillVArrays();
305 
306 	return;
307 }
308 
309 
310 /*
311 ==============
312 R_ShadowBlend
313 Draws projection shadow(s)
314 from stenciled volume
315 ==============
316 */
317 image_t *r_colorbuffer;
318 
R_ShadowBlend(float alpha)319 void R_ShadowBlend(float alpha)
320 {
321 	if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
322 		return;
323 
324 	qglMatrixMode(GL_PROJECTION);
325 	qglPushMatrix();
326 	qglLoadIdentity();
327 	qglOrtho(0, 1, 1, 0, -99999, 99999);
328 
329 	qglMatrixMode(GL_MODELVIEW);
330 	qglPushMatrix();
331 	qglLoadIdentity();
332 
333 	if(gl_state.fbo && gl_state.hasFBOblit && atoi(&gl_config.version_string[0]) >= 3.0)
334 	{
335 		alpha/=1.5; //necessary because we are blending two quads
336 
337 		//blit the stencil mask from main buffer
338 		qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
339 		qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboId[2]);
340 
341 		qglBlitFramebufferEXT(0, 0, vid.width, vid.height, 0, 0, viddef.width, viddef.height,
342 			GL_STENCIL_BUFFER_BIT, GL_NEAREST);
343 
344 		qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
345 		qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
346 
347 		//render offscreen
348 		qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]);
349 
350 		qglDisable(GL_STENCIL_TEST);
351 		GLSTATE_DISABLE_ALPHATEST
352 		qglEnable( GL_BLEND );
353 		qglDisable (GL_DEPTH_TEST);
354 		qglDisable (GL_TEXTURE_2D);
355 
356 		qglColor4f (1,1,1, 1);
357 
358 		qglBegin(GL_TRIANGLES);
359 		qglVertex2f(-5, -5);
360 		qglVertex2f(10, -5);
361 		qglVertex2f(-5, 10);
362 		qglEnd();
363 	}
364 
365 	qglColor4f (0,0,0, alpha);
366 
367 	GLSTATE_DISABLE_ALPHATEST
368 	qglEnable( GL_BLEND );
369 	qglDisable (GL_DEPTH_TEST);
370 	qglDisable (GL_TEXTURE_2D);
371 
372 	qglEnable(GL_STENCIL_TEST);
373 	qglStencilFunc( GL_NOTEQUAL, 0, 0xFF);
374 	qglStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
375 
376 	qglBegin(GL_TRIANGLES);
377 	qglVertex2f(-5, -5);
378 	qglVertex2f(10, -5);
379 	qglVertex2f(-5, 10);
380 	qglEnd();
381 
382 	if(gl_state.fbo && gl_state.hasFBOblit && atoi(&gl_config.version_string[0]) >= 3.0)
383 	{
384 		qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
385 
386 		//revert settings
387 		qglMatrixMode( GL_PROJECTION );
388 		qglLoadIdentity ();
389 		qglOrtho(0, vid.width, vid.height, 0, -10, 100);
390 		qglDisable(GL_CULL_FACE);
391 
392 		qglEnable( GL_BLEND );
393 		qglEnable( GL_TEXTURE_2D );
394 
395 		qglBlendFunc (GL_ZERO, GL_SRC_COLOR);
396 		qglDisable (GL_DEPTH_TEST);
397 		qglDisable(GL_STENCIL_TEST);
398 
399 		qglColor4f (1,1,1,1);
400 
401 		//render quad on screen	into FBO
402 		//and blur it vertically
403 
404 		glUseProgramObjectARB( g_blurprogramObj );
405 
406 		qglActiveTextureARB(GL_TEXTURE0);
407 		qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum);
408 
409 		glUniform1iARB( g_location_source, 0);
410 
411 		glUniform2fARB( g_location_scale, 4.0/vid.width, 2.0/vid.height);
412 
413 		qglEnableClientState (GL_VERTEX_ARRAY);
414 		qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
415 
416 		qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
417 		qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
418 		qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
419 
420 		VA_SetElem2(vert_array[0],0, vid.height);
421 		VA_SetElem2(vert_array[1],vid.width, vid.height);
422 		VA_SetElem2(vert_array[2],vid.width, 0);
423 		VA_SetElem2(vert_array[3],0, 0);
424 
425 		VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl);
426 		VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl);
427 		VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th);
428 		VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th);
429 
430 		R_DrawVarrays(GL_QUADS, 0, 4);
431 
432 		//now blur horizontally
433 
434 		glUniform1iARB( g_location_source, 0);
435 
436 		glUniform2fARB( g_location_scale, 2.0/vid.width, 4.0/vid.height);
437 
438 		qglEnableClientState (GL_VERTEX_ARRAY);
439 		qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
440 
441 		qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
442 		qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
443 		qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
444 
445 		VA_SetElem2(vert_array[0],0, vid.height);
446 		VA_SetElem2(vert_array[1],vid.width, vid.height);
447 		VA_SetElem2(vert_array[2],vid.width, 0);
448 		VA_SetElem2(vert_array[3],0, 0);
449 
450 		VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl);
451 		VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl);
452 		VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th);
453 		VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th);
454 
455 		R_DrawVarrays(GL_QUADS, 0, 4);
456 
457 		R_KillVArrays();
458 
459 		glUseProgramObjectARB(0);
460 	}
461 
462 	//revert settings
463 	qglMatrixMode(GL_PROJECTION);
464 	qglPopMatrix();
465 	qglMatrixMode(GL_MODELVIEW);
466 	qglPopMatrix();
467 
468 	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
469 	qglDisable ( GL_BLEND );
470 	qglEnable (GL_TEXTURE_2D);
471 	qglEnable (GL_DEPTH_TEST);
472 	qglDisable(GL_STENCIL_TEST);
473 	qglEnable(GL_CULL_FACE);
474 
475 	qglColor4f(1,1,1,1);
476 }
477 
478 /*
479 =================
480 R_FB_InitTextures
481 =================
482 */
483 
R_FB_InitTextures(void)484 void R_FB_InitTextures( void )
485 {
486 	byte	*data;
487 	int		size, x, y;
488 	byte	nullpic[16][16][4];
489 
490 	//
491 	// blank texture
492 	//
493 	for (x = 0 ; x < 16 ; x++)
494 	{
495 		for (y = 0 ; y < 16 ; y++)
496 		{
497 			nullpic[y][x][0] = 255;
498 			nullpic[y][x][1] = 255;
499 			nullpic[y][x][2] = 255;
500 			nullpic[y][x][3] = 255;
501 		}
502 	}
503 
504 	//find closer power of 2 to screen size
505 	for (FB_texture_width = 1;FB_texture_width < viddef.width;FB_texture_width *= 2);
506 	for (FB_texture_height = 1;FB_texture_height < viddef.height;FB_texture_height *= 2);
507 
508 	//limit to 2048x2048 - anything larger is generally going to cause problems, and AA doesn't support res higher
509 	if(FB_texture_width > 2048)
510 		FB_texture_width = 2048;
511 	if(FB_texture_height > 2048)
512 		FB_texture_height = 2048;
513 
514 	//init the framebuffer texture
515 	size = FB_texture_width * FB_texture_height * 4;
516 	data = malloc( size );
517 	memset( data, 255, size );
518 	r_framebuffer = GL_LoadPic( "***r_framebuffer***", (byte *)data, FB_texture_width, FB_texture_height, it_pic, 3 );
519 	free ( data );
520 
521 	//init the various FBO textures
522 	size = FB_texture_width * FB_texture_height * 4;
523 	data = malloc( size );
524 	memset( data, 255, size );
525 	r_colorbuffer = GL_LoadPic( "***r_colorbuffer***", (byte *)data, FB_texture_width, FB_texture_height, it_pic, 3 );
526 	free ( data );
527 
528 	//init the distortion textures
529 	r_distortwave = GL_FindImage("gfx/distortwave.jpg", it_pic);
530 	if (!r_distortwave)
531 		r_distortwave = GL_LoadPic ("***r_distortwave***", (byte *)nullpic, 16, 16, it_pic, 32);
532 	r_droplets = GL_FindImage("gfx/droplets.jpg", it_pic);
533 	if (!r_droplets)
534 		r_droplets = GL_LoadPic ("***r_droplets***", (byte *)nullpic, 16, 16, it_pic, 32);
535 
536 	//init gore/blood textures
537 	r_blooddroplets = GL_FindImage("gfx/blooddrops.jpg", it_pic);
538 	if (!r_blooddroplets)
539 		r_blooddroplets = GL_LoadPic ("***r_blooddroplets***", (byte *)nullpic, 16, 16, it_pic, 32);
540 	r_blooddroplets_nm = GL_FindImage("gfx/blooddrops_nm.jpg", it_pic);
541 	if (!r_blooddroplets_nm)
542 		r_blooddroplets_nm = GL_LoadPic ("***r_blooddroplets_nm***", (byte *)nullpic, 16, 16, it_pic, 32);
543 }
544 
545 extern int vehicle_hud;
546 extern cvar_t *cl_vehicle_huds;
R_DrawVehicleHUD(void)547 void R_DrawVehicleHUD (void)
548 {
549 	image_t *gl = NULL;
550 	rscript_t *rs = NULL;
551 	float	alpha;
552 	rs_stage_t *stage;
553 	char shortname[MAX_QPATH];
554 
555 	//draw image over screen
556 	if(!cl_vehicle_huds->integer)
557 		return;
558 
559 	switch(vehicle_hud)
560 	{
561 		case 1:
562 			gl = R_RegisterPic ("hud_bomber");
563 			break;
564 		case 2:
565 			gl = R_RegisterPic ("hud_strafer");
566 			break;
567 		case 3:
568 			gl = R_RegisterPic ("hud_hover");
569 			break;
570 		case 0:
571 		default:
572 			break;
573 	}
574 
575 
576 	if (!gl)
577 	{
578 		return;
579 	}
580 
581 	GL_TexEnv(GL_MODULATE);
582 	qglEnable (GL_BLEND);
583 	qglBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
584 
585 	qglActiveTextureARB(GL_TEXTURE0);
586 	qglBindTexture(GL_TEXTURE_2D, gl->texnum);
587 
588 	qglEnableClientState (GL_VERTEX_ARRAY);
589 	qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
590 
591 	qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
592 	qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
593 	qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
594 
595 	VA_SetElem2(vert_array[0],0, 0);
596 	VA_SetElem2(vert_array[1],vid.width, 0);
597 	VA_SetElem2(vert_array[2],vid.width, vid.height);
598 	VA_SetElem2(vert_array[3],0, vid.height);
599 
600 	VA_SetElem2(tex_array[0],gl->sl, gl->tl);
601 	VA_SetElem2(tex_array[1],gl->sh, gl->tl);
602 	VA_SetElem2(tex_array[2],gl->sh, gl->th);
603 	VA_SetElem2(tex_array[3],gl->sl, gl->th);
604 
605 	qglMatrixMode( GL_PROJECTION );
606 	qglLoadIdentity ();
607 	qglOrtho(0, viddef.width, viddef.height, 0, -10, 100);
608 	qglMatrixMode( GL_MODELVIEW );
609 	qglLoadIdentity ();
610 
611 	R_DrawVarrays(GL_QUADS, 0, 4);
612 
613 	COM_StripExtension ( gl->name, shortname );
614 
615 	rs = gl->script;
616 
617 	if(r_shaders->integer && rs)
618 	{
619 		RS_ReadyScript(rs);
620 
621 		stage=rs->stage;
622 		while (stage)
623 		{
624 			//change to use shader def
625 			qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
626 
627 			alpha=1.0f;
628 			if (stage->alphashift.min || stage->alphashift.speed)
629 			{
630 				if (!stage->alphashift.speed && stage->alphashift.min > 0)
631 				{
632 					alpha=stage->alphashift.min;
633 				}
634 				else if (stage->alphashift.speed)
635 				{
636 					alpha=sin(rs_realtime * stage->alphashift.speed);
637 					alpha=(alpha+1)*0.5f;
638 					if (alpha > stage->alphashift.max) alpha=stage->alphashift.max;
639 					if (alpha < stage->alphashift.min) alpha=stage->alphashift.min;
640 				}
641 			}
642 
643 			qglEnableClientState (GL_VERTEX_ARRAY);
644 			qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
645 
646 			qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
647 			qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
648 			qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
649 
650 			VA_SetElem2(vert_array[0],0, 0);
651 			VA_SetElem2(vert_array[1],vid.width, 0);
652 			VA_SetElem2(vert_array[2],vid.width, vid.height);
653 			VA_SetElem2(vert_array[3],0, vid.height);
654 
655 			qglColor4f(1,1,1, alpha);
656 			VA_SetElem4(col_array[0], 1,1,1, alpha);
657 			VA_SetElem4(col_array[1], 1,1,1, alpha);
658 			VA_SetElem4(col_array[2], 1,1,1, alpha);
659 			VA_SetElem4(col_array[3], 1,1,1, alpha);
660 
661 			if (stage->anim_count)
662 				GL_Bind(RS_Animate(stage));
663 			else
664 				GL_Bind (stage->texture->texnum);
665 
666 			VA_SetElem2(tex_array[0],gl->sl, gl->tl);
667 			VA_SetElem2(tex_array[1],gl->sh, gl->tl);
668 			VA_SetElem2(tex_array[2],gl->sh, gl->th);
669 			VA_SetElem2(tex_array[3],gl->sl, gl->th);
670 
671 			qglMatrixMode( GL_PROJECTION );
672 			qglLoadIdentity ();
673 			qglOrtho(0, viddef.width, viddef.height, 0, -10, 100);
674 			qglMatrixMode( GL_MODELVIEW );
675 			qglLoadIdentity ();
676 
677 			R_DrawVarrays(GL_QUADS, 0, 4);
678 
679 			stage=stage->next;
680 		}
681 	}
682 	qglColor4f(1,1,1,1);
683 	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
684 	qglDisable (GL_BLEND);
685 	GL_TexEnv(GL_REPLACE);
686 
687 	R_KillVArrays();
688 }
689 
R_DrawBloodEffect(void)690 void R_DrawBloodEffect (void)
691 {
692 	image_t *gl = NULL;
693 
694 	gl = R_RegisterPic ("blood_ring");
695 
696 	if (!gl)
697 	{
698 		return;
699 	}
700 
701 	qglEnable (GL_BLEND);
702 
703 	qglActiveTextureARB(GL_TEXTURE0);
704 	qglBindTexture(GL_TEXTURE_2D, gl->texnum);
705 
706 	qglEnableClientState (GL_VERTEX_ARRAY);
707 	qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
708 
709 	qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
710 	qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
711 	qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
712 
713 	VA_SetElem2(vert_array[0],0, 0);
714 	VA_SetElem2(vert_array[1],vid.width, 0);
715 	VA_SetElem2(vert_array[2],vid.width, vid.height);
716 	VA_SetElem2(vert_array[3],0, vid.height);
717 
718 	VA_SetElem2(tex_array[0],gl->sl, gl->tl);
719 	VA_SetElem2(tex_array[1],gl->sh, gl->tl);
720 	VA_SetElem2(tex_array[2],gl->sh, gl->th);
721 	VA_SetElem2(tex_array[3],gl->sl, gl->th);
722 
723 	qglMatrixMode( GL_PROJECTION );
724     qglLoadIdentity ();
725 	qglOrtho(0, viddef.width, viddef.height, 0, -10, 100);
726 	qglMatrixMode( GL_MODELVIEW );
727     qglLoadIdentity ();
728 
729 	R_DrawVarrays(GL_QUADS, 0, 4);
730 
731 	qglDisable (GL_BLEND);
732 
733 	R_KillVArrays();
734 }
735 
736 extern void PART_RenderSunFlare(image_t * tex, float offset, float size, float r,
737                       float g, float b, float alpha);
738 extern void R_DrawShadowMapWorld (qboolean forEnt, vec3_t origin);
739 extern void R_DrawVegetationCasters( qboolean forShadows );
740 extern float sun_alpha;
741 extern void MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
R_GLSLGodRays(void)742 void R_GLSLGodRays(void)
743 {
744 	float size, screenaspect;
745 	vec2_t fxScreenPos;
746 	vec3_t origin = {0, 0, 0};
747 
748 	if(!r_godrays->integer || !r_drawsun->integer)
749 		return;
750 
751 	 if (!draw_sun || sun_alpha <= 0)
752 		return;
753 
754 	//switch to fbo
755 	qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[2]); //need color buffer
756 
757 	qglDisable( GL_DEPTH_TEST );
758 	qglDepthMask (1);
759 
760 	qglClear ( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
761 
762 	//render sun object center
763 	qglMatrixMode(GL_PROJECTION);
764     qglPushMatrix();
765     qglLoadIdentity();
766     qglOrtho(0, r_newrefdef.width, r_newrefdef.height, 0, -99999, 99999);
767     qglMatrixMode(GL_MODELVIEW);
768     qglPushMatrix();
769     qglLoadIdentity();
770 
771 	size = r_newrefdef.width * sun_size/4.0;
772     PART_RenderSunFlare(sun2_object, 0, size, 1.0, 1.0, 1.0, 1.0);
773 
774 	qglPopMatrix();
775     qglMatrixMode(GL_PROJECTION);
776     qglPopMatrix();
777 	qglLoadIdentity();
778 
779 	//render occuders simple, textureless
780 	//need to set up proper matrix for this view!
781 	screenaspect = (float)r_newrefdef.width/(float)r_newrefdef.height;
782 
783 	if(r_newrefdef.fov_y < 90)
784 		MYgluPerspective (r_newrefdef.fov_y,  screenaspect,  4,  128000);
785 	else
786 		MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4 * 74 / r_newrefdef.fov_y, 15000);
787 
788 	qglMatrixMode(GL_MODELVIEW);
789     qglLoadIdentity ();
790 
791 	qglRotatef (-90, 1, 0, 0);	    // put Z going up
792     qglRotatef (90,  0, 0, 1);	    // put Z going up
793 
794     qglRotatef (-r_newrefdef.viewangles[2],  1, 0, 0);
795 	qglRotatef (-r_newrefdef.viewangles[0],  0, 1, 0);
796 	qglRotatef (-r_newrefdef.viewangles[1],  0, 0, 1);
797 	qglTranslatef (-r_newrefdef.vieworg[0],  -r_newrefdef.vieworg[1],  -r_newrefdef.vieworg[2]);
798 
799 	qglCullFace(GL_FRONT);
800 	if (gl_cull->integer)
801 		qglEnable(GL_CULL_FACE);
802 
803 	R_DrawShadowMapWorld(false, origin); //could tweak this to only draw surfaces that are in the sun?
804 	R_DrawVegetationCasters(false);
805 
806 	qglMatrixMode(GL_PROJECTION);
807     qglPushMatrix();
808     qglLoadIdentity();
809     qglOrtho(0, r_newrefdef.width, r_newrefdef.height, 0, -99999, 99999);
810     qglMatrixMode(GL_MODELVIEW);
811     qglPushMatrix();
812     qglLoadIdentity();
813 
814 	//glsl the fbo with effect
815 
816 	qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
817 
818 	glUseProgramObjectARB( g_godraysprogramObj );
819 
820 	qglActiveTextureARB(GL_TEXTURE0);
821 	qglBindTexture(GL_TEXTURE_2D, r_colorbuffer->texnum);
822 
823 	glUniform1iARB( g_location_sunTex, 0);
824 
825 	R_TransformVectorToScreen(&r_newrefdef, sun_origin, fxScreenPos);
826 
827 	fxScreenPos[0] /= viddef.width;
828 	fxScreenPos[1] /= viddef.height;
829 
830 	glUniform2fARB( g_location_lightPositionOnScreen, fxScreenPos[0], fxScreenPos[1]);
831 
832 	glUniform1fARB( g_location_godrayScreenAspect, screenaspect);
833     glUniform1fARB( g_location_sunRadius, sun_size*r_godray_intensity->value);
834 
835 	//render quad
836 	qglEnable (GL_BLEND);
837 	qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
838 	qglDisable(GL_CULL_FACE);
839 
840 	qglEnableClientState (GL_VERTEX_ARRAY);
841 	qglEnableClientState (GL_TEXTURE_COORD_ARRAY);
842 
843 	qglTexCoordPointer (2, GL_FLOAT, sizeof(tex_array[0]), tex_array[0]);
844 	qglVertexPointer (2, GL_FLOAT, sizeof(vert_array[0]), vert_array[0]);
845 	qglColorPointer (4, GL_FLOAT, sizeof(col_array[0]), col_array[0]);
846 
847 	VA_SetElem2(vert_array[0],0, vid.height);
848 	VA_SetElem2(vert_array[1],vid.width, vid.height);
849 	VA_SetElem2(vert_array[2],vid.width, 0);
850 	VA_SetElem2(vert_array[3],0, 0);
851 
852 	VA_SetElem2(tex_array[0],r_colorbuffer->sl, r_colorbuffer->tl);
853 	VA_SetElem2(tex_array[1],r_colorbuffer->sh, r_colorbuffer->tl);
854 	VA_SetElem2(tex_array[2],r_colorbuffer->sh, r_colorbuffer->th);
855 	VA_SetElem2(tex_array[3],r_colorbuffer->sl, r_colorbuffer->th);
856 
857 	R_DrawVarrays(GL_QUADS, 0, 4);
858 
859 	qglDisable (GL_BLEND);
860 	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
861 
862 	R_KillVArrays();
863 
864 	glUseProgramObjectARB( 0 );
865 
866 	qglPopMatrix();
867     qglMatrixMode(GL_PROJECTION);
868     qglPopMatrix();
869     qglMatrixMode(GL_MODELVIEW);
870 }
871 
R_GLSLPostProcess(void)872 void R_GLSLPostProcess(void)
873 {
874 	if(gl_glsl_shaders->integer && gl_state.glsl_shaders)
875 	{
876 		R_GLSLGodRays();
877 
878 		R_GLSLWaterDroplets();
879 
880 		R_GLSLDistortion();
881 	}
882 }
883