UFO: Alien Invasion
Loading...
Searching...
No Matches
r_state.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 1997-2001 Id Software, Inc.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "r_local.h"
26#include "r_program.h"
27#include "r_error.h"
28
29/* useful for particles, pics, etc.. */
31 {0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}
32};
33
34/* Hack to keep track of active rendering program (have to reinit binings&parameters once it changed)*/
35static r_program_t* lastProgram = nullptr;
36
41{
42 if (texunit == r_state.active_texunit)
43 return true;
44
45 /* not supported */
46 if (texunit->texture >= r_config.maxTextureCoords + GL_TEXTURE0)
47 return false;
48
49 r_state.active_texunit = texunit;
50
51 qglActiveTexture(texunit->texture);
52 qglClientActiveTexture(texunit->texture);
53 return true;
54}
55
56static void R_BindTexture_ (int texnum)
57{
58 if (texnum == r_state.active_texunit->texnum)
59 return;
60
61 assert(texnum > 0);
62
63 r_state.active_texunit->texnum = texnum;
64
65 glBindTexture(GL_TEXTURE_2D, texnum);
67}
68
69void R_BindTextureDebug (int texnum, const char* file, int line, const char* function)
70{
71 if (texnum <= 0) {
72 Com_Printf("Bad texnum (%d) in: %s (%d): %s\n", texnum, file, line, function);
73 }
74 R_BindTexture_(texnum);
75}
76
78{
79 /* small optimization to save state changes */
80 if (texnum == texunit->texnum)
81 return;
82
83 R_SelectTexture(texunit);
84
85 R_BindTexture(texnum);
86
88}
89
94
99
104
105void R_UseMaterial (const material_t* material)
106{
107 static float last_b, last_p, last_s, last_h;
108 float b;
109
110 if (r_state.active_material == material)
111 return;
112
113 if (!r_state.active_normalmap)
114 return;
115
116 if (material)
117 r_state.active_material = material;
118 else
119 r_state.active_material = &defaultMaterial;
120
121 b = r_state.active_material->bump * r_bumpmap->value;
122 if (b != last_b)
123 R_ProgramParameter1f("BUMP", b);
124 last_b = b;
125
126 if (r_state.active_program != r_state.world_program || r_programs->integer > 1) {
127 const float p = r_state.active_material->parallax * r_parallax->value;
128 if (p != last_p)
129 R_ProgramParameter1f("PARALLAX", p);
130 last_p = p;
131
132 const float h = r_state.active_material->hardness * r_hardness->value;
133 if (h != last_h)
134 R_ProgramParameter1f("HARDNESS", h);
135 last_h = h;
136
137 const float s = r_state.active_material->specular * r_specular->value;
138 if (s != last_s)
139 R_ProgramParameter1f("SPECULAR", s);
140 last_s = s;
141 } else {
142 last_p = -1;
143 last_h = -1;
144 last_s = -1;
145 }
146}
147
148void R_BindArray (GLenum target, GLenum type, const void* array)
149{
150 const int v = static_cast<int>(target);
151 switch (v) {
152 case GL_VERTEX_ARRAY:
153 glVertexPointer(COMPONENTS_VERTEX_ARRAY3D, type, 0, array);
154 break;
155 case GL_TEXTURE_COORD_ARRAY:
156 glTexCoordPointer(COMPONENTS_TEXCOORD_ARRAY, type, 0, array);
157 break;
158 case GL_COLOR_ARRAY:
159 glColorPointer(COMPONENTS_COLOR_ARRAY, type, 0, array);
160 break;
161 case GL_NORMAL_ARRAY:
162 glNormalPointer(type, 0, array);
163 break;
164 case GL_TANGENT_ARRAY:
166 break;
168 R_AttributePointer("NEXT_FRAME_VERTS", COMPONENTS_VERTEX_ARRAY3D, array);
169 break;
171 R_AttributePointer("NEXT_FRAME_NORMALS", COMPONENTS_NORMAL_ARRAY, array);
172 break;
174 R_AttributePointer("NEXT_FRAME_TANGENTS", COMPONENTS_TANGENT_ARRAY, array);
175 break;
176 }
177}
178
183{
184 const int v = static_cast<int>(target);
185 switch (v) {
186 case GL_VERTEX_ARRAY:
187 R_BindArray(target, GL_FLOAT, r_state.vertex_array_3d);
188 break;
189 case GL_TEXTURE_COORD_ARRAY:
190 R_BindArray(target, GL_FLOAT, r_state.active_texunit->texcoord_array);
191 break;
192 case GL_COLOR_ARRAY:
193 R_BindArray(target, GL_FLOAT, r_state.color_array);
194 break;
195 case GL_NORMAL_ARRAY:
196 R_BindArray(target, GL_FLOAT, r_state.normal_array);
197 break;
198 case GL_TANGENT_ARRAY:
199 R_BindArray(target, GL_FLOAT, r_state.tangent_array);
200 break;
202 R_BindArray(target, GL_FLOAT, r_state.next_vertex_array_3d);
203 break;
205 R_BindArray(target, GL_FLOAT, r_state.next_normal_array);
206 break;
208 R_BindArray(target, GL_FLOAT, r_state.next_tangent_array);
209 break;
210 }
211}
212
214{
215 if (!qglBindBuffer)
216 return;
217
218 if (!r_vertexbuffers->integer)
219 return;
220
221 if (target == GL_ELEMENT_ARRAY_BUFFER) {
222 qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
223 return; /* No need to call gl***Poiner -- this binding is special and automates that */
224 } else {
225 qglBindBuffer(GL_ARRAY_BUFFER, id);
226 }
227
228 if (type && id) /* assign the array pointer as well */
229 R_BindArray(target, type, nullptr);
230}
231
233{
234 if (r_state.blend_src == src && r_state.blend_dest == dest)
235 return;
236
237 r_state.blend_src = src;
238 r_state.blend_dest = dest;
239
240 glBlendFunc(src, dest);
241}
242
243void R_EnableMultisample (bool enable)
244{
245 if (r_multisample->integer == 0 && enable)
246 return;
247
248 if (r_state.multisample_enabled == enable)
249 return;
250
251 r_state.multisample_enabled = enable;
252
253 if (enable) {
254 glEnable(GL_MULTISAMPLE);
255 } else {
256 glDisable(GL_MULTISAMPLE);
257 }
258 R_CheckError();
259}
260
261void R_EnableBlend (bool enable)
262{
263 if (r_state.blend_enabled == enable)
264 return;
265
266 r_state.blend_enabled = enable;
267
268 if (enable) {
269 glEnable(GL_BLEND);
270 glDepthMask(GL_FALSE);
271 } else {
272 glDisable(GL_BLEND);
273 glDepthMask(GL_TRUE);
274 }
275}
276
277void R_EnableAlphaTest (bool enable)
278{
279 if (r_state.alpha_test_enabled == enable)
280 return;
281
282 r_state.alpha_test_enabled = enable;
283
284 if (enable)
285 glEnable(GL_ALPHA_TEST);
286 else
287 glDisable(GL_ALPHA_TEST);
288}
289
290void R_EnableStencilTest (bool enable)
291{
292 if (r_state.stencil_test_enabled == enable)
293 return;
294
295 r_state.stencil_test_enabled = enable;
296
297 if (enable)
298 glEnable(GL_STENCIL_TEST);
299 else
300 glDisable(GL_STENCIL_TEST);
301}
302
303void R_EnableTexture (gltexunit_t* texunit, bool enable)
304{
305 if (enable == texunit->enabled)
306 return;
307
308 texunit->enabled = enable;
309
310 R_SelectTexture(texunit);
311
312 if (enable) {
313 /* activate texture unit */
314 glEnable(GL_TEXTURE_2D);
315
316 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
317
318 if (texunit == &texunit_lightmap) {
319 if (r_lightmap->integer)
320 R_TexEnv(GL_REPLACE);
321 else
322 R_TexEnv(GL_MODULATE);
323 }
324 } else {
325 /* disable on the second texture unit */
326 glDisable(GL_TEXTURE_2D);
327 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
328 }
330}
331
332void R_EnableColorArray (bool enable)
333{
334 if (r_state.color_array_enabled == enable)
335 return;
336
337 r_state.color_array_enabled = enable;
338
339 if (enable)
340 glEnableClientState(GL_COLOR_ARRAY);
341 else
342 glDisableClientState(GL_COLOR_ARRAY);
343}
344
350bool R_EnableLighting (r_program_t* program, bool enable)
351{
352 if (!r_programs->integer)
353 return r_state.lighting_enabled;
354
355 if (enable && (!program || !program->id))
356 return r_state.lighting_enabled;
357
358 if (r_state.lighting_enabled == enable && r_state.active_program == program)
359 return r_state.lighting_enabled;
360
361 r_state.lighting_enabled = enable;
362
363 if (enable) { /* toggle state */
364 R_UseProgram(program);
365
366 glEnableClientState(GL_NORMAL_ARRAY);
367 } else {
368 glDisableClientState(GL_NORMAL_ARRAY);
369
370 R_UseProgram(nullptr);
371 }
372
373 return r_state.lighting_enabled;
374}
375
376void R_SetupSpotLight (int index, const light_t* light)
377{
378 const vec4_t blackColor = {0.0, 0.0, 0.0, 1.0};
379 vec4_t position;
380
381 if (!r_programs->integer || !r_dynamic_lights->integer)
382 return;
383
385 return;
386
387 index += GL_LIGHT0;
388
389 glEnable(index);
390 glLightf(index, GL_CONSTANT_ATTENUATION, MIN_GL_CONSTANT_ATTENUATION);
391 glLightf(index, GL_LINEAR_ATTENUATION, 0);
392 glLightf(index, GL_QUADRATIC_ATTENUATION, 16.0 / (light->radius * light->radius));
393
394 VectorCopy(light->origin, position);
395 position[3] = 1.0; /* spot light */
396
397 glLightfv(index, GL_POSITION, position);
398 glLightfv(index, GL_AMBIENT, blackColor);
399 glLightfv(index, GL_DIFFUSE, light->color);
400 glLightfv(index, GL_SPECULAR, blackColor);
401}
402
404{
405 const vec4_t blackColor = {0.0, 0.0, 0.0, 1.0};
406
407 if (!r_programs->integer || !r_dynamic_lights)
408 return;
409
411 return;
412
413 index += GL_LIGHT0;
414
415 glDisable(index);
416 glLightf(index, GL_CONSTANT_ATTENUATION, MIN_GL_CONSTANT_ATTENUATION);
417 glLightf(index, GL_LINEAR_ATTENUATION, 0.0);
418 glLightf(index, GL_QUADRATIC_ATTENUATION, 0.0);
419 glLightfv(index, GL_AMBIENT, blackColor);
420 glLightfv(index, GL_DIFFUSE, blackColor);
421 glLightfv(index, GL_SPECULAR, blackColor);
422}
423
430void R_EnableAnimation (const mAliasMesh_t* mesh, float backlerp, bool enable)
431{
432 if (!r_programs->integer || !r_state.lighting_enabled)
433 return;
434
435 r_state.animation_enabled = enable;
436
437 if (enable) {
438 R_EnableAttribute("NEXT_FRAME_VERTS");
439 R_EnableAttribute("NEXT_FRAME_NORMALS");
440 R_EnableAttribute("NEXT_FRAME_TANGENTS");
441 R_ProgramParameter1i("ANIMATE", 1);
442
443 R_ProgramParameter1f("TIME", backlerp);
444
445 R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mesh->texcoords);
446 R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, mesh->verts);
447 R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, mesh->normals);
448 R_BindArray(GL_TANGENT_ARRAY, GL_FLOAT, mesh->tangents);
452 } else {
453 R_DisableAttribute("NEXT_FRAME_VERTS");
454 R_DisableAttribute("NEXT_FRAME_NORMALS");
455 R_DisableAttribute("NEXT_FRAME_TANGENTS");
456 R_ProgramParameter1i("ANIMATE", 0);
457 }
458}
459
465void R_EnableBumpmap (const image_t* normalmap)
466{
467 if (!r_state.lighting_enabled)
468 return;
469
470 if (!r_bumpmap->value)
471 return;
472
473 if (r_state.active_normalmap == normalmap)
474 return;
475
476 if (!normalmap) {
477 /* disable bump mapping */
478 R_ProgramParameter1i("BUMPMAP", 0);
479
480 r_state.active_normalmap = normalmap;
481 return;
482 }
483
484 if (!r_state.active_normalmap) {
485 /* enable bump mapping */
486 R_ProgramParameter1i("BUMPMAP", 1);
487 /* default material to use if no material gets loaded */
489 }
490
491 R_BindNormalmapTexture(normalmap->texnum);
492
493 r_state.active_normalmap = normalmap;
494}
495
496void R_EnableWarp (r_program_t* program, bool enable)
497{
498 if (!r_programs->integer)
499 return;
500
501 if (enable && (!program || !program->id))
502 return;
503
504 if (!r_warp->integer || r_state.warp_enabled == enable)
505 return;
506
507 r_state.warp_enabled = enable;
508
510
511 if (enable) {
512 glEnable(GL_TEXTURE_2D);
514 R_UseProgram(program);
515 } else {
516 glDisable(GL_TEXTURE_2D);
517 R_UseProgram(nullptr);
518 }
519
521}
522
523void R_EnableBlur (r_program_t* program, bool enable, r_framebuffer_t* source, r_framebuffer_t* dest, int dir)
524{
525 if (!r_programs->integer)
526 return;
527
528 if (enable && (!program || !program->id))
529 return;
530
531 if (!r_postprocess->integer || r_state.blur_enabled == enable)
532 return;
533
534 r_state.blur_enabled = enable;
535
537
538 if (enable) {
539 float userdata[] = { static_cast<float>(source->width), static_cast<float>(dir) };
541 program->userdata = userdata;
542 R_UseProgram(program);
543 } else {
545 R_UseProgram(nullptr);
546 }
547
549}
550
551void R_EnableShell (bool enable)
552{
553 if (enable == r_state.shell_enabled)
554 return;
555
556 r_state.shell_enabled = enable;
557
558 if (enable) {
559 glEnable(GL_POLYGON_OFFSET_FILL);
560 glPolygonOffset(-1.0, 1.0);
561
562 R_EnableDrawAsGlow(true);
563 R_EnableBlend(true);
564 R_BlendFunc(GL_SRC_ALPHA, GL_ONE);
565
566 if (r_state.lighting_enabled)
567 R_ProgramParameter1f("OFFSET", refdef.time / 3.0);
568 } else {
569 R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
570 R_EnableBlend(false);
571 R_EnableDrawAsGlow(false);
572
573 glPolygonOffset(0.0, 0.0);
574 glDisable(GL_POLYGON_OFFSET_FILL);
575
576 if (r_state.lighting_enabled)
577 R_ProgramParameter1f("OFFSET", 0.0);
578 }
579}
580
581#define FOG_START 300.0
582#define FOG_END 2500.0
583
585
586void R_EnableFog (bool enable)
587{
588 if (!r_fog->integer || r_state.fog_enabled == enable)
589 return;
590
591 r_state.fog_enabled = false;
592
593 /* This is ugly. Shaders could be enabled or disabled between this and rendering call, so we have to setup both FFP and GLSL */
594 if (enable) {
595 if (((refdef.weather & WEATHER_FOG) && r_fog->integer) || r_fog->integer == 2) {
596 r_state.fog_enabled = true;
597
598 glFogfv(GL_FOG_COLOR, refdef.fogColor);
599 glFogf(GL_FOG_DENSITY, refdef.fogColor[3]);
600 glEnable(GL_FOG);
601
602 if (r_programs->integer && (r_state.active_program == r_state.world_program || r_state.active_program == r_state.model_program || r_state.active_program == r_state.warp_program)) {
603 R_ProgramParameter3fv("FOGCOLOR", refdef.fogColor);
604 R_ProgramParameter1f("FOGDENSITY", refdef.fogColor[3]);
605 R_ProgramParameter2fv("FOGRANGE", fogRange);
606 }
607 }
608 } else {
609 glFogf(GL_FOG_DENSITY, 0.0);
610 glDisable(GL_FOG);
611 if (r_programs->integer && (r_state.active_program == r_state.world_program || r_state.active_program == r_state.model_program || r_state.active_program == r_state.warp_program))
612 R_ProgramParameter1f("FOGDENSITY", 0.0f);
613 }
614}
615
617{
618#ifndef GL_VERSION_ES_CM_1_0
619 static GLenum glowRenderTarget = GL_COLOR_ATTACHMENT1_EXT; // Not supported in GLES
620
621 if (r_state.active_program) {
622 /* got an active shader */
623 if (r_state.draw_glow_enabled) {
624 /* switch the draw buffer to the glow buffer */
625 R_BindColorAttachments(1, &glowRenderTarget);
626 R_ProgramParameter1f("GLOWSCALE", 0.0); /* Plumbing to avoid state leak */
627 } else {
628 /* switch back to the draw buffer we are currently rendering into ... */
629 R_DrawBuffers(2);
630 /* ... and enable glow, if there is a glow map */
631 if (r_state.glowmap_enabled) {
632 R_ProgramParameter1f("GLOWSCALE", 1.0);
633 } else {
634 R_ProgramParameter1f("GLOWSCALE", 0.0);
635 }
636 }
637 } else {
638 /* no shader */
639 if (r_state.draw_glow_enabled) {
640 /* switch the draw buffer to the glow buffer */
641 R_BindColorAttachments(1, &glowRenderTarget);
642 } else {
643 if (!r_state.glowmap_enabled) {
644 /* Awkward case. Postprocessing is requested, but fragment
645 * shader is disabled, and we are supposed to draw non-glowing object.
646 * So we just draw this object into color buffer only and hope that it's not
647 * supposed to overlay any glowing objects.
648 */
649 R_DrawBuffers(1);
650 } else {
651 /* FIXME: Had to draw glowmapped object, but don't know how to do it
652 * when rendering through FFP.
653 * So -- just copy color into glow buffer.
654 * (R_DrawAsGlow may hit this)
655 */
656 R_DrawBuffers(2);
657 /*Con_Print("GLSL glow with no program!\n");*/
658 }
659 }
660 }
661#endif
662}
663
664void R_EnableGlowMap (const image_t* image)
665{
666 if (!r_programs->integer)
667 return;
668
669 if (image)
671
673 if (!image && r_state.glowmap_enabled == !!image && r_state.active_program == lastProgram)
674 return;
675
676 r_state.glowmap_enabled = !!image;
677
678 /* Shouldn't render glow without GLSL, so enable simple program for it */
679 if (image) {
680 if (!r_state.active_program)
681 R_UseProgram(r_state.simple_glow_program);
682 } else {
683 if (r_state.active_program == r_state.simple_glow_program)
684 R_UseProgram(nullptr);
685 }
686
687 lastProgram = r_state.active_program;
688
690}
691
692void R_EnableDrawAsGlow (bool enable)
693{
694 if (!r_programs->integer)
695 return;
696
697 if (r_state.draw_glow_enabled == enable && r_state.active_program == lastProgram)
698 return;
699
700 r_state.draw_glow_enabled = enable;
701
702 lastProgram = r_state.active_program;
703
705}
706
707void R_EnableSpecularMap (const image_t* image, bool enable)
708{
709 if (!r_state.dynamic_lighting_enabled)
710 return;
711
712 if (r_programs->integer < 2)
713 return;
714
715 if (enable && image != nullptr) {
717 R_ProgramParameter1i("SPECULARMAP", 1);
718 r_state.specularmap_enabled = enable;
719 } else {
720 R_ProgramParameter1i("SPECULARMAP", 0);
721 r_state.specularmap_enabled = false;
722 }
723}
724
725void R_EnableRoughnessMap (const image_t* image, bool enable)
726{
727 if (!r_state.dynamic_lighting_enabled)
728 return;
729
730 if (enable && image != nullptr) {
732 R_ProgramParameter1i("ROUGHMAP", 1);
733 r_state.roughnessmap_enabled = enable;
734 } else {
735 R_ProgramParameter1i("ROUGHMAP", 0);
736 r_state.roughnessmap_enabled = false;
737 }
738}
739
743static void MYgluPerspective (GLfloat zNear, GLfloat zFar)
744{
745 GLfloat xmin, xmax, ymin, ymax, yaspect = (float) viddef.context.height / viddef.context.width;
746
747 if (r_isometric->integer) {
748 glOrtho(-10 * refdef.fieldOfViewX, 10 * refdef.fieldOfViewX, -10 * refdef.fieldOfViewX * yaspect, 10 * refdef.fieldOfViewX * yaspect, -zFar, zFar);
749 } else {
750 xmax = zNear * tan(refdef.fieldOfViewX * (M_PI / 360.0));
751 xmin = -xmax;
752
753 ymin = xmin * yaspect;
754 ymax = xmax * yaspect;
755
756 glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
757 }
758}
759
763void R_Setup3D (void)
764{
765 /* only for the battlescape rendering */
766 if ((refdef.rendererFlags & RDF_NOWORLDMODEL) == 0) {
767 int x, x2, y2, y, w, h;
768
769 /* set up viewport */
770 x = floorf(viddef.x * viddef.context.width / viddef.context.width);
771 x2 = ceilf((viddef.x + viddef.viewWidth) * viddef.context.width / viddef.context.width);
772 y = floorf(viddef.context.height - viddef.y * viddef.context.height / viddef.context.height);
773 y2 = ceilf(viddef.context.height - (viddef.y + viddef.viewHeight) * viddef.context.height / viddef.context.height);
774
775 w = x2 - x;
776 h = y - y2;
777
778 glViewport(x, y2, w, h);
779 R_CheckError();
780 }
781
782 /* set up projection matrix */
783 glMatrixMode(GL_PROJECTION);
784
785 glLoadIdentity();
786 if ((refdef.rendererFlags & RDF_NOWORLDMODEL) != 0) {
787 /* center image into the viewport */
788 float x = viddef.x + (viddef.viewWidth - VID_NORM_WIDTH) / 2.0 - (viddef.virtualWidth - VID_NORM_WIDTH) / 2.0;
789 float y = viddef.y + (viddef.viewHeight - VID_NORM_HEIGHT) / 2.0 - (viddef.virtualHeight - VID_NORM_HEIGHT) / 2.0;
790 /* @todo magic coef, i dont know where it come from */
791 x *= 2.0f / (float) viddef.virtualWidth;
792 y *= 2.0f / (float) viddef.virtualHeight;
793 glTranslatef(x, -y, 0.0f);
794 }
796
797 glMatrixMode(GL_MODELVIEW);
798 glLoadIdentity();
799 glRotatef(-90.0, 1.0, 0.0, 0.0); /* put Z going up */
800 glRotatef(90.0, 0.0, 0.0, 1.0); /* put Z going up */
801 glRotatef(-refdef.viewAngles[2], 1.0, 0.0, 0.0);
802 glRotatef(-refdef.viewAngles[0], 0.0, 1.0, 0.0);
803 glRotatef(-refdef.viewAngles[1], 0.0, 0.0, 1.0);
804 glTranslatef(-refdef.viewOrigin[0], -refdef.viewOrigin[1], -refdef.viewOrigin[2]);
805
806 /* retrieve the resulting matrix for other manipulations */
807 glGetFloatv(GL_MODELVIEW_MATRIX, r_locals.world_matrix);
808
809 /* set vertex array pointer */
810 R_BindDefaultArray(GL_VERTEX_ARRAY);
811
812 glDisable(GL_BLEND);
813
814 glEnable(GL_DEPTH_TEST);
815
816 /* set up framebuffers for postprocessing */
818
819 R_CheckError();
820}
821
825void R_Setup2D (void)
826{
827 /* only for the battlescape rendering */
828 if ((refdef.rendererFlags & RDF_NOWORLDMODEL) == 0) {
829 /* set 2D virtual screen size */
830 glViewport(0, 0, viddef.context.width, viddef.context.height);
831 }
832
833 glMatrixMode(GL_PROJECTION);
834 glLoadIdentity();
835
836 /* switch to orthographic (2 dimensional) projection
837 * don't draw anything before skybox */
838 glOrtho(0, viddef.context.width, viddef.context.height, 0, 9999.0f, SKYBOX_DEPTH);
839
840 glMatrixMode(GL_MODELVIEW);
841 glLoadIdentity();
842
843 /* bind default vertex array */
844 R_BindDefaultArray(GL_VERTEX_ARRAY);
845
846 R_Color(nullptr);
847
848 glEnable(GL_BLEND);
849
850 glDisable(GL_DEPTH_TEST);
851
852 glDisable(GL_LIGHTING);
853
854 /* disable render-to-framebuffer */
856
857 R_CheckError();
858}
859
861{
862 r_state.shell_enabled = false;
863 r_state.blend_enabled = false;
864 r_state.color_array_enabled = false;
865 r_state.alpha_test_enabled = false;
866 r_state.stencil_test_enabled = false;
867 r_state.lighting_enabled = false;
868 r_state.warp_enabled = false;
869 r_state.fog_enabled = false;
870 r_state.blur_enabled = false;
871 r_state.glowmap_enabled = false;
872 r_state.draw_glow_enabled = false;
873 r_state.dynamic_lighting_enabled = false;
874 r_state.specularmap_enabled = false;
875 r_state.roughnessmap_enabled = false;
876 r_state.animation_enabled = false;
877 r_state.renderbuffer_enabled = false;
878 r_state.active_material = nullptr;
879 r_state.blend_src = 0;
880 r_state.blend_dest = 0;
881 r_state.active_texunit = nullptr;
882
883 glClearColor(0, 0, 0, 0);
884
885 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
886
893
894 /* setup vertex array pointers */
895 glEnableClientState(GL_VERTEX_ARRAY);
896 R_BindDefaultArray(GL_VERTEX_ARRAY);
897
898 R_EnableColorArray(true);
899 R_BindDefaultArray(GL_COLOR_ARRAY);
900 R_EnableColorArray(false);
901
902 glEnableClientState(GL_NORMAL_ARRAY);
903 R_BindDefaultArray(GL_NORMAL_ARRAY);
904 glDisableClientState(GL_NORMAL_ARRAY);
905
906 R_EnableAlphaTest(false);
907
908 /* reset gl error state */
909 R_CheckError();
910
911 /* setup texture units */
912 for (int i = 0; i < r_config.maxTextureCoords && i < MAX_GL_TEXUNITS; i++) {
913 gltexunit_t* tex = &r_state.texunits[i];
914 tex->texture = GL_TEXTURE0 + i;
915 tex->enabled = false;
916
917 R_EnableTexture(tex, true);
918
919 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
920 R_TexEnv(GL_MODULATE);
922
923 if (i > 0) /* turn them off for now */
924 R_EnableTexture(tex, false);
925
926 R_CheckError();
927 }
928
930 /* alpha test parameters */
931 glAlphaFunc(GL_GREATER, 0.01f);
932
933 /* fog parameters */
934 glFogi(GL_FOG_MODE, GL_LINEAR);
935 glFogf(GL_FOG_START, FOG_START);
936 glFogf(GL_FOG_END, FOG_END);
937
938 /* stencil test parameters */
939 glStencilFunc(GL_GEQUAL, 1, 0xff);
940 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
941
942 /* polygon offset parameters */
943 glPolygonOffset(1, 1);
944
945 /* alpha blend parameters */
946 R_EnableBlend(true);
947 R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
948
949 /* remove leftover lights */
951
952 /* reset gl error state */
953 R_CheckError();
954}
955
957{
958 if (mode == r_state.active_texunit->texenv)
959 return;
960
961 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
962 r_state.active_texunit->texenv = mode;
963}
964
969{
970 R_SelectTexture(&texunit_lightmap); /* abuse lightmap texture unit for color manipulation */
971
972 if (!rgba) {
973 R_TexEnv(GL_MODULATE);
974 glDisable(GL_TEXTURE_2D);
976 return;
977 }
978
979 glEnable(GL_TEXTURE_2D);
980
981 R_TexEnv(GL_COMBINE); /* enable color combiner */
982 /* setup texture combiner to blend between actual color of previous texture stage and the constant rgb color given as the parameter to this function
983 * amount of blending is defined by alpha channel of constant color
984 */
985 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT); /* set constant color as blending target*/
986 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
987 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); /* set incoming color as blending source */
988 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
989 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT); /* set constant color alpha as blending factor */
990 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
991 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); /* set blending mode to interpolation from src1 to src0 */
992 /* copy alpha from incoming color, it could be used later for framebuffer operations */
993 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
994 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
995 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
996
997 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba);
998
1000
1002}
1003
1004const vec4_t color_white = {1, 1, 1, 1};
1005
1011void R_Color (const vec4_t rgba)
1012{
1013 const float* color;
1014 if (rgba)
1015 color = rgba;
1016 else
1017 color = color_white;
1018
1019 glColor4f(color[0], color[1], color[2], color[3]);
1020 R_CheckError();
1021}
1022
1030{
1031 if (size <= r_state.array_size)
1032 return;
1033 r_state.vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.vertex_array_3d, size * COMPONENTS_VERTEX_ARRAY3D * sizeof(GLfloat));
1034 r_state.vertex_array_2d = (GLshort*) Mem_SafeReAlloc(r_state.vertex_array_2d, size * COMPONENTS_VERTEX_ARRAY2D * sizeof(GLshort));
1035 r_state.color_array = (GLfloat*) Mem_SafeReAlloc(r_state.color_array, size * COMPONENTS_COLOR_ARRAY * sizeof(GLfloat));
1036 r_state.index_array = (GLint*) Mem_SafeReAlloc(r_state.index_array, size * COMPONENTS_INDEX_ARRAY * sizeof(GLint));
1037 r_state.normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.normal_array, size * COMPONENTS_NORMAL_ARRAY * sizeof(GLfloat));
1038 r_state.tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.tangent_array, size * COMPONENTS_TANGENT_ARRAY * sizeof(GLfloat));
1039 r_state.next_vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.next_vertex_array_3d, size * COMPONENTS_VERTEX_ARRAY3D * sizeof(GLfloat));
1040 r_state.next_normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_normal_array, size * COMPONENTS_NORMAL_ARRAY * sizeof(GLfloat));
1041 r_state.next_tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_tangent_array, size * COMPONENTS_TANGENT_ARRAY * sizeof(GLfloat));
1042 r_state.array_size = size;
1043 R_BindDefaultArray(GL_VERTEX_ARRAY);
1044 R_BindDefaultArray(GL_COLOR_ARRAY);
1045 R_BindDefaultArray(GL_NORMAL_ARRAY);
1050}
1051
1060{
1061 if (size <= texunit->array_size)
1062 return;
1063 texunit->texcoord_array = (GLfloat*) Mem_SafeReAlloc(texunit->texcoord_array, size * COMPONENTS_TEXCOORD_ARRAY * sizeof(GLfloat));
1064 texunit->array_size = size;
1065 if (!r_state.active_texunit)
1066 r_state.active_texunit = texunit;
1067 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
1068}
#define VID_NORM_WIDTH
Definition cl_renderer.h:40
#define WEATHER_FOG
Definition cl_renderer.h:38
#define RDF_NOWORLDMODEL
Definition cl_renderer.h:34
#define VID_NORM_HEIGHT
Definition cl_renderer.h:41
#define MAX_GL_LIGHTS
Definition cl_renderer.h:55
rendererData_t refdef
Definition r_main.cpp:45
viddef_t viddef
Definition cl_video.cpp:34
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define MAX_WORLD_WIDTH
-MAX_WORLD_WIDTH up tp +MAX_WORLD_WIDTH
Definition defines.h:288
void glBindTexture(GLenum target, GLuint id)
Definition gldummy.cpp:4
voidpf void uLong size
Definition ioapi.h:42
const char int mode
Definition ioapi.h:41
#define M_PI
Definition mathlib.h:34
#define Mem_SafeReAlloc(ptr, size)
Definition mem.h:45
Error checking function.
#define R_CheckError()
Definition r_error.h:30
void R_BindColorAttachments(unsigned int n, unsigned int *attachments)
Activate draw buffer(s).
void R_UseFramebuffer(const r_framebuffer_t *buf)
bind specified framebuffer object so we render to it
bool R_EnableRenderbuffer(bool enable)
Enable the render to the framebuffer.
void R_DrawBuffers(unsigned int drawBufferNum)
Activate draw buffer(s).
QGL_EXTERN GLenum GLuint * dest
Definition r_gl.h:101
#define GL_TANGENT_ARRAY
Definition r_gl.h:76
#define GL_NEXT_TANGENT_ARRAY
Definition r_gl.h:79
#define GL_NEXT_VERTEX_ARRAY
Definition r_gl.h:77
QGL_EXTERN GLint
Definition r_gl.h:135
QGL_EXTERN int GLboolean GLfloat * v
Definition r_gl.h:120
QGL_EXTERN GLuint index
Definition r_gl.h:110
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
#define GL_NEXT_NORMAL_ARRAY
Definition r_gl.h:78
QGL_EXTERN GLuint
Definition r_gl.h:124
QGL_EXTERN const GLuint *QGL_EXTERN GLuint *QGL_EXTERN GLenum
Definition r_gl.h:127
#define GL_SOURCE2_RGB
#define GL_SOURCE1_RGB
#define GL_SOURCE0_RGB
#define GL_SOURCE0_ALPHA
image_t * r_dummyTexture
Definition r_main.cpp:53
image_t * r_warpTexture
Definition r_main.cpp:52
void R_ClearStaticLights(void)
Remove all static light data.
Definition r_light.cpp:300
local graphics definitions
cvar_t * r_specular
Definition r_main.cpp:104
cvar_t * r_bumpmap
Definition r_main.cpp:103
cvar_t * r_vertexbuffers
Definition r_main.cpp:94
cvar_t * r_hardness
Definition r_main.cpp:105
cvar_t * r_postprocess
Definition r_main.cpp:100
#define MIN_GL_CONSTANT_ATTENUATION
Definition r_local.h:45
cvar_t * r_fog
Definition r_main.cpp:107
cvar_t * r_parallax
Definition r_main.cpp:106
cvar_t * r_multisample
Definition r_main.cpp:90
cvar_t * r_programs
Definition r_main.cpp:97
rconfig_t r_config
Definition r_main.cpp:47
cvar_t * r_lightmap
Definition r_main.cpp:68
cvar_t * r_isometric
Definition r_main.cpp:63
cvar_t * r_dynamic_lights
Definition r_main.cpp:96
rlocals_t r_locals
Definition r_main.cpp:49
cvar_t * r_warp
Definition r_main.cpp:95
rstate_t r_state
Definition r_main.cpp:48
material_t defaultMaterial
vec2_t fogRange
Definition r_state.cpp:584
void R_ProgramParameter1i(const char *name, GLint value)
void R_EnableAttribute(const char *name)
void R_ProgramParameter2fv(const char *name, GLfloat *value)
void R_ProgramParameter1f(const char *name, GLfloat value)
void R_DisableAttribute(const char *name)
void R_AttributePointer(const char *name, GLuint size, const GLvoid *array)
void R_UseProgram(r_program_t *prog)
Definition r_program.cpp:43
void R_ProgramParameter3fv(const char *name, GLfloat *value)
#define FOG_END
Definition r_state.cpp:582
static void R_BindTexture_(int texnum)
Definition r_state.cpp:56
void R_EnableAlphaTest(bool enable)
Definition r_state.cpp:277
void R_BindBuffer(GLenum target, GLenum type, GLuint id)
Definition r_state.cpp:213
void R_EnableTexture(gltexunit_t *texunit, bool enable)
Definition r_state.cpp:303
void R_BindDefaultArray(GLenum target)
Binds the appropriate shared vertex array to the specified target.
Definition r_state.cpp:182
void R_Setup3D(void)
Definition r_state.cpp:763
void R_TexOverride(vec4_t rgba)
Sets special texture environment mode to override texture color; don't forget to call R_TexOverride(n...
Definition r_state.cpp:968
void R_EnableGlowMap(const image_t *image)
Definition r_state.cpp:664
void R_BlendFunc(GLenum src, GLenum dest)
Definition r_state.cpp:232
void R_EnableDrawAsGlow(bool enable)
Definition r_state.cpp:692
void R_SetDefaultState(void)
Definition r_state.cpp:860
void R_EnableBlur(r_program_t *program, bool enable, r_framebuffer_t *source, r_framebuffer_t *dest, int dir)
Definition r_state.cpp:523
const vec4_t color_white
Definition r_state.cpp:1004
void R_SetupSpotLight(int index, const light_t *light)
Definition r_state.cpp:376
void R_EnableMultisample(bool enable)
Definition r_state.cpp:243
static void R_UpdateGlowBufferBinding(void)
Definition r_state.cpp:616
bool R_EnableLighting(r_program_t *program, bool enable)
Enables hardware-accelerated lighting with the specified program. This should be called after any tex...
Definition r_state.cpp:350
bool R_SelectTexture(gltexunit_t *texunit)
Returns false if the texunit is not supported.
Definition r_state.cpp:40
static void MYgluPerspective(GLfloat zNear, GLfloat zFar)
Definition r_state.cpp:743
void R_Setup2D(void)
Definition r_state.cpp:825
void R_BindLightmapTexture(GLuint texnum)
Definition r_state.cpp:90
void R_DisableSpotLight(int index)
Definition r_state.cpp:403
void R_BindDeluxemapTexture(GLuint texnum)
Definition r_state.cpp:95
#define FOG_START
Definition r_state.cpp:581
void R_UseMaterial(const material_t *material)
Definition r_state.cpp:105
void R_EnableBumpmap(const image_t *normalmap)
Enables bumpmapping and binds the given normalmap.
Definition r_state.cpp:465
void R_EnableWarp(r_program_t *program, bool enable)
Definition r_state.cpp:496
void R_EnableBlend(bool enable)
Definition r_state.cpp:261
void R_TexEnv(GLenum mode)
Definition r_state.cpp:956
void R_EnableSpecularMap(const image_t *image, bool enable)
Definition r_state.cpp:707
void R_EnableRoughnessMap(const image_t *image, bool enable)
Definition r_state.cpp:725
const vec2_t default_texcoords[4]
Definition r_state.cpp:30
void R_BindTextureForTexUnit(GLuint texnum, gltexunit_t *texunit)
Definition r_state.cpp:77
void R_ReallocateTexunitArray(gltexunit_t *texunit, int size)
Reallocate texcoord array of the specified texunit, if needed.
Definition r_state.cpp:1059
void R_EnableShell(bool enable)
Definition r_state.cpp:551
void R_EnableColorArray(bool enable)
Definition r_state.cpp:332
void R_BindNormalmapTexture(GLuint texnum)
Definition r_state.cpp:100
void R_Color(const vec4_t rgba)
Change the color to given value.
Definition r_state.cpp:1011
void R_EnableFog(bool enable)
Definition r_state.cpp:586
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition r_state.cpp:1029
static r_program_t * lastProgram
Definition r_state.cpp:35
void R_BindArray(GLenum target, GLenum type, const void *array)
Definition r_state.cpp:148
void R_EnableAnimation(const mAliasMesh_t *mesh, float backlerp, bool enable)
Enables animation using keyframe interpolation on the GPU.
Definition r_state.cpp:430
void R_EnableStencilTest(bool enable)
Definition r_state.cpp:290
void R_BindTextureDebug(int texnum, const char *file, int line, const char *function)
Definition r_state.cpp:69
#define COMPONENTS_NORMAL_ARRAY
Definition r_state.h:80
#define GL_ARRAY_LENGTH_CHUNK
Definition r_state.h:44
#define texunit_diffuse
Definition r_state.h:68
#define MAX_GL_TEXUNITS
Definition r_state.h:58
#define texunit_roughnessmap
Definition r_state.h:74
#define COMPONENTS_VERTEX_ARRAY2D
Definition r_state.h:77
#define texunit_deluxemap
Definition r_state.h:70
#define texunit_specularmap
Definition r_state.h:73
#define texunit_2
Definition r_state.h:63
#define COMPONENTS_COLOR_ARRAY
Definition r_state.h:78
#define SKYBOX_DEPTH
Center position of skybox along z-axis. This is used to make sure we see only the inside of Skybox.
Definition r_state.h:41
#define COMPONENTS_VERTEX_ARRAY3D
Definition r_state.h:76
#define texunit_lightmap
Definition r_state.h:69
#define COMPONENTS_TEXCOORD_ARRAY
Definition r_state.h:82
#define COMPONENTS_INDEX_ARRAY
Definition r_state.h:79
#define texunit_glowmap
Definition r_state.h:72
#define COMPONENTS_TANGENT_ARRAY
Definition r_state.h:81
#define texunit_3
Definition r_state.h:64
#define texunit_4
Definition r_state.h:65
#define texunit_1
Definition r_state.h:62
#define R_BindTexture(tn)
Definition r_state.h:184
#define fbo_screen
Definition r_state.h:87
#define texunit_normalmap
Definition r_state.h:71
#define texunit_0
Definition r_state.h:61
texunits maintain multitexture state
Definition r_state.h:48
GLint texnum
Definition r_state.h:51
GLenum texture
Definition r_state.h:50
int array_size
Definition r_state.h:55
bool enabled
Definition r_state.h:49
GLfloat * texcoord_array
Definition r_state.h:53
GLuint texnum
Definition r_image.h:66
a light source
Definition r_light.h:29
vec4_t color
Definition r_light.h:31
vec3_t origin
Definition r_light.h:30
float radius
Definition r_light.h:32
vec_t * next_normals
vec_t * texcoords
vec_t * next_tangents
vec_t * next_verts
void * userdata
Definition r_program.h:62
GLuint id
Definition r_program.h:55
vec_t vec4_t[4]
Definition ufotypes.h:40
vec_t vec2_t[2]
Definition ufotypes.h:38
#define VectorCopy(src, dest)
Definition vector.h:51