]> git.xonotic.org Git - xonotic/darkplaces.git/blob - gl_draw.c
66fc741d8c3487234a6fe85f410f3c002196e698
[xonotic/darkplaces.git] / gl_draw.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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 #include "quakedef.h"
22
23 cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
24
25 static rtexture_t *char_texture;
26
27 //=============================================================================
28 /* Support Routines */
29
30 #define MAX_CACHED_PICS 256
31 #define CACHEPICHASHSIZE 256
32 static cachepic_t *cachepichash[CACHEPICHASHSIZE];
33 static cachepic_t cachepics[MAX_CACHED_PICS];
34 static int numcachepics;
35
36 static rtexturepool_t *drawtexturepool;
37
38 static qbyte pointerimage[256] =
39 {
40         "333333332......."
41         "26777761........"
42         "2655541........."
43         "265541.........."
44         "2654561........."
45         "26414561........"
46         "251.14561......."
47         "21...14561......"
48         "1.....141......."
49         ".......1........"
50         "................"
51         "................"
52         "................"
53         "................"
54         "................"
55         "................"
56 };
57
58 static rtexture_t *draw_generatemousepointer(void)
59 {
60         int i;
61         qbyte buffer[256][4];
62         for (i = 0;i < 256;i++)
63         {
64                 if (pointerimage[i] == '.')
65                 {
66                         buffer[i][0] = 0;
67                         buffer[i][1] = 0;
68                         buffer[i][2] = 0;
69                         buffer[i][3] = 0;
70                 }
71                 else
72                 {
73                         buffer[i][0] = (pointerimage[i] - '0') * 16;
74                         buffer[i][1] = (pointerimage[i] - '0') * 16;
75                         buffer[i][2] = (pointerimage[i] - '0') * 16;
76                         buffer[i][3] = 255;
77                 }
78         }
79         return R_LoadTexture(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
80 }
81
82 // must match NUMCROSSHAIRS in r_crosshairs.c
83 #define NUMCROSSHAIRS 5
84
85 static qbyte *crosshairtexdata[NUMCROSSHAIRS] =
86 {
87         "................"
88         "................"
89         "................"
90         "...33......33..."
91         "...355....553..."
92         "....577..775...."
93         ".....77..77....."
94         "................"
95         "................"
96         ".....77..77....."
97         "....577..775...."
98         "...355....553..."
99         "...33......33..."
100         "................"
101         "................"
102         "................"
103         ,
104         "................"
105         "................"
106         "................"
107         "...3........3..."
108         "....5......5...."
109         ".....7....7....."
110         "......7..7......"
111         "................"
112         "................"
113         "......7..7......"
114         ".....7....7....."
115         "....5......5...."
116         "...3........3..."
117         "................"
118         "................"
119         "................"
120         ,
121         "................"
122         ".......77......."
123         ".......77......."
124         "................"
125         "................"
126         ".......44......."
127         ".......44......."
128         ".77..44..44..77."
129         ".77..44..44..77."
130         ".......44......."
131         ".......44......."
132         "................"
133         ".......77......."
134         ".......77......."
135         "................"
136         "................"
137         ,
138         "................"
139         "................"
140         "................"
141         "................"
142         "................"
143         "................"
144         "................"
145         "................"
146         "........7777777."
147         "........752....."
148         "........72......"
149         "........7......."
150         "........7......."
151         "........7......."
152         "................"
153         "................"
154         ,
155         "................"
156         "................"
157         "................"
158         "................"
159         "................"
160         "........7......."
161         "................"
162         "........4......."
163         ".....7.4.4.7...."
164         "........4......."
165         "................"
166         "........7......."
167         "................"
168         "................"
169         "................"
170         "................"
171 };
172
173 static rtexture_t *draw_generatecrosshair(int num)
174 {
175         int i;
176         char *in;
177         qbyte data[16*16][4];
178         in = crosshairtexdata[num];
179         for (i = 0;i < 16*16;i++)
180         {
181                 if (in[i] == '.')
182                 {
183                         data[i][0] = 255;
184                         data[i][1] = 255;
185                         data[i][2] = 255;
186                         data[i][3] = 0;
187                 }
188                 else
189                 {
190                         data[i][0] = 255;
191                         data[i][1] = 255;
192                         data[i][2] = 255;
193                         data[i][3] = (qbyte) ((int) (in[i] - '0') * 255 / 7);
194                 }
195         }
196         return R_LoadTexture(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
197 }
198
199 /*
200 ================
201 Draw_CachePic
202 ================
203 */
204 // FIXME: move this to client somehow
205 cachepic_t      *Draw_CachePic (char *path)
206 {
207         int i, crc, hashkey;
208         cachepic_t *pic;
209         qpic_t *p;
210
211         crc = CRC_Block(path, strlen(path));
212         hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
213         for (pic = cachepichash[hashkey];pic;pic = pic->chain)
214                 if (!strcmp (path, pic->name))
215                         return pic;
216
217         if (numcachepics == MAX_CACHED_PICS)
218                 Sys_Error ("numcachepics == MAX_CACHED_PICS");
219         pic = cachepics + (numcachepics++);
220         strcpy (pic->name, path);
221         // link into list
222         pic->chain = cachepichash[hashkey];
223         cachepichash[hashkey] = pic;
224
225         // load the pic from disk
226         pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true);
227         if (pic->tex == NULL && (p = W_GetLumpName (path)))
228         {
229                 if (!strcmp(path, "conchars"))
230                 {
231                         qbyte *pix;
232                         // conchars is a raw image and with the wrong transparent color
233                         pix = (qbyte *)p;
234                         for (i = 0;i < 128 * 128;i++)
235                                 if (pix[i] == 0)
236                                         pix[i] = 255;
237                         pic->tex = R_LoadTexture (drawtexturepool, path, 128, 128, pix, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
238                 }
239                 else
240                         pic->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
241         }
242         if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga"))
243                 pic->tex = draw_generatemousepointer();
244         if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1.tga"))
245                 pic->tex = draw_generatecrosshair(0);
246         if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2.tga"))
247                 pic->tex = draw_generatecrosshair(1);
248         if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3.tga"))
249                 pic->tex = draw_generatecrosshair(2);
250         if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4.tga"))
251                 pic->tex = draw_generatecrosshair(3);
252         if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5.tga"))
253                 pic->tex = draw_generatecrosshair(4);
254         if (pic->tex == NULL)
255                 Sys_Error ("Draw_CachePic: failed to load %s", path);
256
257         pic->width = R_TextureWidth(pic->tex);
258         pic->height = R_TextureHeight(pic->tex);
259         return pic;
260 }
261
262 cachepic_t *Draw_NewPic(char *picname, int width, int height, int alpha, qbyte *pixels)
263 {
264         int crc, hashkey;
265         cachepic_t *pic;
266
267         crc = CRC_Block(picname, strlen(picname));
268         hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
269         for (pic = cachepichash[hashkey];pic;pic = pic->chain)
270                 if (!strcmp (picname, pic->name))
271                         break;
272
273         if (pic)
274         {
275                 if (pic->tex && pic->width == width && pic->height == height)
276                 {
277                         R_UpdateTexture(pic->tex, pixels);
278                         return pic;
279                 }
280         }
281         else
282         {
283                 if (pic == NULL)
284                 {
285                         if (numcachepics == MAX_CACHED_PICS)
286                                 Sys_Error ("numcachepics == MAX_CACHED_PICS");
287                         pic = cachepics + (numcachepics++);
288                         strcpy (pic->name, picname);
289                         // link into list
290                         pic->chain = cachepichash[hashkey];
291                         cachepichash[hashkey] = pic;
292                 }
293         }
294
295         pic->width = width;
296         pic->height = height;
297         if (pic->tex)
298                 R_FreeTexture(pic->tex);
299         pic->tex = R_LoadTexture (drawtexturepool, picname, width, height, pixels, TEXTYPE_RGBA, alpha ? TEXF_ALPHA : 0);
300         return pic;
301 }
302
303 void Draw_FreePic(char *picname)
304 {
305         int crc;
306         int hashkey;
307         cachepic_t *pic;
308         // this doesn't really free the pic, but does free it's texture
309         crc = CRC_Block(picname, strlen(picname));
310         hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
311         for (pic = cachepichash[hashkey];pic;pic = pic->chain)
312         {
313                 if (!strcmp (picname, pic->name))
314                 {
315                         R_FreeTexture(pic->tex);
316                         pic->width = 0;
317                         pic->height = 0;
318                         return;
319                 }
320         }
321 }
322
323 /*
324 ===============
325 Draw_Init
326 ===============
327 */
328 static void gl_draw_start(void)
329 {
330         drawtexturepool = R_AllocTexturePool();
331
332         numcachepics = 0;
333         memset(cachepichash, 0, sizeof(cachepichash));
334
335         char_texture = Draw_CachePic("conchars")->tex;
336 }
337
338 static void gl_draw_shutdown(void)
339 {
340         R_FreeTexturePool(&drawtexturepool);
341
342         numcachepics = 0;
343         memset(cachepichash, 0, sizeof(cachepichash));
344 }
345
346 static void gl_draw_newmap(void)
347 {
348 }
349
350 void GL_Draw_Init (void)
351 {
352         Cvar_RegisterVariable (&scr_conalpha);
353
354         numcachepics = 0;
355         memset(cachepichash, 0, sizeof(cachepichash));
356
357         R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
358 }
359
360 extern cvar_t gl_mesh_drawmode;
361 extern int gl_maxdrawrangeelementsvertices;
362 extern int gl_maxdrawrangeelementsindices;
363
364 void R_DrawQueue(void)
365 {
366         int pos, num, chartexnum, overbright;
367         float x, y, w, h, s, t, u, v;
368         cachepic_t *pic;
369         drawqueue_t *dq;
370         char *str, *currentpic;
371         int batch, batchcount, additive;
372         unsigned int color;
373         drawqueuemesh_t *mesh;
374         int arraylocked = false;
375
376         if (!r_render.integer)
377                 return;
378
379         qglViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight);
380
381         qglMatrixMode(GL_PROJECTION);
382     qglLoadIdentity();
383         qglOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999);
384
385         qglMatrixMode(GL_MODELVIEW);
386     qglLoadIdentity();
387
388         qglDisable(GL_DEPTH_TEST);
389         qglDisable(GL_CULL_FACE);
390         qglEnable(GL_BLEND);
391         qglEnable(GL_TEXTURE_2D);
392         qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
393
394         chartexnum = R_GetTexture(char_texture);
395
396         additive = false;
397         qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
398         currentpic = "";
399         pic = NULL;
400         qglBindTexture(GL_TEXTURE_2D, 0);
401         color = 0;
402         qglColor4ub(0,0,0,0);
403
404         overbright = v_overbrightbits.integer;
405         batch = false;
406         batchcount = 0;
407         for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
408         {
409                 dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
410                 if (dq->flags & DRAWFLAG_ADDITIVE)
411                 {
412                         if (!additive)
413                         {
414                                 if (batch)
415                                 {
416                                         batch = false;
417                                         qglEnd();
418                                 }
419                                 additive = true;
420                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
421                         }
422                 }
423                 else
424                 {
425                         if (additive)
426                         {
427                                 if (batch)
428                                 {
429                                         batch = false;
430                                         qglEnd();
431                                 }
432                                 additive = false;
433                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
434                         }
435                 }
436                 if (color != dq->color)
437                 {
438                         color = dq->color;
439                         qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF));
440                 }
441                 if (batch && batchcount > 128)
442                 {
443                         batch = false;
444                         qglEnd();
445                 }
446                 x = dq->x;
447                 y = dq->y;
448                 w = dq->scalex;
449                 h = dq->scaley;
450                 switch(dq->command)
451                 {
452                 case DRAWQUEUE_PIC:
453                         str = (char *)(dq + 1);
454                         if (*str)
455                         {
456                                 if (strcmp(str, currentpic))
457                                 {
458                                         if (batch)
459                                         {
460                                                 batch = false;
461                                                 qglEnd();
462                                         }
463                                         currentpic = str;
464                                         pic = Draw_CachePic(str);
465                                         qglBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex));
466                                 }
467                                 if (w == 0)
468                                         w = pic->width;
469                                 if (h == 0)
470                                         h = pic->height;
471                                 if (!batch)
472                                 {
473                                         batch = true;
474                                         qglBegin(GL_TRIANGLES);
475                                         batchcount = 0;
476                                 }
477                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
478                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
479                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
480                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
481                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
482                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
483                                 batchcount++;
484                         }
485                         else
486                         {
487                                 if (currentpic[0])
488                                 {
489                                         if (batch)
490                                         {
491                                                 batch = false;
492                                                 qglEnd();
493                                         }
494                                         currentpic = "";
495                                         qglBindTexture(GL_TEXTURE_2D, 0);
496                                 }
497                                 if (!batch)
498                                 {
499                                         batch = true;
500                                         qglBegin(GL_TRIANGLES);
501                                         batchcount = 0;
502                                 }
503                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
504                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
505                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
506                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
507                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
508                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
509                                 batchcount++;
510                         }
511                         break;
512                 case DRAWQUEUE_STRING:
513                         str = (char *)(dq + 1);
514                         if (strcmp("conchars", currentpic))
515                         {
516                                 if (batch)
517                                 {
518                                         batch = false;
519                                         qglEnd();
520                                 }
521                                 currentpic = "conchars";
522                                 qglBindTexture(GL_TEXTURE_2D, chartexnum);
523                         }
524                         if (!batch)
525                         {
526                                 batch = true;
527                                 qglBegin(GL_TRIANGLES);
528                                 batchcount = 0;
529                         }
530                         while ((num = *str++) && x < vid.conwidth)
531                         {
532                                 if (num != ' ')
533                                 {
534                                         s = (num & 15)*0.0625f + (0.5f / 256.0f);
535                                         t = (num >> 4)*0.0625f + (0.5f / 256.0f);
536                                         u = 0.0625f - (1.0f / 256.0f);
537                                         v = 0.0625f - (1.0f / 256.0f);
538                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
539                                         qglTexCoord2f (s+u, t  );qglVertex2f (x+w, y  );
540                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
541                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
542                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
543                                         qglTexCoord2f (s  , t+v);qglVertex2f (x  , y+h);
544                                         batchcount++;
545                                 }
546                                 x += w;
547                         }
548                         break;
549                 case DRAWQUEUE_MESH:
550                         if (batch)
551                         {
552                                 batch = false;
553                                 qglEnd();
554                         }
555                         mesh = (void *)(dq + 1);
556                         qglBindTexture(GL_TEXTURE_2D, R_GetTexture(mesh->texture));
557
558                         if (gl_mesh_drawmode.integer < 0)
559                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 0);
560                         if (gl_mesh_drawmode.integer > 3)
561                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 3);
562                         if (gl_mesh_drawmode.integer >= 3 && qglDrawRangeElements == NULL)
563                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 2);
564
565                         if (gl_mesh_drawmode.integer > 0)
566                         {
567                                 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), mesh->vertices);CHECKGLERROR
568                                 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoords);CHECKGLERROR
569                                 qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), mesh->colors);CHECKGLERROR
570                                 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
571                                 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
572                                 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
573                         }
574
575                         if (gl_supportslockarrays && gl_lockarrays.integer && gl_mesh_drawmode.integer > 0)
576                         {
577                                 qglLockArraysEXT(0, mesh->numvertices);
578                                 CHECKGLERROR
579                                 arraylocked = true;
580                         }
581                         if (gl_mesh_drawmode.integer >= 3/* && (mesh->numvertices) <= gl_maxdrawrangeelementsvertices && (mesh->numindices) <= gl_maxdrawrangeelementsindices*/)
582                         {
583                                 // GL 1.2 or GL 1.1 with extension
584                                 qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertices, mesh->numindices, GL_UNSIGNED_INT, mesh->indices);
585                                 CHECKGLERROR
586                         }
587                         else if (gl_mesh_drawmode.integer >= 2)
588                         {
589                                 // GL 1.1
590                                 qglDrawElements(GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices);
591                                 CHECKGLERROR
592                         }
593                         else if (gl_mesh_drawmode.integer >= 1)
594                         {
595                                 int i;
596                                 // GL 1.1
597                                 // feed it manually using glArrayElement
598                                 qglBegin(GL_TRIANGLES);
599                                 for (i = 0;i < mesh->numindices;i++)
600                                         qglArrayElement(mesh->indices[i]);
601                                 qglEnd();
602                                 CHECKGLERROR
603                         }
604                         else
605                         {
606                                 int i, in;
607                                 // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver
608                                 // feed it manually
609                                 qglBegin(GL_TRIANGLES);
610                                 for (i = 0;i < mesh->numindices;i++)
611                                 {
612                                         in = mesh->indices[i];
613                                         qglColor4ub(mesh->colors[in * 4], mesh->colors[in * 4 + 1], mesh->colors[in * 4 + 2], mesh->colors[in * 4 + 3]);
614                                         qglTexCoord2f(mesh->texcoords[in * 2], mesh->texcoords[in * 2 + 1]);
615                                         qglVertex3f(mesh->vertices[in * 3], mesh->vertices[in * 3 + 1], mesh->vertices[in * 3 + 2]);
616                                 }
617                                 qglEnd();
618                                 CHECKGLERROR
619                         }
620                         if (arraylocked)
621                         {
622                                 qglUnlockArraysEXT();
623                                 CHECKGLERROR
624                                 arraylocked = false;
625                         }
626                         if (gl_mesh_drawmode.integer > 0)
627                         {
628                                 qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
629                                 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
630                                 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
631                         }
632                         // restore color, since it got trashed by using color array
633                         qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF));
634                         CHECKGLERROR
635                         currentpic = "\0";
636                         break;
637                 }
638         }
639         if (batch)
640                 qglEnd();
641         CHECKGLERROR
642
643         if (!v_hwgamma.integer)
644         {
645                 qglDisable(GL_TEXTURE_2D);
646                 CHECKGLERROR
647                 t = v_contrast.value * (float) (1 << v_overbrightbits.integer);
648                 if (t >= 1.01f)
649                 {
650                         qglBlendFunc (GL_DST_COLOR, GL_ONE);
651                         CHECKGLERROR
652                         qglBegin (GL_TRIANGLES);
653                         while (t >= 1.01f)
654                         {
655                                 num = (int) ((t - 1.0f) * 255.0f);
656                                 if (num > 255)
657                                         num = 255;
658                                 qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
659                                 qglVertex2f (-5000, -5000);
660                                 qglVertex2f (10000, -5000);
661                                 qglVertex2f (-5000, 10000);
662                                 t *= 0.5;
663                         }
664                         qglEnd ();
665                         CHECKGLERROR
666                 }
667                 else if (t <= 0.99f)
668                 {
669                         qglBlendFunc(GL_ZERO, GL_SRC_COLOR);
670                         CHECKGLERROR
671                         qglBegin(GL_TRIANGLES);
672                         num = (int) (t * 255.0f);
673                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
674                         qglVertex2f (-5000, -5000);
675                         qglVertex2f (10000, -5000);
676                         qglVertex2f (-5000, 10000);
677                         qglEnd();
678                         CHECKGLERROR
679                 }
680                 if (v_brightness.value >= 0.01f)
681                 {
682                         qglBlendFunc (GL_ONE, GL_ONE);
683                         CHECKGLERROR
684                         num = (int) (v_brightness.value * 255.0f);
685                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
686                         CHECKGLERROR
687                         qglBegin (GL_TRIANGLES);
688                         qglVertex2f (-5000, -5000);
689                         qglVertex2f (10000, -5000);
690                         qglVertex2f (-5000, 10000);
691                         qglEnd ();
692                         CHECKGLERROR
693                 }
694                 qglEnable(GL_TEXTURE_2D);
695                 CHECKGLERROR
696         }
697
698         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
699         CHECKGLERROR
700         qglEnable (GL_CULL_FACE);
701         CHECKGLERROR
702         qglEnable (GL_DEPTH_TEST);
703         CHECKGLERROR
704         qglDisable (GL_BLEND);
705         CHECKGLERROR
706         qglColor4ub (255, 255, 255, 255);
707         CHECKGLERROR
708 }
709