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 GL_BrightenScreen(void)
308 if (r_brightness.value < 0.1f)
309 Cvar_SetValue("r_brightness", 0.1f);
310 if (r_brightness.value > 5.0f)
311 Cvar_SetValue("r_brightness", 5.0f);
313 if (r_contrast.value < 0.2f)
314 Cvar_SetValue("r_contrast", 0.2f);
315 if (r_contrast.value > 1.0f)
316 Cvar_SetValue("r_contrast", 1.0f);
318 if (!(lighthalf && !hardwaregammasupported) && r_brightness.value < 1.01f && r_contrast.value > 0.99f)
321 if (!r_render.integer)
324 glDisable(GL_TEXTURE_2D);
328 f = r_brightness.value;
329 // only apply lighthalf using software color correction if hardware is not available (speed reasons)
330 if (lighthalf && !hardwaregammasupported)
334 glBlendFunc (GL_DST_COLOR, GL_ONE);
336 glBegin (GL_TRIANGLES);
342 glColor3f (f-1, f-1, f-1);
343 glVertex2f (-5000, -5000);
344 glVertex2f (10000, -5000);
345 glVertex2f (-5000, 10000);
351 if (r_contrast.value <= 0.99f)
353 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
355 if (lighthalf && hardwaregammasupported)
356 glColor4f (0.5, 0.5, 0.5, 1 - r_contrast.value);
358 glColor4f (1, 1, 1, 1 - r_contrast.value);
360 glBegin (GL_TRIANGLES);
361 glVertex2f (-5000, -5000);
362 glVertex2f (10000, -5000);
363 glVertex2f (-5000, 10000);
367 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
370 glEnable (GL_CULL_FACE);
372 glEnable (GL_DEPTH_TEST);
376 glEnable(GL_TEXTURE_2D);
380 void R_DrawQueue(void)
382 int pos, num, chartexnum;
383 float x, y, w, h, s, t, u, v;
386 char *str, *currentpic;
390 if (!r_render.integer)
393 glViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight);
395 glMatrixMode(GL_PROJECTION);
397 glOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999);
399 glMatrixMode(GL_MODELVIEW);
402 glDisable(GL_DEPTH_TEST);
403 glDisable(GL_CULL_FACE);
404 glDisable(GL_ALPHA_TEST);
406 glEnable(GL_TEXTURE_2D);
407 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
409 chartexnum = R_GetTexture(char_texture);
412 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
415 glBindTexture(GL_TEXTURE_2D, 0);
419 // LordHavoc: NEAREST mode on text if not scaling up
421 if (vid.realwidth <= (int) vid.conwidth)
423 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
425 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
430 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
432 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
438 for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size)
440 dq = (drawqueue_t *)(r_refdef.drawqueue + pos);
441 if (dq->flags & DRAWFLAG_ADDITIVE)
451 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
464 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
467 if (color != dq->color)
471 glColor4ub((byte)((color >> 25) & 0x7F), (byte)((color >> 17) & 0x7F), (byte)((color >> 9) & 0x7F), (byte)(color & 0xFF));
473 glColor4ub((byte)((color >> 24) & 0xFF), (byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF));
482 str = (char *)(dq + 1);
485 if (strcmp(str, currentpic))
493 pic = Draw_CachePic(str);
494 glBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex));
505 //DrawQuad(dq->x, dq->y, w, h, 0, 0, 1, 1);
506 glTexCoord2f (0, 0);glVertex2f (x , y );
507 glTexCoord2f (1, 0);glVertex2f (x+w, y );
508 glTexCoord2f (1, 1);glVertex2f (x+w, y+h);
509 glTexCoord2f (0, 1);glVertex2f (x , y+h);
521 glBindTexture(GL_TEXTURE_2D, 0);
528 //DrawQuad(dq->x, dq->y, dq->scalex, dq->scaley, 0, 0, 1, 1);
529 glTexCoord2f (0, 0);glVertex2f (x , y );
530 glTexCoord2f (1, 0);glVertex2f (x+w, y );
531 glTexCoord2f (1, 1);glVertex2f (x+w, y+h);
532 glTexCoord2f (0, 1);glVertex2f (x , y+h);
535 case DRAWQUEUE_STRING:
536 str = (char *)(dq + 1);
537 if (strcmp("conchars", currentpic))
544 currentpic = "conchars";
545 glBindTexture(GL_TEXTURE_2D, chartexnum);
552 while ((num = *str++) && x < vid.conwidth)
556 s = (num & 15)*0.0625f + (0.5f / 256.0f);
557 t = (num >> 4)*0.0625f + (0.5f / 256.0f);
558 u = 0.0625f - (1.0f / 256.0f);
559 v = 0.0625f - (1.0f / 256.0f);
560 //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));
561 glTexCoord2f (s , t );glVertex2f (x , y );
562 glTexCoord2f (s+u, t );glVertex2f (x+w, y );
563 glTexCoord2f (s+u, t+v);glVertex2f (x+w, y+h);
564 glTexCoord2f (s , t+v);glVertex2f (x , y+h);
574 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);