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