A minor removal of a few pieces of dead code. Nothing major. This is
[divverent/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 /*
263 ===============
264 Draw_Init
265 ===============
266 */
267 static void gl_draw_start(void)
268 {
269         drawtexturepool = R_AllocTexturePool();
270
271         numcachepics = 0;
272         memset(cachepichash, 0, sizeof(cachepichash));
273
274         char_texture = Draw_CachePic("conchars")->tex;
275 }
276
277 static void gl_draw_shutdown(void)
278 {
279         R_FreeTexturePool(&drawtexturepool);
280
281         numcachepics = 0;
282         memset(cachepichash, 0, sizeof(cachepichash));
283 }
284
285 static void gl_draw_newmap(void)
286 {
287 }
288
289 void GL_Draw_Init (void)
290 {
291         Cvar_RegisterVariable (&scr_conalpha);
292
293         numcachepics = 0;
294         memset(cachepichash, 0, sizeof(cachepichash));
295
296         R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
297 }
298
299 void R_DrawQueue(void)
300 {
301         int pos, num, chartexnum, overbright;
302         float x, y, w, h, s, t, u, v;
303         cachepic_t *pic;
304         drawqueue_t *dq;
305         char *str, *currentpic;
306         int batch, batchcount, additive;
307         unsigned int color;
308
309         if (!r_render.integer)
310                 return;
311
312         qglViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight);
313
314         qglMatrixMode(GL_PROJECTION);
315     qglLoadIdentity();
316         qglOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999);
317
318         qglMatrixMode(GL_MODELVIEW);
319     qglLoadIdentity();
320
321         qglDisable(GL_DEPTH_TEST);
322         qglDisable(GL_CULL_FACE);
323         qglEnable(GL_BLEND);
324         qglEnable(GL_TEXTURE_2D);
325         qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
326
327         chartexnum = R_GetTexture(char_texture);
328
329         additive = false;
330         qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
331         currentpic = "";
332         pic = NULL;
333         qglBindTexture(GL_TEXTURE_2D, 0);
334         color = 0;
335         qglColor4ub(0,0,0,0);
336
337         overbright = v_overbrightbits.integer;
338         batch = false;
339         batchcount = 0;
340         for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
341         {
342                 dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
343                 if (dq->flags & DRAWFLAG_ADDITIVE)
344                 {
345                         if (!additive)
346                         {
347                                 if (batch)
348                                 {
349                                         batch = false;
350                                         qglEnd();
351                                 }
352                                 additive = true;
353                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
354                         }
355                 }
356                 else
357                 {
358                         if (additive)
359                         {
360                                 if (batch)
361                                 {
362                                         batch = false;
363                                         qglEnd();
364                                 }
365                                 additive = false;
366                                 qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
367                         }
368                 }
369                 if (color != dq->color)
370                 {
371                         color = dq->color;
372                         qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF));
373                 }
374                 if (batch && batchcount > 128)
375                 {
376                         batch = false;
377                         qglEnd();
378                 }
379                 x = dq->x;
380                 y = dq->y;
381                 w = dq->scalex;
382                 h = dq->scaley;
383                 switch(dq->command)
384                 {
385                 case DRAWQUEUE_PIC:
386                         str = (char *)(dq + 1);
387                         if (*str)
388                         {
389                                 if (strcmp(str, currentpic))
390                                 {
391                                         if (batch)
392                                         {
393                                                 batch = false;
394                                                 qglEnd();
395                                         }
396                                         currentpic = str;
397                                         pic = Draw_CachePic(str);
398                                         qglBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex));
399                                 }
400                                 if (w == 0)
401                                         w = pic->width;
402                                 if (h == 0)
403                                         h = pic->height;
404                                 if (!batch)
405                                 {
406                                         batch = true;
407                                         qglBegin(GL_TRIANGLES);
408                                         batchcount = 0;
409                                 }
410                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
411                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
412                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
413                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
414                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
415                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
416                                 batchcount++;
417                         }
418                         else
419                         {
420                                 if (currentpic[0])
421                                 {
422                                         if (batch)
423                                         {
424                                                 batch = false;
425                                                 qglEnd();
426                                         }
427                                         currentpic = "";
428                                         qglBindTexture(GL_TEXTURE_2D, 0);
429                                 }
430                                 if (!batch)
431                                 {
432                                         batch = true;
433                                         qglBegin(GL_TRIANGLES);
434                                         batchcount = 0;
435                                 }
436                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
437                                 qglTexCoord2f (1, 0);qglVertex2f (x+w, y  );
438                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
439                                 qglTexCoord2f (0, 0);qglVertex2f (x  , y  );
440                                 qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h);
441                                 qglTexCoord2f (0, 1);qglVertex2f (x  , y+h);
442                                 batchcount++;
443                         }
444                         break;
445                 case DRAWQUEUE_STRING:
446                         str = (char *)(dq + 1);
447                         if (strcmp("conchars", currentpic))
448                         {
449                                 if (batch)
450                                 {
451                                         batch = false;
452                                         qglEnd();
453                                 }
454                                 currentpic = "conchars";
455                                 qglBindTexture(GL_TEXTURE_2D, chartexnum);
456                         }
457                         if (!batch)
458                         {
459                                 batch = true;
460                                 qglBegin(GL_TRIANGLES);
461                                 batchcount = 0;
462                         }
463                         while ((num = *str++) && x < vid.conwidth)
464                         {
465                                 if (num != ' ')
466                                 {
467                                         s = (num & 15)*0.0625f + (0.5f / 256.0f);
468                                         t = (num >> 4)*0.0625f + (0.5f / 256.0f);
469                                         u = 0.0625f - (1.0f / 256.0f);
470                                         v = 0.0625f - (1.0f / 256.0f);
471                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
472                                         qglTexCoord2f (s+u, t  );qglVertex2f (x+w, y  );
473                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
474                                         qglTexCoord2f (s  , t  );qglVertex2f (x  , y  );
475                                         qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h);
476                                         qglTexCoord2f (s  , t+v);qglVertex2f (x  , y+h);
477                                         batchcount++;
478                                 }
479                                 x += w;
480                         }
481                         break;
482                 }
483         }
484         if (batch)
485                 qglEnd();
486         CHECKGLERROR
487
488         if (!v_hwgamma.integer)
489         {
490                 qglDisable(GL_TEXTURE_2D);
491                 CHECKGLERROR
492                 t = v_contrast.value * (float) (1 << v_overbrightbits.integer);
493                 if (t >= 1.01f)
494                 {
495                         qglBlendFunc (GL_DST_COLOR, GL_ONE);
496                         CHECKGLERROR
497                         qglBegin (GL_TRIANGLES);
498                         while (t >= 1.01f)
499                         {
500                                 num = (int) ((t - 1.0f) * 255.0f);
501                                 if (num > 255)
502                                         num = 255;
503                                 qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
504                                 qglVertex2f (-5000, -5000);
505                                 qglVertex2f (10000, -5000);
506                                 qglVertex2f (-5000, 10000);
507                                 t *= 0.5;
508                         }
509                         qglEnd ();
510                         CHECKGLERROR
511                 }
512                 else if (t <= 0.99f)
513                 {
514                         qglBlendFunc(GL_ZERO, GL_SRC_COLOR);
515                         CHECKGLERROR
516                         qglBegin(GL_TRIANGLES);
517                         num = (int) (t * 255.0f);
518                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
519                         qglVertex2f (-5000, -5000);
520                         qglVertex2f (10000, -5000);
521                         qglVertex2f (-5000, 10000);
522                         qglEnd();
523                         CHECKGLERROR
524                 }
525                 if (v_brightness.value >= 0.01f)
526                 {
527                         qglBlendFunc (GL_ONE, GL_ONE);
528                         CHECKGLERROR
529                         num = (int) (v_brightness.value * 255.0f);
530                         qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255);
531                         CHECKGLERROR
532                         qglBegin (GL_TRIANGLES);
533                         qglVertex2f (-5000, -5000);
534                         qglVertex2f (10000, -5000);
535                         qglVertex2f (-5000, 10000);
536                         qglEnd ();
537                         CHECKGLERROR
538                 }
539                 qglEnable(GL_TEXTURE_2D);
540                 CHECKGLERROR
541         }
542
543         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
544         CHECKGLERROR
545         qglEnable (GL_CULL_FACE);
546         CHECKGLERROR
547         qglEnable (GL_DEPTH_TEST);
548         CHECKGLERROR
549         qglDisable (GL_BLEND);
550         CHECKGLERROR
551         qglColor4ub (255, 255, 255, 255);
552         CHECKGLERROR
553 }
554