Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

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