]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - gl_draw.c
free texture processing buffers each frame so they don't hang around wasting memory
[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
375         if (!r_render.integer)
376                 return;
377
378         qglViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight);
379
380         qglMatrixMode(GL_PROJECTION);
381     qglLoadIdentity();
382         qglOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999);
383
384         qglMatrixMode(GL_MODELVIEW);
385     qglLoadIdentity();
386
387         qglDisable(GL_DEPTH_TEST);
388         qglDisable(GL_CULL_FACE);
389         qglEnable(GL_BLEND);
390         qglEnable(GL_TEXTURE_2D);
391         qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
392
393         chartexnum = R_GetTexture(char_texture);
394
395         additive = false;
396         qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
397         currentpic = "";
398         pic = NULL;
399         qglBindTexture(GL_TEXTURE_2D, 0);
400         color = 0;
401         qglColor4ub(0,0,0,0);
402
403         overbright = v_overbrightbits.integer;
404         batch = false;
405         batchcount = 0;
406         for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
407         {
408                 dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
409                 if (dq->flags & DRAWFLAG_ADDITIVE)
410                 {
411                         if (!additive)
412                         {
413                                 if (batch)
414                                 {
415                                         batch = false;
416                                         qglEnd();
417                                 }
418                                 additive = true;
419                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
420                         }
421                 }
422                 else
423                 {
424                         if (additive)
425                         {
426                                 if (batch)
427                                 {
428                                         batch = false;
429                                         qglEnd();
430                                 }
431                                 additive = false;
432                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
433                         }
434                 }
435                 if (color != dq->color)
436                 {
437                         color = dq->color;
438                         qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF));
439                 }
440                 if (batch && batchcount > 128)
441                 {
442                         batch = false;
443                         qglEnd();
444                 }
445                 x = dq->x;
446                 y = dq->y;
447                 w = dq->scalex;
448                 h = dq->scaley;
449                 switch(dq->command)
450                 {
451                 case DRAWQUEUE_PIC:
452                         str = (char *)(dq + 1);
453                         if (*str)
454                         {
455                                 if (strcmp(str, currentpic))
456                                 {
457                                         if (batch)
458                                         {
459                                                 batch = false;
460                                                 qglEnd();
461                                         }
462                                         currentpic = str;
463                                         pic = Draw_CachePic(str);
464                                         qglBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex));
465                                 }
466                                 if (w == 0)
467                                         w = pic->width;
468                                 if (h == 0)
469                                         h = pic->height;
470                                 if (!batch)
471                                 {
472                                         batch = true;
473                                         qglBegin(GL_TRIANGLES);
474                                         batchcount = 0;
475                                 }
476                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
477                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
478                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
479                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
480                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
481                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
482                                 batchcount++;
483                         }
484                         else
485                         {
486                                 if (currentpic[0])
487                                 {
488                                         if (batch)
489                                         {
490                                                 batch = false;
491                                                 qglEnd();
492                                         }
493                                         currentpic = "";
494                                         qglBindTexture(GL_TEXTURE_2D, 0);
495                                 }
496                                 if (!batch)
497                                 {
498                                         batch = true;
499                                         qglBegin(GL_TRIANGLES);
500                                         batchcount = 0;
501                                 }
502                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
503                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
504                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
505                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
506                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
507                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
508                                 batchcount++;
509                         }
510                         break;
511                 case DRAWQUEUE_STRING:
512                         str = (char *)(dq + 1);
513                         if (strcmp("conchars", currentpic))
514                         {
515                                 if (batch)
516                                 {
517                                         batch = false;
518                                         qglEnd();
519                                 }
520                                 currentpic = "conchars";
521                                 qglBindTexture(GL_TEXTURE_2D, chartexnum);
522                         }
523                         if (!batch)
524                         {
525                                 batch = true;
526                                 qglBegin(GL_TRIANGLES);
527                                 batchcount = 0;
528                         }
529                         while ((num = *str++) && x < vid.conwidth)
530                         {
531                                 if (num != ' ')
532                                 {
533                                         s = (num & 15)*0.0625f + (0.5f / 256.0f);
534                                         t = (num >> 4)*0.0625f + (0.5f / 256.0f);
535                                         u = 0.0625f - (1.0f / 256.0f);
536                                         v = 0.0625f - (1.0f / 256.0f);
537                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
538                                         qglTexCoord2f (s+u, t  );qglVertex2f (x+w, y  );
539                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
540                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
541                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
542                                         qglTexCoord2f (s  , t+v);qglVertex2f (x  , y+h);
543                                         batchcount++;
544                                 }
545                                 x += w;
546                         }
547                         break;
548                 case DRAWQUEUE_MESH:
549                         if (batch)
550                         {
551                                 batch = false;
552                                 qglEnd();
553                         }
554                         mesh = (void *)(dq + 1);
555                         qglBindTexture(GL_TEXTURE_2D, R_GetTexture(mesh->texture));
556
557                         if (gl_mesh_drawmode.integer < 0)
558                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 0);
559                         if (gl_mesh_drawmode.integer > 3)
560                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 3);
561                         if (gl_mesh_drawmode.integer >= 3 && qglDrawRangeElements == NULL)
562                                 Cvar_SetValueQuick(&gl_mesh_drawmode, 2);
563
564                         if (gl_mesh_drawmode.integer > 0)
565                         {
566                                 qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), mesh->vertices);CHECKGLERROR
567                                 qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoords);CHECKGLERROR
568                                 qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), mesh->colors);CHECKGLERROR
569                                 qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
570                                 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
571                                 qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
572                         }
573
574                         if (gl_mesh_drawmode.integer >= 3/* && (mesh->numvertices) <= gl_maxdrawrangeelementsvertices && (mesh->numindices) <= gl_maxdrawrangeelementsindices*/)
575                         {
576                                 // GL 1.2 or GL 1.1 with extension
577                                 GL_LockArray(0, mesh->numvertices);
578                                 qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertices, mesh->numindices, GL_UNSIGNED_INT, mesh->indices);
579                                 CHECKGLERROR
580                                 GL_UnlockArray();
581                         }
582                         else if (gl_mesh_drawmode.integer >= 2)
583                         {
584                                 // GL 1.1
585                                 GL_LockArray(0, mesh->numvertices);
586                                 qglDrawElements(GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices);
587                                 CHECKGLERROR
588                                 GL_UnlockArray();
589                         }
590                         else if (gl_mesh_drawmode.integer >= 1)
591                         {
592                                 int i;
593                                 // GL 1.1
594                                 // feed it manually using glArrayElement
595                                 GL_LockArray(0, mesh->numvertices);
596                                 qglBegin(GL_TRIANGLES);
597                                 for (i = 0;i < mesh->numindices;i++)
598                                         qglArrayElement(mesh->indices[i]);
599                                 qglEnd();
600                                 CHECKGLERROR
601                                 GL_UnlockArray();
602                         }
603                         else
604                         {
605                                 int i, in;
606                                 // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver
607                                 // feed it manually
608                                 qglBegin(GL_TRIANGLES);
609                                 for (i = 0;i < mesh->numindices;i++)
610                                 {
611                                         in = mesh->indices[i];
612                                         qglColor4ub(mesh->colors[in * 4], mesh->colors[in * 4 + 1], mesh->colors[in * 4 + 2], mesh->colors[in * 4 + 3]);
613                                         qglTexCoord2f(mesh->texcoords[in * 2], mesh->texcoords[in * 2 + 1]);
614                                         qglVertex3f(mesh->vertices[in * 3], mesh->vertices[in * 3 + 1], mesh->vertices[in * 3 + 2]);
615                                 }
616                                 qglEnd();
617                                 CHECKGLERROR
618                         }
619                         if (gl_mesh_drawmode.integer > 0)
620                         {
621                                 qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
622                                 qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
623                                 qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
624                         }
625                         // restore color, since it got trashed by using color array
626                         qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF));
627                         CHECKGLERROR
628                         currentpic = "\0";
629                         break;
630                 }
631         }
632         if (batch)
633                 qglEnd();
634         CHECKGLERROR
635
636         if (!v_hwgamma.integer)
637         {
638                 qglDisable(GL_TEXTURE_2D);
639                 CHECKGLERROR
640                 t = v_contrast.value * (float) (1 << v_overbrightbits.integer);
641                 if (t >= 1.01f)
642                 {
643                         qglBlendFunc (GL_DST_COLOR, GL_ONE);
644                         CHECKGLERROR
645                         qglBegin (GL_TRIANGLES);
646                         while (t >= 1.01f)
647                         {
648                                 num = (int) ((t - 1.0f) * 255.0f);
649                                 if (num > 255)
650                                         num = 255;
651                                 qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
652                                 qglVertex2f (-5000, -5000);
653                                 qglVertex2f (10000, -5000);
654                                 qglVertex2f (-5000, 10000);
655                                 t *= 0.5;
656                         }
657                         qglEnd ();
658                         CHECKGLERROR
659                 }
660                 else if (t <= 0.99f)
661                 {
662                         qglBlendFunc(GL_ZERO, GL_SRC_COLOR);
663                         CHECKGLERROR
664                         qglBegin(GL_TRIANGLES);
665                         num = (int) (t * 255.0f);
666                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
667                         qglVertex2f (-5000, -5000);
668                         qglVertex2f (10000, -5000);
669                         qglVertex2f (-5000, 10000);
670                         qglEnd();
671                         CHECKGLERROR
672                 }
673                 if (v_brightness.value >= 0.01f)
674                 {
675                         qglBlendFunc (GL_ONE, GL_ONE);
676                         CHECKGLERROR
677                         num = (int) (v_brightness.value * 255.0f);
678                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
679                         CHECKGLERROR
680                         qglBegin (GL_TRIANGLES);
681                         qglVertex2f (-5000, -5000);
682                         qglVertex2f (10000, -5000);
683                         qglVertex2f (-5000, 10000);
684                         qglEnd ();
685                         CHECKGLERROR
686                 }
687                 qglEnable(GL_TEXTURE_2D);
688                 CHECKGLERROR
689         }
690
691         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
692         CHECKGLERROR
693         qglEnable (GL_CULL_FACE);
694         CHECKGLERROR
695         qglEnable (GL_DEPTH_TEST);
696         CHECKGLERROR
697         qglDisable (GL_BLEND);
698         CHECKGLERROR
699         qglColor4ub (255, 255, 255, 255);
700         CHECKGLERROR
701 }
702