2000-05-10 20:33:16 +00:00
|
|
|
/*
|
2000-05-11 16:03:29 +00:00
|
|
|
gl_draw.c
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-12 16:16:29 +00:00
|
|
|
Draw functions for chars, textures, etc
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
$Id$
|
|
|
|
*/
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-05-17 10:03:19 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2000-05-23 17:05:34 +00:00
|
|
|
# include "config.h"
|
2000-05-17 10:03:19 +00:00
|
|
|
#endif
|
2000-05-23 17:05:34 +00:00
|
|
|
|
2000-05-12 16:16:29 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2000-05-26 03:55:27 +00:00
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
#include <strings.h>
|
|
|
|
#endif
|
2000-05-12 16:16:29 +00:00
|
|
|
|
|
|
|
#include "cmd.h"
|
|
|
|
#include "console.h"
|
2000-12-30 02:16:36 +00:00
|
|
|
#include "crc.h"
|
|
|
|
#include "draw.h"
|
2000-05-12 16:16:29 +00:00
|
|
|
#include "glquake.h"
|
2000-12-30 02:16:36 +00:00
|
|
|
#include "sbar.h"
|
|
|
|
#include "sys.h"
|
2000-05-12 16:16:29 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static int GL_LoadPicTexture (qpic_t *pic);
|
2000-06-26 02:35:40 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
extern byte *host_basepal;
|
2000-05-10 11:29:38 +00:00
|
|
|
extern unsigned char d_15to8table[65536];
|
2000-12-08 06:51:37 +00:00
|
|
|
extern cvar_t *crosshair, *cl_crossx, *cl_crossy, *crosshaircolor,
|
2000-05-16 04:47:41 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
*gl_colorlights;
|
2000-05-16 04:47:41 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
cvar_t *gl_max_size;
|
|
|
|
cvar_t *gl_picmip;
|
2000-05-13 20:51:02 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
cvar_t *gl_constretch;
|
|
|
|
cvar_t *gl_conalpha;
|
|
|
|
cvar_t *gl_conspin;
|
|
|
|
cvar_t *cl_verstring;
|
|
|
|
cvar_t *gl_lightmode; // LordHavoc: lighting mode
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-09 23:26:27 +00:00
|
|
|
byte *draw_chars; // 8*8 graphic characters
|
2000-12-08 06:51:37 +00:00
|
|
|
qpic_t *draw_disc;
|
|
|
|
qpic_t *draw_backtile;
|
|
|
|
|
|
|
|
static int translate_texture;
|
|
|
|
static int char_texture;
|
|
|
|
static int cs_texture; // crosshair texturea
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
static byte cs_data[64] = {
|
|
|
|
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
typedef struct {
|
|
|
|
int texnum;
|
|
|
|
int bytesperpixel;
|
|
|
|
float sl, tl, sh, th;
|
2000-05-10 11:29:38 +00:00
|
|
|
} glpic_t;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
int gl_lightmap_format = 4;
|
|
|
|
int gl_solid_format = 3;
|
|
|
|
int gl_alpha_format = 4;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
|
|
|
|
static int gl_filter_max = GL_LINEAR;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
typedef struct {
|
|
|
|
int texnum;
|
|
|
|
char identifier[64];
|
|
|
|
int width, height;
|
|
|
|
int bytesperpixel;
|
|
|
|
qboolean mipmap;
|
|
|
|
unsigned short crc; // LordHavoc: CRC for texture
|
|
|
|
// validation
|
2000-05-10 11:29:38 +00:00
|
|
|
} gltexture_t;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static gltexture_t gltextures[MAX_GLTEXTURES];
|
|
|
|
static int numgltextures = 0;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
=============================================================================
|
|
|
|
|
|
|
|
scrap allocation
|
|
|
|
|
|
|
|
Allocate all the little status bar obejcts into a single texture
|
|
|
|
to crutch up stupid hardware / drivers
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
Note, this is a kluge, which may slow down sane cards..
|
|
|
|
As such its all contained in ifdefs..
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
=============================================================================
|
|
|
|
*/
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#undef gl_draw_scraps
|
|
|
|
|
|
|
|
#ifdef gl_draw_scraps
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
#define MAX_SCRAPS 1
|
|
|
|
#define BLOCK_WIDTH 256
|
|
|
|
#define BLOCK_HEIGHT 256
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
|
|
|
|
static byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT * 4];
|
|
|
|
static qboolean scrap_dirty;
|
|
|
|
static int scrap_texnum;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// returns a texture number and the position inside it
|
2000-12-08 06:51:37 +00:00
|
|
|
static int
|
|
|
|
Scrap_AllocBlock (int w, int h, int *x, int *y)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, j;
|
|
|
|
int best, best2;
|
|
|
|
int texnum;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (texnum = 0; texnum < MAX_SCRAPS; texnum++) {
|
2000-05-10 11:29:38 +00:00
|
|
|
best = BLOCK_HEIGHT;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < BLOCK_WIDTH - w; i++) {
|
2000-05-10 11:29:38 +00:00
|
|
|
best2 = 0;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (j = 0; j < w; j++) {
|
|
|
|
if (scrap_allocated[texnum][i + j] >= best)
|
2000-05-10 11:29:38 +00:00
|
|
|
break;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (scrap_allocated[texnum][i + j] > best2)
|
|
|
|
best2 = scrap_allocated[texnum][i + j];
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
if (j == w) { // this is a valid spot
|
2000-05-10 11:29:38 +00:00
|
|
|
*x = i;
|
|
|
|
*y = best = best2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (best + h > BLOCK_HEIGHT)
|
|
|
|
continue;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < w; i++)
|
2000-05-10 11:29:38 +00:00
|
|
|
scrap_allocated[texnum][*x + i] = best + h;
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
scrap_dirty = true;
|
2000-05-10 11:29:38 +00:00
|
|
|
return texnum;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sys_Error ("Scrap_AllocBlock: full");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
Scrap_Upload (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, scrap_texnum);
|
2000-05-10 11:29:38 +00:00
|
|
|
GL_Upload8 (scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
|
|
|
|
scrap_dirty = false;
|
|
|
|
}
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
//=============================================================================
|
|
|
|
/* Support Routines */
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
typedef struct cachepic_s {
|
|
|
|
char name[MAX_QPATH];
|
|
|
|
qboolean dirty;
|
|
|
|
qpic_t pic;
|
|
|
|
byte padding[32]; // for appended glpic
|
2000-05-10 11:29:38 +00:00
|
|
|
} cachepic_t;
|
|
|
|
|
|
|
|
#define MAX_CACHED_PICS 128
|
2000-12-08 06:51:37 +00:00
|
|
|
static cachepic_t cachepics[MAX_CACHED_PICS];
|
|
|
|
static int numcachepics;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-29 03:14:53 +00:00
|
|
|
static byte menuplyr_pixels[4096];
|
|
|
|
|
2000-12-12 02:46:46 +00:00
|
|
|
qpic_t *
|
2000-12-08 06:51:37 +00:00
|
|
|
Draw_PicFromWad (char *name)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
qpic_t *p;
|
|
|
|
glpic_t *gl;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
p = W_GetLumpName (name);
|
2000-12-08 06:51:37 +00:00
|
|
|
gl = (glpic_t *) p->data;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#ifdef gl_draw_scraps
|
2000-05-10 11:29:38 +00:00
|
|
|
// load little ones into the scrap
|
2000-08-14 04:53:45 +00:00
|
|
|
if (p->width < 64 && p->height < 64) {
|
2000-12-08 06:51:37 +00:00
|
|
|
int x, y;
|
|
|
|
int i, j, k;
|
|
|
|
int texnum;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
|
|
|
|
k = 0;
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < p->height; i++)
|
|
|
|
for (j = 0; j < p->width; j++, k++)
|
|
|
|
scrap_texels[texnum][(y + i) * BLOCK_WIDTH + x + j] =
|
|
|
|
p->data[k];
|
2000-05-10 11:29:38 +00:00
|
|
|
texnum += scrap_texnum;
|
|
|
|
gl->texnum = texnum;
|
2000-12-08 06:51:37 +00:00
|
|
|
gl->sl = (x + 0.01) / (float) BLOCK_WIDTH;
|
|
|
|
gl->sh = (x + p->width - 0.01) / (float) BLOCK_WIDTH;
|
|
|
|
gl->tl = (y + 0.01) / (float) BLOCK_WIDTH;
|
|
|
|
gl->th = (y + p->height - 0.01) / (float) BLOCK_WIDTH;
|
|
|
|
} else
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
gl->texnum = GL_LoadPicTexture (p);
|
|
|
|
gl->sl = 0;
|
|
|
|
gl->sh = 1;
|
|
|
|
gl->tl = 0;
|
|
|
|
gl->th = 1;
|
|
|
|
}
|
2000-08-14 04:53:45 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2000-06-23 18:36:59 +00:00
|
|
|
void
|
|
|
|
Draw_ClearCache (void)
|
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
cachepic_t *pic;
|
|
|
|
int i;
|
2000-06-23 18:36:59 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (pic = cachepics, i = 0; i < numcachepics; pic++, i++)
|
2000-06-23 18:36:59 +00:00
|
|
|
pic->dirty = true;
|
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Draw_CachePic
|
|
|
|
================
|
|
|
|
*/
|
2000-12-12 02:46:46 +00:00
|
|
|
qpic_t *
|
2000-12-08 06:51:37 +00:00
|
|
|
Draw_CachePic (char *path)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
cachepic_t *pic;
|
|
|
|
int i;
|
|
|
|
qpic_t *dat;
|
|
|
|
glpic_t *gl;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// First, check and see if its cached..
|
2000-12-08 06:51:37 +00:00
|
|
|
for (pic = cachepics, i = 0; i < numcachepics; pic++, i++)
|
2000-08-14 04:53:45 +00:00
|
|
|
if ((!strcmp (path, pic->name)) && !pic->dirty)
|
|
|
|
return &pic->pic;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Its not cached, lets make sure we have space in the cache..
|
|
|
|
if (numcachepics == MAX_CACHED_PICS)
|
2000-12-29 03:14:53 +00:00
|
|
|
Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Load the picture..
|
2000-12-08 06:51:37 +00:00
|
|
|
dat = (qpic_t *) COM_LoadTempFile (path);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (!dat)
|
|
|
|
Sys_Error ("Draw_CachePic: failed to load %s", path);
|
2000-08-14 04:53:45 +00:00
|
|
|
|
|
|
|
// Adjust for endian..
|
2000-05-10 11:29:38 +00:00
|
|
|
SwapPic (dat);
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Ok, the image is here, lets load it up into the cache..
|
|
|
|
|
|
|
|
// First the image name..
|
2000-12-08 06:51:37 +00:00
|
|
|
strncpy (pic->name, path, sizeof (pic->name));
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Now the width and height.
|
2000-05-10 11:29:38 +00:00
|
|
|
pic->pic.width = dat->width;
|
|
|
|
pic->pic.height = dat->height;
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Now feed it to the GL stuff and get a texture number..
|
2000-12-08 06:51:37 +00:00
|
|
|
gl = (glpic_t *) pic->pic.data;
|
2000-05-10 11:29:38 +00:00
|
|
|
gl->texnum = GL_LoadPicTexture (dat);
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// Alignment stuff..
|
2000-12-08 06:51:37 +00:00
|
|
|
gl->sl = 0;
|
|
|
|
gl->sh = 1;
|
|
|
|
gl->tl = 0;
|
|
|
|
gl->th = 1;
|
2000-08-14 04:53:45 +00:00
|
|
|
|
|
|
|
// Now lets mark this cache entry as used..
|
|
|
|
pic->dirty = false;
|
|
|
|
numcachepics++;
|
|
|
|
|
2000-12-29 03:14:53 +00:00
|
|
|
// FIXME:
|
|
|
|
// A really ugly kluge, keep a specific image in memory
|
|
|
|
// for the menu system.
|
|
|
|
//
|
|
|
|
// Some days I really dislike legacy support..
|
|
|
|
|
|
|
|
if (!strcmp (path, "gfx/menuplyr.lmp"))
|
|
|
|
memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
// And now we are done, return what was asked for..
|
2000-05-10 11:29:38 +00:00
|
|
|
return &pic->pic;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
typedef struct {
|
|
|
|
char *name;
|
|
|
|
int minimize, maximize;
|
2000-05-10 11:29:38 +00:00
|
|
|
} glmode_t;
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
static glmode_t modes[] = {
|
2000-05-10 11:29:38 +00:00
|
|
|
{"GL_NEAREST", GL_NEAREST, GL_NEAREST},
|
|
|
|
{"GL_LINEAR", GL_LINEAR, GL_LINEAR},
|
|
|
|
{"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
|
|
|
|
{"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
|
|
|
|
{"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
|
|
|
|
{"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Draw_TextureMode_f
|
|
|
|
===============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
Draw_TextureMode_f (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i;
|
|
|
|
gltexture_t *glt;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
if (Cmd_Argc () == 1) {
|
|
|
|
for (i = 0; i < 6; i++)
|
|
|
|
if (gl_filter_min == modes[i].minimize) {
|
2000-05-10 11:29:38 +00:00
|
|
|
Con_Printf ("%s\n", modes[i].name);
|
|
|
|
return;
|
|
|
|
}
|
2000-12-07 17:08:38 +00:00
|
|
|
Con_Printf ("current filter is unknown?\n");
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
if (!stricmp (modes[i].name, Cmd_Argv (1)))
|
2000-05-10 11:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
if (i == 6) {
|
2000-05-10 11:29:38 +00:00
|
|
|
Con_Printf ("bad filter name\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gl_filter_min = modes[i].minimize;
|
|
|
|
gl_filter_max = modes[i].maximize;
|
|
|
|
|
|
|
|
// change all the existing mipmap texture objects
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0, glt = gltextures; i < numgltextures; i++, glt++) {
|
|
|
|
if (glt->mipmap) {
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, glt->texnum);
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
|
|
gl_filter_min);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
|
|
gl_filter_max);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-12 02:46:46 +00:00
|
|
|
void
|
|
|
|
Draw_TextBox (int x, int y, int width, int lines)
|
|
|
|
{
|
|
|
|
qpic_t *p;
|
|
|
|
int cx, cy;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
// draw left side
|
|
|
|
cx = x;
|
|
|
|
cy = y;
|
|
|
|
p = Draw_CachePic ("gfx/box_tl.lmp");
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
p = Draw_CachePic ("gfx/box_ml.lmp");
|
|
|
|
for (n = 0; n < lines; n++) {
|
|
|
|
cy += 8;
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
}
|
|
|
|
p = Draw_CachePic ("gfx/box_bl.lmp");
|
|
|
|
Draw_Pic (cx, cy + 8, p);
|
|
|
|
|
|
|
|
// draw middle
|
|
|
|
cx += 8;
|
|
|
|
while (width > 0) {
|
|
|
|
cy = y;
|
|
|
|
p = Draw_CachePic ("gfx/box_tm.lmp");
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
p = Draw_CachePic ("gfx/box_mm.lmp");
|
|
|
|
for (n = 0; n < lines; n++) {
|
|
|
|
cy += 8;
|
|
|
|
if (n == 1)
|
|
|
|
p = Draw_CachePic ("gfx/box_mm2.lmp");
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
}
|
|
|
|
p = Draw_CachePic ("gfx/box_bm.lmp");
|
|
|
|
Draw_Pic (cx, cy + 8, p);
|
|
|
|
width -= 2;
|
|
|
|
cx += 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw right side
|
|
|
|
cy = y;
|
|
|
|
p = Draw_CachePic ("gfx/box_tr.lmp");
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
p = Draw_CachePic ("gfx/box_mr.lmp");
|
|
|
|
for (n = 0; n < lines; n++) {
|
|
|
|
cy += 8;
|
|
|
|
Draw_Pic (cx, cy, p);
|
|
|
|
}
|
|
|
|
p = Draw_CachePic ("gfx/box_br.lmp");
|
|
|
|
Draw_Pic (cx, cy + 8, p);
|
|
|
|
}
|
|
|
|
|
2000-12-28 09:30:32 +00:00
|
|
|
extern void glrmain_init (void);
|
|
|
|
extern void glrsurf_init (void);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Draw_Init
|
|
|
|
===============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Init (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// 3dfx can only handle 256 wide textures
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!strncasecmp ((char *) gl_renderer, "3dfx", 4) ||
|
|
|
|
!strncasecmp ((char *) gl_renderer, "Mesa", 4))
|
2000-05-17 23:16:23 +00:00
|
|
|
Cvar_Set (gl_max_size, "256");
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
// LordHavoc: 3DFX's dithering has terrible artifacting when using
|
|
|
|
// lightmode 1
|
|
|
|
if (!strncasecmp ((char *) gl_renderer, "3dfx", 4))
|
2000-07-02 05:16:10 +00:00
|
|
|
Cvar_Set (gl_lightmode, "0");
|
2000-12-08 06:51:37 +00:00
|
|
|
lighthalf = gl_lightmode->int_val != 0; // to avoid re-rendering all
|
|
|
|
// lightmaps on first frame
|
2000-09-28 00:22:24 +00:00
|
|
|
if (lighthalf) {
|
|
|
|
lighthalf_v[0] = lighthalf_v[1] = lighthalf_v[2] = 128;
|
|
|
|
} else {
|
|
|
|
lighthalf_v[0] = lighthalf_v[1] = lighthalf_v[2] = 255;
|
|
|
|
}
|
2000-07-02 05:16:10 +00:00
|
|
|
|
2001-01-15 17:07:06 +00:00
|
|
|
Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f, "No Description");
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// load the console background and the charset
|
|
|
|
// by hand, because we need to write the version
|
|
|
|
// string into the background before turning
|
|
|
|
// it into a texture
|
|
|
|
draw_chars = W_GetLumpName ("conchars");
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < 256 * 64; i++)
|
2000-05-10 11:29:38 +00:00
|
|
|
if (draw_chars[i] == 0)
|
2000-12-08 06:51:37 +00:00
|
|
|
draw_chars[i] = 255; // proper transparent color
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// now turn them into textures
|
2000-12-20 21:59:56 +00:00
|
|
|
char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1); // 1999-12-27 Conwidth/height charset fix by TcT
|
2000-09-22 09:12:03 +00:00
|
|
|
cs_texture = GL_LoadTexture ("crosshair", 8, 8, cs_data, false, true, 1);
|
2000-12-08 06:51:37 +00:00
|
|
|
// char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1); // 1999-12-27 Conwidth/height charset fix by TcT
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// save a texture slot for translated picture
|
|
|
|
translate_texture = texture_extension_number++;
|
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#ifdef gl_draw_scraps
|
2000-05-10 11:29:38 +00:00
|
|
|
// save slots for scraps
|
|
|
|
scrap_texnum = texture_extension_number;
|
|
|
|
texture_extension_number += MAX_SCRAPS;
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
//
|
2000-05-10 11:29:38 +00:00
|
|
|
// get the other pics we need
|
2000-12-08 06:51:37 +00:00
|
|
|
//
|
2000-05-10 11:29:38 +00:00
|
|
|
draw_disc = Draw_PicFromWad ("disc");
|
|
|
|
draw_backtile = Draw_PicFromWad ("backtile");
|
2000-07-02 05:16:10 +00:00
|
|
|
|
|
|
|
// LordHavoc: call init code for other GL renderer modules;
|
2000-12-08 06:51:37 +00:00
|
|
|
glrmain_init ();
|
|
|
|
glrsurf_init ();
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Init_Cvars (void)
|
2000-10-29 15:35:24 +00:00
|
|
|
{
|
|
|
|
// LordHavoc: lighting mode
|
2000-12-08 06:51:37 +00:00
|
|
|
gl_lightmode = Cvar_Get ("gl_lightmode", "1", CVAR_ARCHIVE,
|
|
|
|
"Lighting mode (0 = GLQuake style, 1 = new style)");
|
2000-12-31 04:46:04 +00:00
|
|
|
gl_max_size = Cvar_Get ("gl_max_size", "1024", CVAR_NONE, "Texture dimension");
|
|
|
|
|
|
|
|
gl_picmip = Cvar_Get ("gl_picmip", "0", CVAR_NONE, "Dimensions of displayed textures. 0 is normal, 1 is half, 2 is 1/4");
|
|
|
|
|
2000-10-29 15:35:24 +00:00
|
|
|
gl_colorlights = Cvar_Get ("gl_colorlights", "1", CVAR_ROM,
|
2000-12-08 06:51:37 +00:00
|
|
|
"Whether to use RGB lightmaps or not");
|
2000-10-29 15:35:24 +00:00
|
|
|
|
|
|
|
// Console effects --KB
|
|
|
|
gl_constretch = Cvar_Get ("gl_constretch", "0", CVAR_ARCHIVE,
|
2000-12-08 06:51:37 +00:00
|
|
|
"whether slide the console or stretch it");
|
2000-10-29 15:35:24 +00:00
|
|
|
gl_conalpha = Cvar_Get ("gl_conalpha", "0.6", CVAR_ARCHIVE,
|
2000-12-08 06:51:37 +00:00
|
|
|
"alpha value for the console background");
|
2000-10-29 15:35:24 +00:00
|
|
|
gl_conspin = Cvar_Get ("gl_conspin", "0", CVAR_ARCHIVE,
|
2000-12-08 06:51:37 +00:00
|
|
|
"speed at which the console spins");
|
2000-10-29 15:35:24 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
cl_verstring = Cvar_Get ("cl_verstring", PROGRAM " " VERSION, CVAR_NONE,
|
2000-12-31 04:46:04 +00:00
|
|
|
"Client version string");
|
2000-10-29 15:35:24 +00:00
|
|
|
}
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
2000-06-05 01:05:25 +00:00
|
|
|
Draw_Character8
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
Draws one 8*8 graphics character with 0 being transparent.
|
|
|
|
It can be clipped to the top of the screen to allow the console to be
|
|
|
|
smoothly scrolled off.
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Character8 (int x, int y, int num)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int row, col;
|
|
|
|
float frow, fcol, size;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (num == 32)
|
2000-12-08 06:51:37 +00:00
|
|
|
return; // space
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
num &= 255;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
if (y <= -8)
|
2000-12-08 06:51:37 +00:00
|
|
|
return; // totally off screen
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
row = num >> 4;
|
|
|
|
col = num & 15;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
frow = row * 0.0625;
|
|
|
|
fcol = col * 0.0625;
|
2000-05-10 11:29:38 +00:00
|
|
|
size = 0.0625;
|
|
|
|
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, char_texture);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (fcol, frow);
|
|
|
|
glVertex2f (x, y);
|
|
|
|
glTexCoord2f (fcol + size, frow);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + 8, y);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (fcol + size, frow + size);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + 8, y + 8);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (fcol, frow + size);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x, y + 8);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnd ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
2000-06-05 01:05:25 +00:00
|
|
|
Draw_String8
|
2000-05-10 11:29:38 +00:00
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_String8 (int x, int y, char *str)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
while (*str) {
|
2000-06-05 01:05:25 +00:00
|
|
|
Draw_Character8 (x, y, *str);
|
2000-05-10 11:29:38 +00:00
|
|
|
str++;
|
|
|
|
x += 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
2000-06-05 01:05:25 +00:00
|
|
|
Draw_AltString8
|
2000-05-10 11:29:38 +00:00
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_AltString8 (int x, int y, char *str)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
while (*str) {
|
2000-06-05 01:05:25 +00:00
|
|
|
Draw_Character8 (x, y, (*str) | 0x80);
|
2000-05-10 11:29:38 +00:00
|
|
|
str++;
|
|
|
|
x += 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Crosshair (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int x, y;
|
|
|
|
extern vrect_t scr_vrect;
|
2000-05-10 11:29:38 +00:00
|
|
|
unsigned char *pColor;
|
|
|
|
|
2000-10-17 03:17:42 +00:00
|
|
|
switch (crosshair->int_val) {
|
2000-08-31 17:36:02 +00:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
default:
|
2000-12-08 06:51:37 +00:00
|
|
|
Draw_Character8 (scr_vrect.x + scr_vrect.width / 2 - 4 +
|
|
|
|
cl_crossx->int_val,
|
|
|
|
scr_vrect.y + scr_vrect.height / 2 - 4 +
|
|
|
|
cl_crossy->int_val, '+');
|
2000-08-31 17:36:02 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2000-12-08 06:51:37 +00:00
|
|
|
x = scr_vrect.x + scr_vrect.width / 2 - 3 + cl_crossx->int_val;
|
|
|
|
y = scr_vrect.y + scr_vrect.height / 2 - 3 + cl_crossy->int_val;
|
2000-08-31 17:36:02 +00:00
|
|
|
|
2000-10-17 03:17:42 +00:00
|
|
|
pColor = (unsigned char *) &d_8to24table[crosshaircolor->int_val];
|
2000-08-31 17:36:02 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor4ub ((byte) ((int) pColor[0] >> 1),
|
|
|
|
(byte) ((int) pColor[1] >> 1),
|
|
|
|
(byte) ((int) pColor[2] >> 1), pColor[3]);
|
2000-08-31 17:36:02 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor4ubv (pColor);
|
2000-08-31 17:36:02 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, cs_texture);
|
|
|
|
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (0, 0);
|
|
|
|
glVertex2f (x - 4, y - 4);
|
|
|
|
glTexCoord2f (1, 0);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + 12, y - 4);
|
2000-08-31 17:36:02 +00:00
|
|
|
glTexCoord2f (1, 1);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + 12, y + 12);
|
2000-08-31 17:36:02 +00:00
|
|
|
glTexCoord2f (0, 1);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x - 4, y + 12);
|
2000-08-31 17:36:02 +00:00
|
|
|
glEnd ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-08-31 17:36:02 +00:00
|
|
|
break;
|
2000-06-23 18:36:59 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Draw_Pic
|
|
|
|
=============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Pic (int x, int y, qpic_t *pic)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
glpic_t *gl;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#ifdef gl_draw_scraps
|
2000-05-10 11:29:38 +00:00
|
|
|
if (scrap_dirty)
|
|
|
|
Scrap_Upload ();
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
2000-12-08 06:51:37 +00:00
|
|
|
gl = (glpic_t *) pic->data;
|
2000-12-12 02:46:46 +00:00
|
|
|
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
2000-05-10 11:29:38 +00:00
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (gl->sl, gl->tl);
|
|
|
|
glVertex2f (x, y);
|
|
|
|
glTexCoord2f (gl->sh, gl->tl);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + pic->width, y);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (gl->sh, gl->th);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + pic->width, y + pic->height);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (gl->sl, gl->th);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x, y + pic->height);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnd ();
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
|
|
|
|
int height)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
glpic_t *gl;
|
|
|
|
float newsl, newtl, newsh, newth;
|
|
|
|
float oldglwidth, oldglheight;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
#ifdef gl_draw_scraps
|
2000-05-10 11:29:38 +00:00
|
|
|
if (scrap_dirty)
|
|
|
|
Scrap_Upload ();
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
2000-12-08 06:51:37 +00:00
|
|
|
gl = (glpic_t *) pic->data;
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
oldglwidth = gl->sh - gl->sl;
|
|
|
|
oldglheight = gl->th - gl->tl;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
newsl = gl->sl + (srcx * oldglwidth) / pic->width;
|
|
|
|
newsh = newsl + (width * oldglwidth) / pic->width;
|
|
|
|
|
|
|
|
newtl = gl->tl + (srcy * oldglheight) / pic->height;
|
|
|
|
newth = newtl + (height * oldglheight) / pic->height;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-07-02 05:16:10 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
2000-07-02 05:16:10 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
2000-05-10 11:29:38 +00:00
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (newsl, newtl);
|
|
|
|
glVertex2f (x, y);
|
|
|
|
glTexCoord2f (newsh, newtl);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + width, y);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (newsh, newth);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x + width, y + height);
|
2000-05-10 11:29:38 +00:00
|
|
|
glTexCoord2f (newsl, newth);
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x, y + height);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnd ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-29 03:14:53 +00:00
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Draw_TransPicTranslate
|
|
|
|
|
|
|
|
Only used for the player color selection menu
|
|
|
|
=============
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte * translation)
|
|
|
|
{
|
|
|
|
int v, u, c;
|
|
|
|
unsigned int trans[64 * 64], *dest;
|
|
|
|
byte *src;
|
|
|
|
int p;
|
|
|
|
|
|
|
|
glBindTexture (GL_TEXTURE_2D, translate_texture);
|
|
|
|
|
|
|
|
c = pic->width * pic->height;
|
|
|
|
|
|
|
|
dest = trans;
|
|
|
|
for (v = 0; v < 64; v++, dest += 64) {
|
|
|
|
src = &menuplyr_pixels[((v * pic->height) >> 6) * pic->width];
|
|
|
|
for (u = 0; u < 64; u++) {
|
|
|
|
p = src[(u * pic->width) >> 6];
|
|
|
|
if (p == 255)
|
|
|
|
dest[u] = p;
|
|
|
|
else
|
|
|
|
dest[u] = d_8to24table[translation[p]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA,
|
|
|
|
GL_UNSIGNED_BYTE, trans);
|
|
|
|
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
|
|
|
if (lighthalf)
|
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
|
|
|
else
|
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (0, 0);
|
|
|
|
glVertex2f (x, y);
|
|
|
|
glTexCoord2f (1, 0);
|
|
|
|
glVertex2f (x + pic->width, y);
|
|
|
|
glTexCoord2f (1, 1);
|
|
|
|
glVertex2f (x + pic->width, y + pic->height);
|
|
|
|
glTexCoord2f (0, 1);
|
|
|
|
glVertex2f (x, y + pic->height);
|
|
|
|
glEnd ();
|
|
|
|
glColor3ubv (lighthalf_v);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
/*
|
2000-05-29 10:16:04 +00:00
|
|
|
Draw_ConsoleBackground
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-05-29 10:16:04 +00:00
|
|
|
Draws console background (obviously!) Completely rewritten to use
|
|
|
|
several simple yet very cool GL effects. --KB
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_ConsoleBackground (int lines)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int y;
|
|
|
|
qpic_t *conback;
|
|
|
|
glpic_t *gl;
|
|
|
|
float ofs;
|
|
|
|
float alpha;
|
2000-05-29 10:16:04 +00:00
|
|
|
|
|
|
|
// This can be a CachePic now, just like in software
|
|
|
|
conback = Draw_CachePic ("gfx/conback.lmp");
|
2000-12-08 06:51:37 +00:00
|
|
|
gl = (glpic_t *) conback->data;
|
2000-05-29 10:16:04 +00:00
|
|
|
|
|
|
|
// spin the console? - effect described in a QER tutorial
|
2000-12-08 06:51:37 +00:00
|
|
|
if (gl_conspin->value) {
|
2000-05-29 10:16:04 +00:00
|
|
|
static float xangle = 0;
|
|
|
|
static float xfactor = .3f;
|
|
|
|
static float xstep = .005f;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-29 10:16:04 +00:00
|
|
|
glPushMatrix ();
|
|
|
|
glMatrixMode (GL_TEXTURE);
|
|
|
|
glPushMatrix ();
|
|
|
|
glLoadIdentity ();
|
|
|
|
xangle += gl_conspin->value;
|
|
|
|
xfactor += xstep;
|
|
|
|
if (xfactor > 8 || xfactor < .3f)
|
|
|
|
xstep = -xstep;
|
|
|
|
glRotatef (xangle, 0, 0, 1);
|
|
|
|
glScalef (xfactor, xfactor, xfactor);
|
|
|
|
}
|
|
|
|
// slide console up/down or stretch it?
|
2000-10-24 19:32:30 +00:00
|
|
|
if (gl_constretch->int_val)
|
2000-05-29 10:16:04 +00:00
|
|
|
ofs = 0;
|
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
ofs = (vid.conheight - lines) / (float) vid.conheight;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
This is a NON-TRIVIAL update which took LordHavoc and I about 3 days to
make work properly:
Win32 thing.. If you don't free textures explicitly, you can cause a
problem with nVidia drivers.
Colored lighting is now RGB instead of RGBA. The alpha is kinda pointless
on a lightmap and the effect's not all that great. Plus people stuck with
16 bit OpenGL (any other 3dfx people out there?) will be quite pleased
with the improvement in image quality. This does include LordHavoc's
dynamic light optimization code which takes most of the pain out of having
gl_flashblend off.
All glColor*'s are now half of what they used to be, except where they
aren't. If that doesn't make sense, don't worry. If you see one that's
only half what you'd expect, don't worry---it probably is meant to be like
that.. (More below)
glDisable (GL_BLEND) is now a thing of the GL_PAST. As is GL_REPLACE.
Instead, we _always_ use GL_MODULATE and leave GL_BLEND turned on. This
seems at first like it might be a performance hit, but I swear it's much
more expensive to change blending modes and texture functions 20-30 times
every screen frame!
Win32 issue.. Even though we check for multitexture, we currently don't
use it. Reason is that I am planning to replace SGIS_multitexture with
the preferred ARB_multitexture extension which is supported in most GL 1.1
implementations and is a requirement for GL 1.2 anyway. I also wanted to
get rid of some duplicated code. Since Linux doesn't support multitexture
yet, I just commented out the code keeping me from compiling to get it to
work. Win32 should work without it until it's fixed, which shouldn't be
long since the differences between SGIS and ARB multitextures as far as
Quake is concerned is minimal AT BEST.
LordHavoc and I have been working tirelessly (well not quite, we both did
manage to sleep sometime during this ordeal) to fix the lighting in the GL
renderers! It looks DAMNED CLOSE to software's lighting now, including
the ability to overbright a color. You've gotta see this to know what I'm
talking about. That's why the glColor*'s are halved in most places. The
gamma table code and the general way it works is LordHavoc's design, but
over the course of re-implementing it in QF we did come up with a few more
small optimizations.
A lot of people have noticed that QF's fps count has gone to shit lately.
No promises that this undid whatever the problem was. That means there
could be a huge optimization lurking somewhere in the shadows, waiting for
us to fix it for a massive FPS boost. Even if there's not, the code in
this commit DOUBLED MY FPS COUNT. Granted I was getting pathetic FPS as
it was (around 30, which is pathetic even for a Voodoo3 in Linux) but
still---60 is a big improvement over 30!
Please be sure to "test" this code thuroughly.
2000-06-03 19:56:09 +00:00
|
|
|
y = vid.height >> 1;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (lines > y) {
|
2000-05-29 10:16:04 +00:00
|
|
|
alpha = 1.0;
|
|
|
|
} else {
|
|
|
|
// set up to draw alpha console
|
2000-12-08 06:51:37 +00:00
|
|
|
alpha = (float) (gl_conalpha->value * lines) / y;
|
2000-05-29 10:16:04 +00:00
|
|
|
}
|
|
|
|
|
2000-07-02 05:16:10 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor4f (0.4, 0.4, 0.4, alpha);
|
2000-07-02 05:16:10 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor4f (0.8, 0.8, 0.8, alpha);
|
2000-05-29 10:16:04 +00:00
|
|
|
|
|
|
|
// draw the console texture
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, gl->texnum);
|
2000-05-29 10:16:04 +00:00
|
|
|
glBegin (GL_QUADS);
|
|
|
|
glTexCoord2f (gl->sl, gl->tl + ofs);
|
|
|
|
glVertex2f (0, 0);
|
|
|
|
glTexCoord2f (gl->sh, gl->tl + ofs);
|
|
|
|
glVertex2f (vid.conwidth, 0);
|
|
|
|
glTexCoord2f (gl->sh, gl->th);
|
|
|
|
glVertex2f (vid.conwidth, lines);
|
|
|
|
glTexCoord2f (gl->sl, gl->th);
|
|
|
|
glVertex2f (0, lines);
|
|
|
|
glEnd ();
|
|
|
|
|
|
|
|
// turn off alpha blending
|
2000-12-08 06:51:37 +00:00
|
|
|
if (alpha < 1.0) {
|
2000-07-02 05:16:10 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
2000-07-02 05:16:10 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
2000-05-29 10:16:04 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
if (gl_conspin->value) {
|
2000-05-29 10:16:04 +00:00
|
|
|
glPopMatrix ();
|
|
|
|
glMatrixMode (GL_MODELVIEW);
|
|
|
|
glPopMatrix ();
|
|
|
|
}
|
|
|
|
// draw version string if not downloading
|
|
|
|
if (!cls.download)
|
2000-12-08 06:51:37 +00:00
|
|
|
Draw_AltString8 (vid.conwidth - strlen (cl_verstring->string) * 8 - 11,
|
|
|
|
lines - 14, cl_verstring->string);
|
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Draw_TileClear
|
|
|
|
|
|
|
|
This repeats a 64*64 tile graphic to fill the screen around a sized down
|
|
|
|
refresh window.
|
|
|
|
=============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_TileClear (int x, int y, int w, int h)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-07-02 05:16:10 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.4, 0.4, 0.4);
|
2000-07-02 05:16:10 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (0.8, 0.8, 0.8);
|
|
|
|
glBindTexture (GL_TEXTURE_2D, *(int *) draw_backtile->data);
|
2000-05-10 11:29:38 +00:00
|
|
|
glBegin (GL_QUADS);
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexCoord2f (x / 64.0, y / 64.0);
|
2000-05-10 11:29:38 +00:00
|
|
|
glVertex2f (x, y);
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexCoord2f ((x + w) / 64.0, y / 64.0);
|
|
|
|
glVertex2f (x + w, y);
|
|
|
|
glTexCoord2f ((x + w) / 64.0, (y + h) / 64.0);
|
|
|
|
glVertex2f (x + w, y + h);
|
|
|
|
glTexCoord2f (x / 64.0, (y + h) / 64.0);
|
|
|
|
glVertex2f (x, y + h);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnd ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Draw_Fill
|
|
|
|
|
|
|
|
Fills a box of pixels with a single color
|
|
|
|
=============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_Fill (int x, int y, int w, int h, int c)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
glDisable (GL_TEXTURE_2D);
|
2000-07-02 05:16:10 +00:00
|
|
|
if (lighthalf)
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (host_basepal[c * 3] / 510.0, host_basepal[c * 3 + 1] / 510.0,
|
|
|
|
host_basepal[c * 3 + 2] / 510.0);
|
2000-07-02 05:16:10 +00:00
|
|
|
else
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3f (host_basepal[c * 3] / 255.0, host_basepal[c * 3 + 1] / 255.0,
|
|
|
|
host_basepal[c * 3 + 2] / 255.0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (x, y);
|
|
|
|
glVertex2f (x + w, y);
|
|
|
|
glVertex2f (x + w, y + h);
|
|
|
|
glVertex2f (x, y + h);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
glEnd ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnable (GL_TEXTURE_2D);
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Draw_FadeScreen
|
|
|
|
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_FadeScreen (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
glDisable (GL_TEXTURE_2D);
|
This is a NON-TRIVIAL update which took LordHavoc and I about 3 days to
make work properly:
Win32 thing.. If you don't free textures explicitly, you can cause a
problem with nVidia drivers.
Colored lighting is now RGB instead of RGBA. The alpha is kinda pointless
on a lightmap and the effect's not all that great. Plus people stuck with
16 bit OpenGL (any other 3dfx people out there?) will be quite pleased
with the improvement in image quality. This does include LordHavoc's
dynamic light optimization code which takes most of the pain out of having
gl_flashblend off.
All glColor*'s are now half of what they used to be, except where they
aren't. If that doesn't make sense, don't worry. If you see one that's
only half what you'd expect, don't worry---it probably is meant to be like
that.. (More below)
glDisable (GL_BLEND) is now a thing of the GL_PAST. As is GL_REPLACE.
Instead, we _always_ use GL_MODULATE and leave GL_BLEND turned on. This
seems at first like it might be a performance hit, but I swear it's much
more expensive to change blending modes and texture functions 20-30 times
every screen frame!
Win32 issue.. Even though we check for multitexture, we currently don't
use it. Reason is that I am planning to replace SGIS_multitexture with
the preferred ARB_multitexture extension which is supported in most GL 1.1
implementations and is a requirement for GL 1.2 anyway. I also wanted to
get rid of some duplicated code. Since Linux doesn't support multitexture
yet, I just commented out the code keeping me from compiling to get it to
work. Win32 should work without it until it's fixed, which shouldn't be
long since the differences between SGIS and ARB multitextures as far as
Quake is concerned is minimal AT BEST.
LordHavoc and I have been working tirelessly (well not quite, we both did
manage to sleep sometime during this ordeal) to fix the lighting in the GL
renderers! It looks DAMNED CLOSE to software's lighting now, including
the ability to overbright a color. You've gotta see this to know what I'm
talking about. That's why the glColor*'s are halved in most places. The
gamma table code and the general way it works is LordHavoc's design, but
over the course of re-implementing it in QF we did come up with a few more
small optimizations.
A lot of people have noticed that QF's fps count has gone to shit lately.
No promises that this undid whatever the problem was. That means there
could be a huge optimization lurking somewhere in the shadows, waiting for
us to fix it for a massive FPS boost. Even if there's not, the code in
this commit DOUBLED MY FPS COUNT. Granted I was getting pathetic FPS as
it was (around 30, which is pathetic even for a Voodoo3 in Linux) but
still---60 is a big improvement over 30!
Please be sure to "test" this code thuroughly.
2000-06-03 19:56:09 +00:00
|
|
|
glColor4f (0, 0, 0, 0.7);
|
2000-05-10 11:29:38 +00:00
|
|
|
glBegin (GL_QUADS);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glVertex2f (0, 0);
|
2000-05-10 11:29:38 +00:00
|
|
|
glVertex2f (vid.width, 0);
|
|
|
|
glVertex2f (vid.width, vid.height);
|
|
|
|
glVertex2f (0, vid.height);
|
|
|
|
|
|
|
|
glEnd ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
glEnable (GL_TEXTURE_2D);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
Sbar_Changed ();
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Draw_BeginDisc
|
|
|
|
|
|
|
|
Draws the little blue disc in the corner of the screen.
|
|
|
|
Call before beginning any disc IO.
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_BeginDisc (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Draw_EndDisc
|
|
|
|
|
|
|
|
Erases the disc icon.
|
|
|
|
Call after completing any disc IO
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
Draw_EndDisc (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_Set2D
|
|
|
|
|
|
|
|
Setup as if the screen was 320*200
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
|
|
|
GL_Set2D (void)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
glViewport (glx, gly, glwidth, glheight);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glMatrixMode (GL_PROJECTION);
|
2000-11-19 21:34:27 +00:00
|
|
|
glLoadIdentity ();
|
2000-12-08 06:51:37 +00:00
|
|
|
glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glMatrixMode (GL_MODELVIEW);
|
2000-11-19 21:34:27 +00:00
|
|
|
glLoadIdentity ();
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
glDisable (GL_DEPTH_TEST);
|
|
|
|
glDisable (GL_CULL_FACE);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glColor3ubv (lighthalf_v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_ResampleTexture
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
GL_ResampleTexture (unsigned int *in, int inwidth, int inheight,
|
|
|
|
unsigned int *out, int outwidth, int outheight)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, j;
|
|
|
|
unsigned int *inrow;
|
|
|
|
unsigned int frac, fracstep;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-24 04:43:22 +00:00
|
|
|
if (!outwidth || !outheight)
|
|
|
|
return;
|
2000-12-08 06:51:37 +00:00
|
|
|
fracstep = inwidth * 0x10000 / outwidth;
|
|
|
|
for (i = 0; i < outheight; i++, out += outwidth) {
|
|
|
|
inrow = in + inwidth * (i * inheight / outheight);
|
2000-05-10 11:29:38 +00:00
|
|
|
frac = fracstep >> 1;
|
2000-12-24 04:59:15 +00:00
|
|
|
for (j = 0; j < outwidth; j ++) {
|
2000-12-08 06:51:37 +00:00
|
|
|
out[j] = inrow[frac >> 16];
|
2000-05-10 11:29:38 +00:00
|
|
|
frac += fracstep;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_Resample8BitTexture -- JACK
|
|
|
|
================
|
|
|
|
*/
|
2000-12-01 04:44:05 +00:00
|
|
|
#if defined(GL_SHARED_TEXTURE_PALETTE_EXT) && defined(HAVE_GL_COLOR_INDEX8_EXT)
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight,
|
|
|
|
unsigned char *out, int outwidth, int outheight)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, j;
|
|
|
|
unsigned char *inrow;
|
|
|
|
unsigned int frac, fracstep;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-24 04:59:15 +00:00
|
|
|
if (!outwidth || !outheight)
|
|
|
|
return;
|
2000-12-08 06:51:37 +00:00
|
|
|
fracstep = inwidth * 0x10000 / outwidth;
|
|
|
|
for (i = 0; i < outheight; i++, out += outwidth) {
|
|
|
|
inrow = in + inwidth * (i * inheight / outheight);
|
2000-05-10 11:29:38 +00:00
|
|
|
frac = fracstep >> 1;
|
2000-12-24 04:59:15 +00:00
|
|
|
for (j = 0; j < outwidth; j ++) {
|
2000-12-08 06:51:37 +00:00
|
|
|
out[j] = inrow[frac >> 16];
|
2000-05-10 11:29:38 +00:00
|
|
|
frac += fracstep;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-12-01 04:44:05 +00:00
|
|
|
#endif
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_MipMap
|
|
|
|
|
|
|
|
Operates in place, quartering the size of the texture
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
GL_MipMap (byte * in, int width, int height)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, j;
|
|
|
|
byte *out;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
width <<= 2;
|
2000-05-10 11:29:38 +00:00
|
|
|
height >>= 1;
|
|
|
|
out = in;
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < height; i++, in += width) {
|
|
|
|
for (j = 0; j < width; j += 8, out += 4, in += 8) {
|
|
|
|
out[0] = (in[0] + in[4] + in[width + 0] + in[width + 4]) >> 2;
|
|
|
|
out[1] = (in[1] + in[5] + in[width + 1] + in[width + 5]) >> 2;
|
|
|
|
out[2] = (in[2] + in[6] + in[width + 2] + in[width + 6]) >> 2;
|
|
|
|
out[3] = (in[3] + in[7] + in[width + 3] + in[width + 7]) >> 2;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_MipMap8Bit
|
|
|
|
|
|
|
|
Mipping for 8 bit textures
|
|
|
|
================
|
|
|
|
*/
|
2000-12-01 04:44:05 +00:00
|
|
|
#if defined(GL_SHARED_TEXTURE_PALETTE_EXT) && defined(HAVE_GL_COLOR_INDEX8_EXT)
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
GL_MipMap8Bit (byte * in, int width, int height)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, j;
|
|
|
|
byte *out;
|
|
|
|
unsigned short r, g, b;
|
|
|
|
byte *at1, *at2, *at3, *at4;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
height >>= 1;
|
|
|
|
out = in;
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < height; i++, in += width)
|
|
|
|
for (j = 0; j < width; j += 2, out += 1, in += 2) {
|
|
|
|
at1 = (byte *) & d_8to24table[in[0]];
|
|
|
|
at2 = (byte *) & d_8to24table[in[1]];
|
|
|
|
at3 = (byte *) & d_8to24table[in[width + 0]];
|
|
|
|
at4 = (byte *) & d_8to24table[in[width + 1]];
|
|
|
|
|
|
|
|
r = (at1[0] + at2[0] + at3[0] + at4[0]);
|
|
|
|
r >>= 5;
|
|
|
|
g = (at1[1] + at2[1] + at3[1] + at4[1]);
|
|
|
|
g >>= 5;
|
|
|
|
b = (at1[2] + at2[2] + at3[2] + at4[2]);
|
|
|
|
b >>= 5;
|
|
|
|
|
|
|
|
out[0] = d_15to8table[(r << 0) + (g << 5) + (b << 10)];
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
2000-12-01 04:44:05 +00:00
|
|
|
#endif
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
GL_Upload32
|
|
|
|
===============
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
static void
|
|
|
|
GL_Upload32 (unsigned int *data, int width, int height, qboolean mipmap,
|
|
|
|
qboolean alpha)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
unsigned int *scaled;
|
|
|
|
int scaled_width, scaled_height, samples;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-23 00:09:42 +00:00
|
|
|
if (!width || !height)
|
|
|
|
return; // Null texture
|
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
// Snap the height and width to a power of 2.
|
2000-12-08 06:51:37 +00:00
|
|
|
for (scaled_width = 1; scaled_width < width; scaled_width <<= 1);
|
|
|
|
for (scaled_height = 1; scaled_height < height; scaled_height <<= 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-10-17 03:17:42 +00:00
|
|
|
scaled_width >>= gl_picmip->int_val;
|
|
|
|
scaled_height >>= gl_picmip->int_val;
|
2000-05-16 04:47:41 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
scaled_width = min (scaled_width, gl_max_size->int_val);
|
|
|
|
scaled_height = min (scaled_height, gl_max_size->int_val);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-20 22:03:49 +00:00
|
|
|
if (!(scaled = malloc (scaled_width * scaled_height * sizeof (GLuint))))
|
|
|
|
Sys_Error ("GL_LoadTexture: too big");
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
samples = alpha ? gl_alpha_format : gl_solid_format;
|
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
// If the real width/height and the 'scaled' width/height then we
|
|
|
|
// rescale it.
|
|
|
|
if (scaled_width == width && scaled_height == height) {
|
2000-12-23 00:09:42 +00:00
|
|
|
memcpy (scaled, data, width * height * sizeof (GLuint));
|
2000-09-22 09:08:08 +00:00
|
|
|
} else {
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_ResampleTexture (data, width, height, scaled, scaled_width,
|
|
|
|
scaled_height);
|
2000-09-22 09:08:08 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, scaled);
|
2000-09-22 09:08:08 +00:00
|
|
|
|
|
|
|
if (mipmap) {
|
2000-12-08 06:51:37 +00:00
|
|
|
int miplevel;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
miplevel = 0;
|
2000-09-22 09:08:08 +00:00
|
|
|
while (scaled_width > 1 || scaled_height > 1) {
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_MipMap ((byte *) scaled, scaled_width, scaled_height);
|
2000-05-10 11:29:38 +00:00
|
|
|
scaled_width >>= 1;
|
|
|
|
scaled_height >>= 1;
|
2000-11-21 09:15:36 +00:00
|
|
|
scaled_width = max (scaled_width, 1);
|
|
|
|
scaled_height = max (scaled_height, 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
miplevel++;
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width,
|
|
|
|
scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
if (mipmap) {
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
2000-09-22 09:08:08 +00:00
|
|
|
} else {
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-09-22 09:08:08 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
free (scaled);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-11-23 08:01:04 +00:00
|
|
|
/*
|
|
|
|
GL_Upload8_EXT
|
|
|
|
|
|
|
|
If we have shared or global palettes, upload an 8-bit texture. If we don't,
|
|
|
|
this function does nothing.
|
|
|
|
*/
|
2000-11-21 09:15:36 +00:00
|
|
|
void
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_Upload8_EXT (byte * data, int width, int height, qboolean mipmap,
|
|
|
|
qboolean alpha)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-11-23 08:01:04 +00:00
|
|
|
#if defined(GL_SHARED_TEXTURE_PALETTE_EXT) && defined(HAVE_GL_COLOR_INDEX8_EXT)
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
byte *scaled;
|
|
|
|
int scaled_width, scaled_height;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
// Snap the height and width to a power of 2.
|
2000-12-08 06:51:37 +00:00
|
|
|
for (scaled_width = 1; scaled_width < width; scaled_width <<= 1);
|
|
|
|
for (scaled_height = 1; scaled_height < height; scaled_height <<= 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-10-17 03:17:42 +00:00
|
|
|
scaled_width >>= gl_picmip->int_val;
|
|
|
|
scaled_height >>= gl_picmip->int_val;
|
2000-05-16 04:47:41 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
scaled_width = min (scaled_width, gl_max_size->int_val);
|
|
|
|
scaled_height = min (scaled_height, gl_max_size->int_val);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!(scaled = malloc (scaled_width * scaled_height)))
|
2000-05-10 11:29:38 +00:00
|
|
|
Sys_Error ("GL_LoadTexture: too big");
|
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
// If the real width/height and the 'scaled' width/height then we
|
|
|
|
// rescale it.
|
|
|
|
if (scaled_width == width && scaled_height == height) {
|
2000-12-08 06:51:37 +00:00
|
|
|
memcpy (scaled, data, width * height);
|
2000-09-22 09:08:08 +00:00
|
|
|
} else {
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_Resample8BitTexture (data, width, height, scaled, scaled_width,
|
|
|
|
scaled_height);
|
2000-09-22 09:08:08 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width,
|
|
|
|
scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
|
2000-09-22 09:08:08 +00:00
|
|
|
|
|
|
|
if (mipmap) {
|
2000-12-08 06:51:37 +00:00
|
|
|
int miplevel;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
miplevel = 0;
|
2000-09-22 09:08:08 +00:00
|
|
|
while (scaled_width > 1 || scaled_height > 1) {
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_MipMap8Bit ((byte *) scaled, scaled_width, scaled_height);
|
2000-05-10 11:29:38 +00:00
|
|
|
scaled_width >>= 1;
|
|
|
|
scaled_height >>= 1;
|
2000-11-21 09:15:36 +00:00
|
|
|
scaled_width = max (scaled_width, 1);
|
|
|
|
scaled_height = max (scaled_height, 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
miplevel++;
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT,
|
|
|
|
scaled_width, scaled_height, 0, GL_COLOR_INDEX,
|
|
|
|
GL_UNSIGNED_BYTE, scaled);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
if (mipmap) {
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
2000-09-22 09:08:08 +00:00
|
|
|
} else {
|
2000-12-08 06:51:37 +00:00
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
|
|
|
|
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-09-22 09:08:08 +00:00
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
free (scaled);
|
|
|
|
#endif
|
2000-11-23 08:01:04 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-28 09:30:32 +00:00
|
|
|
extern qboolean VID_Is8bit (void);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
GL_Upload8
|
|
|
|
===============
|
|
|
|
*/
|
2000-11-21 09:15:36 +00:00
|
|
|
void
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_Upload8 (byte * data, int width, int height, qboolean mipmap, qboolean alpha)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
unsigned int *trans = NULL;
|
|
|
|
int i, s, p;
|
2000-09-22 09:08:08 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
s = width * height;
|
2000-11-21 09:15:36 +00:00
|
|
|
trans = malloc (s * sizeof (unsigned int));
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-09-22 09:08:08 +00:00
|
|
|
// if there are no transparent pixels, make it a 3 component
|
|
|
|
// texture even if it was specified as otherwise
|
|
|
|
if (alpha) {
|
|
|
|
alpha = false;
|
2000-11-21 09:15:36 +00:00
|
|
|
for (i = 0; i < s; i++) {
|
2000-09-22 09:08:08 +00:00
|
|
|
p = data[i];
|
2000-11-21 09:15:36 +00:00
|
|
|
if (p == 255)
|
|
|
|
alpha = true;
|
2000-09-22 09:08:08 +00:00
|
|
|
trans[i] = d_8to24table[p];
|
|
|
|
}
|
|
|
|
} else {
|
2000-11-21 09:15:36 +00:00
|
|
|
if (s & 3)
|
2000-11-23 08:01:04 +00:00
|
|
|
Sys_Error ("GL_Upload8: width*height divisible by 3");
|
2000-11-21 09:15:36 +00:00
|
|
|
for (i = 0; i < s; i += 4) {
|
2000-09-22 09:08:08 +00:00
|
|
|
trans[i] = d_8to24table[data[i]];
|
2000-12-08 06:51:37 +00:00
|
|
|
trans[i + 1] = d_8to24table[data[i + 1]];
|
|
|
|
trans[i + 2] = d_8to24table[data[i + 2]];
|
|
|
|
trans[i + 3] = d_8to24table[data[i + 3]];
|
2000-09-22 09:08:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
#if defined(GL_SHARED_TEXTURE_PALETTE_EXT) && defined(HAVE_GL_COLOR_INDEX8_EXT)
|
2000-09-22 09:08:08 +00:00
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
# ifdef gl_draw_scraps
|
2000-12-08 06:51:37 +00:00
|
|
|
if (VID_Is8bit () && !alpha && (data != scrap_texels[0])) {
|
2000-11-21 09:15:36 +00:00
|
|
|
# else
|
2000-12-08 06:51:37 +00:00
|
|
|
if (VID_Is8bit () && !alpha) {
|
2000-11-21 09:15:36 +00:00
|
|
|
# endif
|
2000-09-22 09:08:08 +00:00
|
|
|
GL_Upload8_EXT (data, width, height, mipmap, alpha);
|
|
|
|
} else {
|
|
|
|
#else
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-08-14 04:53:45 +00:00
|
|
|
#endif
|
2000-11-21 09:15:36 +00:00
|
|
|
GL_Upload32 (trans, width, height, mipmap, alpha);
|
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
free (trans);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_LoadTexture
|
|
|
|
================
|
|
|
|
*/
|
2000-11-21 09:15:36 +00:00
|
|
|
int
|
2000-12-08 06:51:37 +00:00
|
|
|
GL_LoadTexture (char *identifier, int width, int height, byte * data,
|
|
|
|
qboolean mipmap, qboolean alpha, int bytesperpixel)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-08-14 04:53:45 +00:00
|
|
|
gltexture_t *glt;
|
2000-12-08 06:51:37 +00:00
|
|
|
int i, crc;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-09-22 15:08:28 +00:00
|
|
|
// LordHavoc: now just using a standard CRC for texture validation
|
2000-11-21 09:15:36 +00:00
|
|
|
crc = CRC_Block (data, width * height * bytesperpixel);
|
2000-09-22 15:08:28 +00:00
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
// see if the texture is already present
|
|
|
|
if (identifier[0]) {
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0, glt = gltextures; i < numgltextures; i++, glt++) {
|
2000-11-21 09:15:36 +00:00
|
|
|
if (strequal (identifier, glt->identifier)) {
|
2000-09-22 15:08:28 +00:00
|
|
|
if (crc != glt->crc
|
2000-12-08 06:51:37 +00:00
|
|
|
|| width != glt->width
|
|
|
|
|| height != glt->height
|
|
|
|
|| bytesperpixel != glt->bytesperpixel) goto SetupTexture;
|
2000-06-09 22:28:08 +00:00
|
|
|
else
|
|
|
|
return gltextures[i].texnum;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-06-09 22:28:08 +00:00
|
|
|
|
2000-08-14 04:53:45 +00:00
|
|
|
if (numgltextures == MAX_GLTEXTURES)
|
|
|
|
Sys_Error ("numgltextures == MAX_GLTEXTURES");
|
|
|
|
|
2000-06-09 22:28:08 +00:00
|
|
|
glt = &gltextures[numgltextures];
|
2000-05-10 11:29:38 +00:00
|
|
|
numgltextures++;
|
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
strncpy (glt->identifier, identifier, sizeof (glt->identifier) - 1);
|
|
|
|
glt->identifier[sizeof (glt->identifier) - 1] = '\0';
|
2000-08-14 04:53:45 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
glt->texnum = texture_extension_number;
|
2000-06-09 22:28:08 +00:00
|
|
|
texture_extension_number++;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
SetupTexture:
|
2000-09-22 15:08:28 +00:00
|
|
|
glt->crc = crc;
|
2000-05-10 11:29:38 +00:00
|
|
|
glt->width = width;
|
|
|
|
glt->height = height;
|
2000-06-23 08:43:32 +00:00
|
|
|
glt->bytesperpixel = bytesperpixel;
|
2000-05-10 11:29:38 +00:00
|
|
|
glt->mipmap = mipmap;
|
|
|
|
|
2000-06-17 10:39:28 +00:00
|
|
|
glBindTexture (GL_TEXTURE_2D, glt->texnum);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-11-21 09:15:36 +00:00
|
|
|
switch (glt->bytesperpixel) {
|
2000-06-23 08:43:32 +00:00
|
|
|
case 1:
|
|
|
|
GL_Upload8 (data, width, height, mipmap, alpha);
|
|
|
|
break;
|
|
|
|
case 4:
|
2000-12-20 21:59:56 +00:00
|
|
|
GL_Upload32 ((GLuint *) data, width, height, mipmap, alpha);
|
2000-06-23 08:43:32 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Sys_Error ("SetupTexture: unknown bytesperpixel %i",
|
2000-12-08 06:51:37 +00:00
|
|
|
glt->bytesperpixel);
|
2000-06-23 08:43:32 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-06-09 22:28:08 +00:00
|
|
|
return glt->texnum;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-06-23 08:43:32 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
/*
|
|
|
|
================
|
|
|
|
GL_LoadPicTexture
|
|
|
|
================
|
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
static int
|
|
|
|
GL_LoadPicTexture (qpic_t *pic)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true,
|
|
|
|
1);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|