gl_draw.c (8459B)
1 /* 2 Copyright (C) 1997-2001 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 // draw.c 22 23 #include "gl_local.h" 24 25 image_t *draw_chars; 26 27 extern qboolean scrap_dirty; 28 void Scrap_Upload (void); 29 30 31 /* 32 =============== 33 Draw_InitLocal 34 =============== 35 */ 36 void Draw_InitLocal (void) 37 { 38 // load console characters (don't bilerp characters) 39 draw_chars = GL_FindImage ("pics/conchars.pcx", it_pic); 40 GL_Bind( draw_chars->texnum ); 41 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 42 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 43 } 44 45 46 47 /* 48 ================ 49 Draw_Char 50 51 Draws one 8*8 graphics character with 0 being transparent. 52 It can be clipped to the top of the screen to allow the console to be 53 smoothly scrolled off. 54 ================ 55 */ 56 void Draw_Char (int x, int y, int num) 57 { 58 int row, col; 59 float frow, fcol, size; 60 61 num &= 255; 62 63 if ( (num&127) == 32 ) 64 return; // space 65 66 if (y <= -8) 67 return; // totally off screen 68 69 row = num>>4; 70 col = num&15; 71 72 frow = row*0.0625; 73 fcol = col*0.0625; 74 size = 0.0625; 75 76 GL_Bind (draw_chars->texnum); 77 78 qglBegin (GL_QUADS); 79 qglTexCoord2f (fcol, frow); 80 qglVertex2f (x, y); 81 qglTexCoord2f (fcol + size, frow); 82 qglVertex2f (x+8, y); 83 qglTexCoord2f (fcol + size, frow + size); 84 qglVertex2f (x+8, y+8); 85 qglTexCoord2f (fcol, frow + size); 86 qglVertex2f (x, y+8); 87 qglEnd (); 88 } 89 90 /* 91 ============= 92 Draw_FindPic 93 ============= 94 */ 95 image_t *Draw_FindPic (char *name) 96 { 97 image_t *gl; 98 char fullname[MAX_QPATH]; 99 100 if (name[0] != '/' && name[0] != '\\') 101 { 102 Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name); 103 gl = GL_FindImage (fullname, it_pic); 104 } 105 else 106 gl = GL_FindImage (name+1, it_pic); 107 108 return gl; 109 } 110 111 /* 112 ============= 113 Draw_GetPicSize 114 ============= 115 */ 116 void Draw_GetPicSize (int *w, int *h, char *pic) 117 { 118 image_t *gl; 119 120 gl = Draw_FindPic (pic); 121 if (!gl) 122 { 123 *w = *h = -1; 124 return; 125 } 126 *w = gl->width; 127 *h = gl->height; 128 } 129 130 /* 131 ============= 132 Draw_StretchPic 133 ============= 134 */ 135 void Draw_StretchPic (int x, int y, int w, int h, char *pic) 136 { 137 image_t *gl; 138 139 gl = Draw_FindPic (pic); 140 if (!gl) 141 { 142 ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", pic); 143 return; 144 } 145 146 if (scrap_dirty) 147 Scrap_Upload (); 148 149 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) 150 qglDisable (GL_ALPHA_TEST); 151 152 GL_Bind (gl->texnum); 153 qglBegin (GL_QUADS); 154 qglTexCoord2f (gl->sl, gl->tl); 155 qglVertex2f (x, y); 156 qglTexCoord2f (gl->sh, gl->tl); 157 qglVertex2f (x+w, y); 158 qglTexCoord2f (gl->sh, gl->th); 159 qglVertex2f (x+w, y+h); 160 qglTexCoord2f (gl->sl, gl->th); 161 qglVertex2f (x, y+h); 162 qglEnd (); 163 164 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) 165 qglEnable (GL_ALPHA_TEST); 166 } 167 168 169 /* 170 ============= 171 Draw_Pic 172 ============= 173 */ 174 void Draw_Pic (int x, int y, char *pic) 175 { 176 image_t *gl; 177 178 gl = Draw_FindPic (pic); 179 if (!gl) 180 { 181 ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", pic); 182 return; 183 } 184 if (scrap_dirty) 185 Scrap_Upload (); 186 187 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) 188 qglDisable (GL_ALPHA_TEST); 189 190 GL_Bind (gl->texnum); 191 qglBegin (GL_QUADS); 192 qglTexCoord2f (gl->sl, gl->tl); 193 qglVertex2f (x, y); 194 qglTexCoord2f (gl->sh, gl->tl); 195 qglVertex2f (x+gl->width, y); 196 qglTexCoord2f (gl->sh, gl->th); 197 qglVertex2f (x+gl->width, y+gl->height); 198 qglTexCoord2f (gl->sl, gl->th); 199 qglVertex2f (x, y+gl->height); 200 qglEnd (); 201 202 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha) 203 qglEnable (GL_ALPHA_TEST); 204 } 205 206 /* 207 ============= 208 Draw_TileClear 209 210 This repeats a 64*64 tile graphic to fill the screen around a sized down 211 refresh window. 212 ============= 213 */ 214 void Draw_TileClear (int x, int y, int w, int h, char *pic) 215 { 216 image_t *image; 217 218 image = Draw_FindPic (pic); 219 if (!image) 220 { 221 ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", pic); 222 return; 223 } 224 225 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !image->has_alpha) 226 qglDisable (GL_ALPHA_TEST); 227 228 GL_Bind (image->texnum); 229 qglBegin (GL_QUADS); 230 qglTexCoord2f (x/64.0, y/64.0); 231 qglVertex2f (x, y); 232 qglTexCoord2f ( (x+w)/64.0, y/64.0); 233 qglVertex2f (x+w, y); 234 qglTexCoord2f ( (x+w)/64.0, (y+h)/64.0); 235 qglVertex2f (x+w, y+h); 236 qglTexCoord2f ( x/64.0, (y+h)/64.0 ); 237 qglVertex2f (x, y+h); 238 qglEnd (); 239 240 if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !image->has_alpha) 241 qglEnable (GL_ALPHA_TEST); 242 } 243 244 245 /* 246 ============= 247 Draw_Fill 248 249 Fills a box of pixels with a single color 250 ============= 251 */ 252 void Draw_Fill (int x, int y, int w, int h, int c) 253 { 254 union 255 { 256 unsigned c; 257 byte v[4]; 258 } color; 259 260 if ( (unsigned)c > 255) 261 ri.Sys_Error (ERR_FATAL, "Draw_Fill: bad color"); 262 263 qglDisable (GL_TEXTURE_2D); 264 265 color.c = d_8to24table[c]; 266 qglColor3f (color.v[0]/255.0, 267 color.v[1]/255.0, 268 color.v[2]/255.0); 269 270 qglBegin (GL_QUADS); 271 272 qglVertex2f (x,y); 273 qglVertex2f (x+w, y); 274 qglVertex2f (x+w, y+h); 275 qglVertex2f (x, y+h); 276 277 qglEnd (); 278 qglColor3f (1,1,1); 279 qglEnable (GL_TEXTURE_2D); 280 } 281 282 //============================================================================= 283 284 /* 285 ================ 286 Draw_FadeScreen 287 288 ================ 289 */ 290 void Draw_FadeScreen (void) 291 { 292 qglEnable (GL_BLEND); 293 qglDisable (GL_TEXTURE_2D); 294 qglColor4f (0, 0, 0, 0.8); 295 qglBegin (GL_QUADS); 296 297 qglVertex2f (0,0); 298 qglVertex2f (vid.width, 0); 299 qglVertex2f (vid.width, vid.height); 300 qglVertex2f (0, vid.height); 301 302 qglEnd (); 303 qglColor4f (1,1,1,1); 304 qglEnable (GL_TEXTURE_2D); 305 qglDisable (GL_BLEND); 306 } 307 308 309 //==================================================================== 310 311 312 /* 313 ============= 314 Draw_StretchRaw 315 ============= 316 */ 317 extern unsigned r_rawpalette[256]; 318 319 void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data) 320 { 321 unsigned image32[256*256]; 322 unsigned char image8[256*256]; 323 int i, j, trows; 324 byte *source; 325 int frac, fracstep; 326 float hscale; 327 int row; 328 float t; 329 330 GL_Bind (0); 331 332 if (rows<=256) 333 { 334 hscale = 1; 335 trows = rows; 336 } 337 else 338 { 339 hscale = rows/256.0; 340 trows = 256; 341 } 342 t = rows*hscale / 256; 343 344 if ( !qglColorTableEXT ) 345 { 346 unsigned *dest; 347 348 for (i=0 ; i<trows ; i++) 349 { 350 row = (int)(i*hscale); 351 if (row > rows) 352 break; 353 source = data + cols*row; 354 dest = &image32[i*256]; 355 fracstep = cols*0x10000/256; 356 frac = fracstep >> 1; 357 for (j=0 ; j<256 ; j++) 358 { 359 dest[j] = r_rawpalette[source[frac>>16]]; 360 frac += fracstep; 361 } 362 } 363 364 qglTexImage2D (GL_TEXTURE_2D, 0, gl_tex_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image32); 365 } 366 else 367 { 368 unsigned char *dest; 369 370 for (i=0 ; i<trows ; i++) 371 { 372 row = (int)(i*hscale); 373 if (row > rows) 374 break; 375 source = data + cols*row; 376 dest = &image8[i*256]; 377 fracstep = cols*0x10000/256; 378 frac = fracstep >> 1; 379 for (j=0 ; j<256 ; j++) 380 { 381 dest[j] = source[frac>>16]; 382 frac += fracstep; 383 } 384 } 385 386 qglTexImage2D( GL_TEXTURE_2D, 387 0, 388 GL_COLOR_INDEX8_EXT, 389 256, 256, 390 0, 391 GL_COLOR_INDEX, 392 GL_UNSIGNED_BYTE, 393 image8 ); 394 } 395 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 396 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 397 398 if ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) 399 qglDisable (GL_ALPHA_TEST); 400 401 qglBegin (GL_QUADS); 402 qglTexCoord2f (0, 0); 403 qglVertex2f (x, y); 404 qglTexCoord2f (1, 0); 405 qglVertex2f (x+w, y); 406 qglTexCoord2f (1, t); 407 qglVertex2f (x+w, y+h); 408 qglTexCoord2f (0, t); 409 qglVertex2f (x, y+h); 410 qglEnd (); 411 412 if ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) 413 qglEnable (GL_ALPHA_TEST); 414 } 415