2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
23 //#define GL_COLOR_INDEX8_EXT 0x80E5
25 cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
27 static rtexture_t *char_texture;
29 //=============================================================================
30 /* Support Routines */
32 #define MAX_CACHED_PICS 256
33 #define CACHEPICHASHSIZE 256
34 static cachepic_t *cachepichash[CACHEPICHASHSIZE];
35 static cachepic_t cachepics[MAX_CACHED_PICS];
36 static int numcachepics;
38 static rtexturepool_t *drawtexturepool;
40 static byte pointerimage[256] =
60 static rtexture_t *draw_generatemousepointer(void)
64 for (i = 0;i < 256;i++)
66 if (pointerimage[i] == '.')
75 buffer[i][0] = (pointerimage[i] - '0') * 16;
76 buffer[i][1] = (pointerimage[i] - '0') * 16;
77 buffer[i][2] = (pointerimage[i] - '0') * 16;
81 return R_LoadTexture(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
84 // must match NUMCROSSHAIRS in r_crosshairs.c
85 #define NUMCROSSHAIRS 5
87 static byte *crosshairtexdata[NUMCROSSHAIRS] =
175 static rtexture_t *draw_generatecrosshair(int num)
180 in = crosshairtexdata[num];
181 for (i = 0;i < 16*16;i++)
195 data[i][3] = (byte) ((int) (in[i] - '0') * 255 / 7);
198 return R_LoadTexture(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
206 // FIXME: move this to client somehow
207 cachepic_t *Draw_CachePic (char *path)
213 crc = CRC_Block(path, strlen(path));
214 hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
215 for (pic = cachepichash[hashkey];pic;pic = pic->chain)
216 if (!strcmp (path, pic->name))
218 //for (pic = cachepics, i = 0;i < numcachepics;pic++, i++)
219 // if (!strcmp (path, pic->name))
222 if (numcachepics == MAX_CACHED_PICS)
223 Sys_Error ("numcachepics == MAX_CACHED_PICS");
224 pic = cachepics + (numcachepics++);
225 strcpy (pic->name, path);
227 pic->chain = cachepichash[hashkey];
228 cachepichash[hashkey] = pic;
230 // load the pic from disk
231 pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true);
232 if (pic->tex == NULL && (p = W_GetLumpName (path)))
234 if (!strcmp(path, "conchars"))
237 // conchars is a raw image and with the wrong transparent color
239 for (i = 0;i < 128 * 128;i++)
242 pic->tex = R_LoadTexture (drawtexturepool, path, 128, 128, pix, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
245 pic->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
247 if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga"))
248 pic->tex = draw_generatemousepointer();
249 if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1.tga"))
250 pic->tex = draw_generatecrosshair(0);
251 if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2.tga"))
252 pic->tex = draw_generatecrosshair(1);
253 if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3.tga"))
254 pic->tex = draw_generatecrosshair(2);
255 if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4.tga"))
256 pic->tex = draw_generatecrosshair(3);
257 if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5.tga"))
258 pic->tex = draw_generatecrosshair(4);
259 if (pic->tex == NULL)
260 Sys_Error ("Draw_CachePic: failed to load %s", path);
262 pic->width = R_TextureWidth(pic->tex);
263 pic->height = R_TextureHeight(pic->tex);
272 static void gl_draw_start(void)
274 drawtexturepool = R_AllocTexturePool();
277 memset(cachepichash, 0, sizeof(cachepichash));
279 char_texture = Draw_CachePic("conchars")->tex;
282 static void gl_draw_shutdown(void)
284 R_FreeTexturePool(&drawtexturepool);
287 memset(cachepichash, 0, sizeof(cachepichash));
290 static void gl_draw_newmap(void)
294 void GL_Draw_Init (void)
296 Cvar_RegisterVariable (&scr_conalpha);
299 memset(cachepichash, 0, sizeof(cachepichash));
301 R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap);
304 void R_DrawQueue(void)
306 int pos, num, chartexnum, overbright;
307 float x, y, w, h, s, t, u, v;
310 char *str, *currentpic;
314 if (!r_render.integer)
317 glViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight);
319 glMatrixMode(GL_PROJECTION);
321 glOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999);
323 glMatrixMode(GL_MODELVIEW);
326 glDisable(GL_DEPTH_TEST);
327 glDisable(GL_CULL_FACE);
329 glEnable(GL_TEXTURE_2D);
330 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
332 chartexnum = R_GetTexture(char_texture);
335 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
338 glBindTexture(GL_TEXTURE_2D, 0);
342 // LordHavoc: NEAREST mode on text if not scaling up
344 if (vid.realwidth <= (int) vid.conwidth)
346 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
348 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
353 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
355 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
360 overbright = v_overbrightbits.integer;
362 for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
364 dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
365 if (dq->flags & DRAWFLAG_ADDITIVE)
375 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
388 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
391 if (color != dq->color)
394 glColor4ub((byte)(((color >> 24) & 0xFF) >> overbright), (byte)(((color >> 16) & 0xFF) >> overbright), (byte)(((color >> 8) & 0xFF) >> overbright), (byte)(color & 0xFF));
403 str = (char *)(dq + 1);
406 if (strcmp(str, currentpic))
414 pic = Draw_CachePic(str);
415 glBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex));
426 //DrawQuad(dq->x, dq->y, w, h, 0, 0, 1, 1);
427 glTexCoord2f (0, 0);glVertex2f (x , y );
428 glTexCoord2f (1, 0);glVertex2f (x+w, y );
429 glTexCoord2f (1, 1);glVertex2f (x+w, y+h);
430 glTexCoord2f (0, 1);glVertex2f (x , y+h);
442 glBindTexture(GL_TEXTURE_2D, 0);
449 //DrawQuad(dq->x, dq->y, dq->scalex, dq->scaley, 0, 0, 1, 1);
450 glTexCoord2f (0, 0);glVertex2f (x , y );
451 glTexCoord2f (1, 0);glVertex2f (x+w, y );
452 glTexCoord2f (1, 1);glVertex2f (x+w, y+h);
453 glTexCoord2f (0, 1);glVertex2f (x , y+h);
456 case DRAWQUEUE_STRING:
457 str = (char *)(dq + 1);
458 if (strcmp("conchars", currentpic))
465 currentpic = "conchars";
466 glBindTexture(GL_TEXTURE_2D, chartexnum);
473 while ((num = *str++) && x < vid.conwidth)
477 s = (num & 15)*0.0625f + (0.5f / 256.0f);
478 t = (num >> 4)*0.0625f + (0.5f / 256.0f);
479 u = 0.0625f - (1.0f / 256.0f);
480 v = 0.0625f - (1.0f / 256.0f);
481 //DrawQuad(x, y, w, h, (num & 15)*0.0625f + (0.5f / 256.0f), (num >> 4)*0.0625f + (0.5f / 256.0f), 0.0625f - (1.0f / 256.0f), 0.0625f - (1.0f / 256.0f));
482 glTexCoord2f (s , t );glVertex2f (x , y );
483 glTexCoord2f (s+u, t );glVertex2f (x+w, y );
484 glTexCoord2f (s+u, t+v);glVertex2f (x+w, y+h);
485 glTexCoord2f (s , t+v);glVertex2f (x , y+h);
496 if (!v_hwgamma.integer)
498 glDisable(GL_TEXTURE_2D);
500 t = v_contrast.value * (float) (1 << v_overbrightbits.integer);
503 glBlendFunc (GL_DST_COLOR, GL_ONE);
505 glBegin (GL_TRIANGLES);
511 glColor3f (t-1, t-1, t-1);
512 glVertex2f (-5000, -5000);
513 glVertex2f (10000, -5000);
514 glVertex2f (-5000, 10000);
522 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
524 glBegin(GL_TRIANGLES);
526 glVertex2f(-5000, -5000);
527 glVertex2f(10000, -5000);
528 glVertex2f(-5000, 10000);
532 if (v_brightness.value >= 0.01f)
534 glBlendFunc (GL_ONE, GL_ONE);
536 glColor3f (v_brightness.value, v_brightness.value, v_brightness.value);
538 glBegin (GL_TRIANGLES);
539 glVertex2f (-5000, -5000);
540 glVertex2f (10000, -5000);
541 glVertex2f (-5000, 10000);
545 glEnable(GL_TEXTURE_2D);
549 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
551 glEnable (GL_CULL_FACE);
553 glEnable (GL_DEPTH_TEST);