X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=gl_draw.c;h=bad2c8c711cfe2db24a1a25a11e985f59a88b4c3;hb=2275e4d0cab079f4a0849ba55b8f92023d6f3eab;hp=88e68abde7d33bd8440e0d65e515950d8f4db930;hpb=cecffffdd5310e387e8b910735ff77aa329cdb43;p=xonotic%2Fdarkplaces.git diff --git a/gl_draw.c b/gl_draw.c index 88e68abd..bad2c8c7 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -25,18 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define GL_COLOR_INDEX8_EXT 0x80E5 -extern unsigned char d_15to8table[65536]; - cvar_t qsg_version = {"qsg_version", "1"}; -cvar_t gl_max_size = {"gl_max_size", "1024"}; -cvar_t gl_picmip = {"gl_picmip", "0"}; -cvar_t gl_conalpha = {"gl_conalpha", "1"}; -cvar_t gl_lerpimages = {"gl_lerpimages", "1"}; +cvar_t scr_conalpha = {"scr_conalpha", "1"}; byte *draw_chars; // 8*8 graphic characters qpic_t *draw_disc; -int translate_texture; int char_texture; typedef struct @@ -45,31 +39,7 @@ typedef struct float sl, tl, sh, th; } glpic_t; -byte conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)]; -qpic_t *conback = (qpic_t *)&conback_buffer; - -int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; -int gl_filter_max = GL_LINEAR; - - -int texels; - -typedef struct -{ - int texnum; - char identifier[64]; - int width, height; - qboolean mipmap; -// LordHavoc: 32bit textures - int bytesperpixel; -// LordHavoc: CRC to identify cache mismatchs - int crc; - int lerped; // whether this texture was uploaded with or without interpolation -} gltexture_t; - -#define MAX_GLTEXTURES 4096 -gltexture_t gltextures[MAX_GLTEXTURES]; -int numgltextures; +int conbacktexnum; /* ============================================================================= @@ -82,6 +52,7 @@ int numgltextures; ============================================================================= */ +/* #define MAX_SCRAPS 2 #define BLOCK_WIDTH 256 #define BLOCK_HEIGHT 256 @@ -89,7 +60,6 @@ int numgltextures; int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4]; qboolean scrap_dirty; -int scrap_texnum; // returns a texture number and the position inside it int Scrap_AllocBlock (int w, int h, int *x, int *y) @@ -134,6 +104,7 @@ int Scrap_AllocBlock (int w, int h, int *x, int *y) } int scrap_uploads; +int scraptexnum[MAX_SCRAPS]; void Scrap_Upload (void) { @@ -142,12 +113,10 @@ void Scrap_Upload (void) scrap_uploads++; for (texnum=0 ; texnumdata; // load little ones into the scrap + /* if (p->width < 64 && p->height < 64) { int x, y; @@ -191,8 +161,9 @@ qpic_t *Draw_PicFromWad (char *name) for (i=0 ; iheight ; i++) for (j=0 ; jwidth ; j++, k++) scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k]; - texnum += scrap_texnum; - gl->texnum = texnum; + if (!scraptexnum[texnum]) + scraptexnum[texnum] = GL_LoadTexture (va("scrapslot%d", texnum), BLOCK_WIDTH, BLOCK_HEIGHT, scrap_texels[texnum], false, true, 1); + gl->texnum = scraptexnum[texnum]; 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; @@ -200,21 +171,16 @@ qpic_t *Draw_PicFromWad (char *name) pic_count++; pic_texels += p->width*p->height; - // LordHavoc: LINEAR interpolation - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { + */ gl->texnum = GL_LoadPicTexture (p); gl->sl = 0; gl->sh = 1; gl->tl = 0; gl->th = 1; - // LordHavoc: LINEAR interpolation - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //NEAREST); - } + //} return p; } @@ -258,7 +224,9 @@ qpic_t *Draw_CachePic (char *path) pic->pic.height = dat->height; gl = (glpic_t *)pic->pic.data; - gl->texnum = GL_LoadPicTexture (dat); + gl->texnum = loadtextureimage(path, 0, 0, false, false); + if (!gl->texnum) + gl->texnum = GL_LoadPicTexture (dat); gl->sl = 0; gl->sh = 1; gl->tl = 0; @@ -267,195 +235,72 @@ qpic_t *Draw_CachePic (char *path) return &pic->pic; } - -void Draw_CharToConback (int num, byte *dest) -{ - int row, col; - byte *source; - int drawline; - int x; - - row = num>>4; - col = num&15; - source = draw_chars + (row<<10) + (col<<3); - - drawline = 8; - - while (drawline--) - { - for (x=0 ; x<8 ; x++) - if (source[x] != 255) - dest[x] = 0x60 + source[x]; - source += 128; - dest += 320; - } - -} - -typedef struct -{ - char *name; - int minimize, maximize; -} glmode_t; - -glmode_t modes[] = { - {"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} -}; +extern void LoadSky_f(void); /* =============== -Draw_TextureMode_f +Draw_Init =============== */ -void Draw_TextureMode_f (void) +void rmain_registercvars(); +extern int buildnumber; + +void gl_draw_start() { int i; - gltexture_t *glt; - if (Cmd_Argc() == 1) + char_texture = loadtextureimage ("conchars", 0, 0, false, false); + if (!char_texture) { - for (i=0 ; i< 6 ; i++) - if (gl_filter_min == modes[i].minimize) - { - Con_Printf ("%s\n", modes[i].name); - return; - } - Con_Printf ("current filter is unknown???\n"); - return; - } + draw_chars = W_GetLumpName ("conchars"); + for (i=0 ; i<128*128 ; i++) + if (draw_chars[i] == 0) + draw_chars[i] = 255; // proper transparent color - for (i=0 ; i< 6 ; i++) - { - if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) ) - break; - } - if (i == 6) - { - Con_Printf ("bad filter name\n"); - return; + // now turn them into textures + char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1); } - gl_filter_min = modes[i].minimize; - gl_filter_max = modes[i].maximize; + conbacktexnum = loadtextureimage("gfx/conback", 0, 0, false, false); - // change all the existing mipmap texture objects - for (i=0, glt=gltextures ; imipmap) - { - glBindTexture(GL_TEXTURE_2D, glt->texnum); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - } +// memset(scraptexnum, 0, sizeof(scraptexnum)); + + // get the other pics we need + draw_disc = Draw_PicFromWad ("disc"); } -extern void LoadSky_f(void); +void gl_draw_shutdown() +{ +} -extern char *QSG_EXTENSIONS; +char engineversion[40]; +int engineversionx, engineversiony; -/* -=============== -Draw_Init -=============== -*/ -void rmain_registercvars(); -void Draw_Init (void) +extern void GL_Textures_Init(); +void GL_Draw_Init (void) { - int i; - qpic_t *cb; - byte *dest; - int x, y; - char ver[40]; - glpic_t *gl; - int start; - + int i; Cvar_RegisterVariable (&qsg_version); - Cvar_RegisterVariable (&gl_max_size); - Cvar_RegisterVariable (&gl_picmip); - Cvar_RegisterVariable (&gl_conalpha); - Cvar_RegisterVariable (&gl_lerpimages); - - // 3dfx can only handle 256 wide textures - if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) || - strstr((char *)gl_renderer, "Glide")) - Cvar_Set ("gl_max_size", "256"); - - Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f); + Cvar_RegisterVariable (&scr_conalpha); Cmd_AddCommand ("loadsky", &LoadSky_f); - // 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"); - for (i=0 ; i<256*64 ; i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; // proper transparent color - - // now turn them into textures - char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, 1); - - start = Hunk_LowMark(); - - cb = (qpic_t *)COM_LoadMallocFile ("gfx/conback.lmp", false); - if (!cb) - Sys_Error ("Couldn't load gfx/conback.lmp"); - SwapPic (cb); - - // hack the version number directly into the pic -#ifdef NEHAHRA #if defined(__linux__) - sprintf (ver, "DPNehahra Linux GL %.2f", (float) VERSION); + sprintf (engineversion, "DarkPlaces Linux GL %.2f build %3i", (float) VERSION, buildnumber); +#elif defined(WIN32) + sprintf (engineversion, "DarkPlaces Windows GL %.2f build %3i", (float) VERSION, buildnumber); #else - sprintf (ver, "DPNehahra Windows GL %.2f", (float) VERSION); + sprintf (engineversion, "DarkPlaces Unknown GL %.2f build %3i", (float) VERSION, buildnumber); #endif -#else -#if defined(__linux__) - sprintf (ver, "DarkPlaces Linux GL %.2f", (float)VERSION); -#else - sprintf (ver, "DarkPlaces Windows GL %.2f", (float)VERSION); -#endif -#endif - dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver); - y = strlen(ver); - for (x=0 ; xdata; - gl->texnum = GL_LoadTexture ("conback", cb->width, cb->height, cb->data, false, false, 1); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - conback->width = vid.width; - conback->height = vid.height; - - // free loaded console - free(cb); + for (i = 0;i < 40 && engineversion[i];i++) + engineversion[i] += 0x80; // shift to orange + engineversionx = vid.width - strlen(engineversion) * 8 - 8; + engineversiony = vid.height - 8; - // save a texture slot for translated picture - translate_texture = texture_extension_number++; - - // save slots for scraps - scrap_texnum = texture_extension_number; - texture_extension_number += MAX_SCRAPS; - - // - // get the other pics we need - // - draw_disc = Draw_PicFromWad ("disc"); - - rmain_registercvars(); + GL_Textures_Init(); + R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown); } - /* ================ Draw_Character @@ -485,9 +330,11 @@ void Draw_Character (int x, int y, int num) fcol = col*0.0625; size = 0.0625; + if (!r_render.value) + return; glBindTexture(GL_TEXTURE_2D, char_texture); // LordHavoc: NEAREST mode on text if not scaling up - if ((int) vid.width < glwidth) + if (glwidth < (int) vid.width) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -520,6 +367,8 @@ void Draw_String (int x, int y, char *str, int maxlen) { int num; float frow, fcol; + if (!r_render.value) + return; if (y <= -8 || y >= (int) vid.height || x >= (int) vid.width || *str == 0) // completely offscreen or no text to print return; if (maxlen < 1) @@ -529,7 +378,7 @@ void Draw_String (int x, int y, char *str, int maxlen) glBindTexture(GL_TEXTURE_2D, char_texture); // LordHavoc: NEAREST mode on text if not scaling up - if ((int) vid.width < glwidth) + if (glwidth < (int) vid.width) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -543,14 +392,10 @@ void Draw_String (int x, int y, char *str, int maxlen) { frow = (float) ((int) num >> 4)*0.0625; fcol = (float) ((int) num & 15)*0.0625; - glTexCoord2f (fcol, frow); - glVertex2f (x, y); - glTexCoord2f (fcol + 0.0625, frow); - glVertex2f (x+8, y); - glTexCoord2f (fcol + 0.0625, frow + 0.0625); - glVertex2f (x+8, y+8); - glTexCoord2f (fcol, frow + 0.0625); - glVertex2f (x, y+8); + glTexCoord2f (fcol , frow );glVertex2f (x, y); + glTexCoord2f (fcol + 0.0625, frow );glVertex2f (x+8, y); + glTexCoord2f (fcol + 0.0625, frow + 0.0625);glVertex2f (x+8, y+8); + glTexCoord2f (fcol , frow + 0.0625);glVertex2f (x, y+8); } x += 8; } @@ -561,6 +406,20 @@ void Draw_String (int x, int y, char *str, int maxlen) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } +void Draw_GenericPic (int texnum, float red, float green, float blue, float alpha, int x, int y, int width, int height) +{ + if (!r_render.value) + return; + glColor4f(red,green,blue,alpha); + glBindTexture(GL_TEXTURE_2D, texnum); + glBegin (GL_QUADS); + glTexCoord2f (0, 0);glVertex2f (x, y); + glTexCoord2f (1, 0);glVertex2f (x+width, y); + glTexCoord2f (1, 1);glVertex2f (x+width, y+height); + glTexCoord2f (0, 1);glVertex2f (x, y+height); + glEnd (); +} + /* ============= Draw_AlphaPic @@ -570,29 +429,19 @@ void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) { glpic_t *gl; - if (scrap_dirty) - Scrap_Upload (); +// if (scrap_dirty) +// Scrap_Upload (); gl = (glpic_t *)pic->data; -// glDisable(GL_ALPHA_TEST); -// glEnable (GL_BLEND); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// glCullFace(GL_FRONT); - glColor4f(0.8,0.8,0.8,alpha); + if (!r_render.value) + return; + glColor4f(1,1,1,alpha); glBindTexture(GL_TEXTURE_2D, gl->texnum); -// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBegin (GL_QUADS); - glTexCoord2f (gl->sl, gl->tl); - glVertex2f (x, y); - glTexCoord2f (gl->sh, gl->tl); - glVertex2f (x+pic->width, y); - glTexCoord2f (gl->sh, gl->th); - glVertex2f (x+pic->width, y+pic->height); - glTexCoord2f (gl->sl, gl->th); - glVertex2f (x, y+pic->height); + glTexCoord2f (gl->sl, gl->tl);glVertex2f (x, y); + glTexCoord2f (gl->sh, gl->tl);glVertex2f (x+pic->width, y); + glTexCoord2f (gl->sh, gl->th);glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (gl->sl, gl->th);glVertex2f (x, y+pic->height); glEnd (); - glColor3f(1,1,1); -// glEnable(GL_ALPHA_TEST); -// glDisable (GL_BLEND); } @@ -605,90 +454,56 @@ void Draw_Pic (int x, int y, qpic_t *pic) { glpic_t *gl; - if (scrap_dirty) - Scrap_Upload (); +// if (scrap_dirty) +// Scrap_Upload (); gl = (glpic_t *)pic->data; - glColor3f(0.8,0.8,0.8); + if (!r_render.value) + return; + glColor3f(1,1,1); glBindTexture(GL_TEXTURE_2D, gl->texnum); glBegin (GL_QUADS); - glTexCoord2f (gl->sl, gl->tl); - glVertex2f (x, y); - glTexCoord2f (gl->sh, gl->tl); - glVertex2f (x+pic->width, y); - glTexCoord2f (gl->sh, gl->th); - glVertex2f (x+pic->width, y+pic->height); - glTexCoord2f (gl->sl, gl->th); - glVertex2f (x, y+pic->height); + glTexCoord2f (gl->sl, gl->tl);glVertex2f (x, y); + glTexCoord2f (gl->sh, gl->tl);glVertex2f (x+pic->width, y); + glTexCoord2f (gl->sh, gl->th);glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (gl->sl, gl->th);glVertex2f (x, y+pic->height); glEnd (); } /* ============= -Draw_TransPic -============= -*/ -void Draw_TransPic (int x, int y, qpic_t *pic) -{ - if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || (unsigned)(y + pic->height) > vid.height) - Sys_Error ("Draw_TransPic: bad coordinates"); - -// glEnable(GL_BLEND); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// glDisable(GL_ALPHA_TEST); - Draw_Pic (x, y, pic); -// glDisable(GL_BLEND); -} - - -/* -============= -Draw_TransPicTranslate +Draw_PicTranslate Only used for the player color selection menu ============= */ -void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation) { - int v, u, c; - unsigned trans[64*64], *dest; - byte *src; - int p; - - glBindTexture(GL_TEXTURE_2D, translate_texture); + int i, c; + byte *trans, *src, *dest; c = pic->width * pic->height; + src = menuplyr_pixels; + dest = trans = malloc(c); + for (i = 0;i < c;i++) + *dest++ = translation[*src++]; - 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, 4, 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); + c = GL_LoadTexture ("translatedplayerpic", pic->width, pic->height, trans, false, true, 1); + free(trans); - glColor3f(0.8,0.8,0.8); + if (!r_render.value) + return; + Draw_GenericPic (c, 1,1,1,1, x, y, pic->width, pic->height); + /* + glBindTexture(GL_TEXTURE_2D, c); + glColor3f(1,1,1); 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); + 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 (); + */ } @@ -700,14 +515,9 @@ Draw_ConsoleBackground */ void Draw_ConsoleBackground (int lines) { - // LordHavoc: changed alpha - //int y = (vid.height >> 1); - - if (lines >= (int) vid.height) - Draw_Pic(0, lines - vid.height, conback); - else - Draw_AlphaPic (0, lines - vid.height, conback, gl_conalpha.value*lines/vid.height); - // Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); + Draw_GenericPic (conbacktexnum, 1,1,1,scr_conalpha.value*lines/vid.height, 0, lines - vid.height, vid.width, vid.height); + // LordHavoc: draw version + Draw_String(engineversionx, lines - vid.height + engineversiony, engineversion, 9999); } /* @@ -719,6 +529,8 @@ Fills a box of pixels with a single color */ void Draw_Fill (int x, int y, int w, int h, int c) { + if (!r_render.value) + return; glDisable (GL_TEXTURE_2D); glColor3f (host_basepal[c*3]/255.0, host_basepal[c*3+1]/255.0, host_basepal[c*3+2]/255.0); @@ -746,6 +558,8 @@ Setup as if the screen was 320*200 */ void GL_Set2D (void) { + if (!r_render.value) + return; glViewport (glx, gly, glwidth, glheight); glMatrixMode(GL_PROJECTION); @@ -757,8 +571,7 @@ void GL_Set2D (void) glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); - glEnable (GL_BLEND); // was Disable -// glEnable (GL_ALPHA_TEST); + glEnable (GL_BLEND); glDisable (GL_ALPHA_TEST); glEnable(GL_TEXTURE_2D); @@ -831,7 +644,7 @@ void SHOWLMP_drawall() int i; for (i = 0;i < SHOWLMP_MAXLABELS;i++) if (showlmp[i].isactive) - Draw_TransPic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic)); + Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic)); } void SHOWLMP_clear() @@ -840,587 +653,3 @@ void SHOWLMP_clear() for (i = 0;i < SHOWLMP_MAXLABELS;i++) showlmp[i].isactive = false; } - -//==================================================================== - -/* -================ -GL_FindTexture -================ -*/ -int GL_FindTexture (char *identifier) -{ - int i; - gltexture_t *glt; - - for (i=0, glt=gltextures ; iidentifier)) - return gltextures[i].texnum; - } - - return -1; -} - -extern byte qgamma[]; - -// LordHavoc: gamma correction and improved resampling -void GL_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth) -{ - int j, xi, oldx = 0; - float f, fstep, l1, l2; - fstep = (float) inwidth/outwidth; - for (j = 0,f = 0;j < outwidth;j++, f += fstep) - { - xi = (int) f; - if (xi != oldx) - { - in += (xi - oldx) * 4; - oldx = xi; - } - if (xi < (inwidth-1)) - { - l2 = f - xi; - l1 = 1 - l2; - *out++ = qgamma[(byte) (in[0] * l1 + in[4] * l2)]; - *out++ = qgamma[(byte) (in[1] * l1 + in[5] * l2)]; - *out++ = qgamma[(byte) (in[2] * l1 + in[6] * l2)]; - *out++ = (byte) (in[3] * l1 + in[7] * l2) ; - } - else // last pixel of the line has no pixel to lerp to - { - *out++ = qgamma[in[0]]; - *out++ = qgamma[in[1]]; - *out++ = qgamma[in[2]]; - *out++ = in[3] ; - } - } -} - -/* -================ -GL_ResampleTexture -================ -*/ -void GL_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight) -{ - // LordHavoc: gamma correction and greatly improved resampling - if (gl_lerpimages.value) - { - int i, j, yi, oldy; - byte *inrow, *out, *row1, *row2; - float f, fstep, l1, l2; - out = outdata; - fstep = (float) inheight/outheight; - - row1 = malloc(outwidth*4); - row2 = malloc(outwidth*4); - inrow = indata; - oldy = 0; - GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth); - GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth); - for (i = 0, f = 0;i < outheight;i++,f += fstep) - { - yi = (int) f; - if (yi != oldy) - { - inrow = (byte *)((int)indata + inwidth*4*yi); - if (yi == oldy+1) - memcpy(row1, row2, outwidth*4); - else - GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth); - if (yi < (inheight-1)) - GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth); - else - memcpy(row2, row1, outwidth*4); - oldy = yi; - } - if (yi < (inheight-1)) - { - l2 = f - yi; - l1 = 1 - l2; - for (j = 0;j < outwidth;j++) - { - *out++ = (byte) (*row1++ * l1 + *row2++ * l2); - *out++ = (byte) (*row1++ * l1 + *row2++ * l2); - *out++ = (byte) (*row1++ * l1 + *row2++ * l2); - *out++ = (byte) (*row1++ * l1 + *row2++ * l2); - } - row1 -= outwidth*4; - row2 -= outwidth*4; - } - else // last line has no pixels to lerp to - { - for (j = 0;j < outwidth;j++) - { - *out++ = *row1++; - *out++ = *row1++; - *out++ = *row1++; - *out++ = *row1++; - } - row1 -= outwidth*4; - } - } - free(row1); - free(row2); - } - else - { - int i, j; - unsigned frac, fracstep; - byte *inrow, *out, *inpix; - out = outdata; - - fracstep = inwidth*0x10000/outwidth; - for (i=0 ; i> 1; - for (j=0 ; j> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep; - } - } - } -} - -/* -================ -GL_Resample8BitTexture -- JACK -================ -*/ -void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight) -{ - int i, j; - unsigned char *inrow; - unsigned frac, fracstep; - - fracstep = inwidth*0x10000/outwidth; - for (i=0 ; i> 1; - for (j=0 ; j>16]; - frac += fracstep; - out[j+1] = inrow[frac>>16]; - frac += fracstep; - out[j+2] = inrow[frac>>16]; - frac += fracstep; - out[j+3] = inrow[frac>>16]; - frac += fracstep; - } - } -} - - -/* -================ -GL_MipMap - -Operates in place, quartering the size of the texture -================ -*/ -void GL_MipMap (byte *in, int width, int height) -{ - int i, j; - byte *out; - - width <<=2; - height >>= 1; - out = in; - for (i=0 ; i>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; - } - } -} - -/* -================ -GL_MipMap8Bit - -Mipping for 8 bit textures -================ -*/ -void GL_MipMap8Bit (byte *in, int width, int height) -{ - int i, j; - unsigned short r,g,b; - byte *out, *at1, *at2, *at3, *at4; - - height >>= 1; - out = in; - for (i=0 ; i>=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)]; - } - } -} - -/* -=============== -GL_Upload32 -=============== -*/ -void GL_Upload32 (void *data, int width, int height, qboolean mipmap, qboolean alpha) -{ - int samples, scaled_width, scaled_height, i; - byte *in, *out, *scaled; - - for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) - ; - for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) - ; - - scaled_width >>= (int)gl_picmip.value; - scaled_height >>= (int)gl_picmip.value; - - if (scaled_width > gl_max_size.value) - scaled_width = gl_max_size.value; - if (scaled_height > gl_max_size.value) - scaled_height = gl_max_size.value; - - if (alpha) - { - alpha = false; - in = data; - for (i = 3;i < width*height*4;i += 4) - if (in[i] != 255) - { - alpha = true; - break; - } - } - - samples = alpha ? gl_alpha_format : gl_solid_format; - -#if 0 - if (mipmap) - gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - else if (scaled_width == width && scaled_height == height) - glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - else - { - gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, scaled, scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled); - glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - } -#else -texels += scaled_width * scaled_height; - - scaled = malloc(scaled_width*scaled_height*4); - if (scaled_width == width && scaled_height == height) - { - // LordHavoc: gamma correct while copying - in = (byte *)data; - out = (byte *)scaled; - for (i = 0;i < width*height;i++) - { - *out++ = qgamma[*in++]; - *out++ = qgamma[*in++]; - *out++ = qgamma[*in++]; - *out++ = *in++; - } - } - else - GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height); - - glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - if (mipmap) - { - int miplevel; - - miplevel = 0; - while (scaled_width > 1 || scaled_height > 1) - { - GL_MipMap ((byte *)scaled, scaled_width, scaled_height); - scaled_width >>= 1; - scaled_height >>= 1; - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; - miplevel++; - glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - } - } -#endif - - - if (mipmap) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - free(scaled); -} - -void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap) -{ - int scaled_width, scaled_height; - byte *scaled = NULL; - - for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) - ; - for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) - ; - - scaled_width >>= (int)gl_picmip.value; - scaled_height >>= (int)gl_picmip.value; - - if (scaled_width > gl_max_size.value) - scaled_width = gl_max_size.value; - if (scaled_height > gl_max_size.value) - scaled_height = gl_max_size.value; - - texels += scaled_width * scaled_height; - - if (scaled_width == width && scaled_height == height) - { - if (!mipmap) - { - glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data); - goto done; - } - scaled = malloc(scaled_width*scaled_height*4); - memcpy (scaled, data, width*height); - } - else - { - scaled = malloc(scaled_width*scaled_height*4); - GL_Resample8BitTexture (data, width, height, (void*) scaled, scaled_width, scaled_height); - } - - glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); - if (mipmap) - { - int miplevel; - - miplevel = 0; - while (scaled_width > 1 || scaled_height > 1) - { - GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height); - scaled_width >>= 1; - scaled_height >>= 1; - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; - miplevel++; - glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); - } - } -done: ; - - - if (mipmap) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - free(scaled); -} - -qboolean VID_Is8bit(); - -/* -=============== -GL_Upload8 -=============== -*/ -void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha) -{ - static unsigned *trans; - int i, s; - qboolean noalpha; - int p; - byte *indata; - int *outdata; - - s = width*height; - trans = malloc(s*4); - // if there are no transparent pixels, make it a 3 component - // texture even if it was specified as otherwise - if (alpha) - { - noalpha = true; - for (i=0 ; iidentifier)) - { - // LordHavoc: everyone hates cache mismatchs, so I fixed it - if (crc != glt->crc || width != glt->width || height != glt->height) - { - Con_DPrintf("GL_LoadTexture: cache mismatch, replacing old texture\n"); - goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace - //Sys_Error ("GL_LoadTexture: cache mismatch"); - } - if ((gl_lerpimages.value != 0) != glt->lerped) - goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace - return glt->texnum; - } - } - } - // LordHavoc: although this could be an else condition as it was in the original id code, - // it is more clear this way - // LordHavoc: check if there are still slots available - if (numgltextures >= MAX_GLTEXTURES) - Sys_Error ("GL_LoadTexture: ran out of texture slots (%d)\n", MAX_GLTEXTURES); - glt = &gltextures[numgltextures++]; - - strcpy (glt->identifier, identifier); - glt->texnum = texture_extension_number; - texture_extension_number++; -// LordHavoc: label to drop out of the loop into the setup code -GL_LoadTexture_setup: - glt->crc = crc; // LordHavoc: used to verify textures are identical - glt->width = width; - glt->height = height; - glt->mipmap = mipmap; - glt->bytesperpixel = bytesperpixel; - glt->lerped = gl_lerpimages.value != 0; - - glBindTexture(GL_TEXTURE_2D, glt->texnum); - - if (bytesperpixel == 1) // 8bit - GL_Upload8 (data, width, height, mipmap, alpha); - else // 32bit - GL_Upload32 (data, width, height, mipmap, true); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - return glt->texnum; -} - -/* -================ -GL_LoadPicTexture -================ -*/ -int GL_LoadPicTexture (qpic_t *pic) -{ - return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, 1); -} - -int GL_GetTextureSlots (int count) -{ - gltexture_t *glt, *first; - - first = glt = &gltextures[numgltextures]; - while (count--) - { - glt->identifier[0] = 0; - glt->texnum = texture_extension_number++; - glt->crc = 0; - glt->width = 0; - glt->height = 0; - glt->bytesperpixel = 0; - glt++; - numgltextures++; - } - return first->texnum; -}