X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_draw.c;h=a798805d0435fc907bb92b5de5afba2fd157adc9;hp=d9eebeb44ca70bc0f7bed524152ff8be6eb0380c;hb=281412c28688a491cc4124f0c5ec783a409df820;hpb=d57be67cb00229acb8564b92c8b7c58eeed8a0cb diff --git a/gl_draw.c b/gl_draw.c index d9eebeb4..a798805d 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -20,101 +20,303 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -//#define GL_COLOR_INDEX8_EXT 0x80E5 +cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"}; -cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"}; - -rtexture_t *char_texture; - -typedef struct -{ - rtexture_t *tex; -} glpic_t; - -rtexture_t *conbacktex; +static rtexture_t *char_texture; //============================================================================= /* Support Routines */ -typedef struct cachepic_s -{ - char name[MAX_QPATH]; - // FIXME: qpic is evil - qpic_t pic; - byte padding[32]; // for appended glpic -} -cachepic_t; +#define MAX_CACHED_PICS 256 +#define CACHEPICHASHSIZE 256 +static cachepic_t *cachepichash[CACHEPICHASHSIZE]; +static cachepic_t cachepics[MAX_CACHED_PICS]; +static int numcachepics; -#define MAX_CACHED_PICS 256 -cachepic_t menu_cachepics[MAX_CACHED_PICS]; -int menu_numcachepics; +static rtexturepool_t *drawtexturepool; -byte menuplyr_pixels[4096]; +static qbyte pointerimage[256] = +{ + "333333332......." + "26777761........" + "2655541........." + "265541.........." + "2654561........." + "26414561........" + "251.14561......." + "21...14561......" + "1.....141......." + ".......1........" + "................" + "................" + "................" + "................" + "................" + "................" +}; + +static rtexture_t *draw_generatemousepointer(void) +{ + int i; + qbyte buffer[256][4]; + for (i = 0;i < 256;i++) + { + if (pointerimage[i] == '.') + { + buffer[i][0] = 0; + buffer[i][1] = 0; + buffer[i][2] = 0; + buffer[i][3] = 0; + } + else + { + buffer[i][0] = (pointerimage[i] - '0') * 16; + buffer[i][1] = (pointerimage[i] - '0') * 16; + buffer[i][2] = (pointerimage[i] - '0') * 16; + buffer[i][3] = 255; + } + } + return R_LoadTexture(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); +} -int pic_texels; -int pic_count; +// must match NUMCROSSHAIRS in r_crosshairs.c +#define NUMCROSSHAIRS 5 -rtexturepool_t *drawtexturepool; +static qbyte *crosshairtexdata[NUMCROSSHAIRS] = +{ + "................" + "................" + "................" + "...33......33..." + "...355....553..." + "....577..775...." + ".....77..77....." + "................" + "................" + ".....77..77....." + "....577..775...." + "...355....553..." + "...33......33..." + "................" + "................" + "................" + , + "................" + "................" + "................" + "...3........3..." + "....5......5...." + ".....7....7....." + "......7..7......" + "................" + "................" + "......7..7......" + ".....7....7....." + "....5......5...." + "...3........3..." + "................" + "................" + "................" + , + "................" + ".......77......." + ".......77......." + "................" + "................" + ".......44......." + ".......44......." + ".77..44..44..77." + ".77..44..44..77." + ".......44......." + ".......44......." + "................" + ".......77......." + ".......77......." + "................" + "................" + , + "................" + "................" + "................" + "................" + "................" + "................" + "................" + "................" + "........7777777." + "........752....." + "........72......" + "........7......." + "........7......." + "........7......." + "................" + "................" + , + "................" + "................" + "................" + "................" + "................" + "........7......." + "................" + "........4......." + ".....7.4.4.7...." + "........4......." + "................" + "........7......." + "................" + "................" + "................" + "................" +}; + +static rtexture_t *draw_generatecrosshair(int num) +{ + int i; + char *in; + qbyte data[16*16][4]; + in = crosshairtexdata[num]; + for (i = 0;i < 16*16;i++) + { + if (in[i] == '.') + { + data[i][0] = 255; + data[i][1] = 255; + data[i][2] = 255; + data[i][3] = 0; + } + else + { + data[i][0] = 255; + data[i][1] = 255; + data[i][2] = 255; + data[i][3] = (qbyte) ((int) (in[i] - '0') * 255 / 7); + } + } + return R_LoadTexture(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE); +} /* ================ Draw_CachePic ================ */ -// FIXME: qpic is evil -qpic_t *Draw_CachePic (char *path) +// FIXME: move this to client somehow +cachepic_t *Draw_CachePic (char *path) { - cachepic_t *pic; - int i; - qpic_t *dat; - glpic_t *gl; - rtexture_t *tex; + int i, crc, hashkey; + cachepic_t *pic; + qpic_t *p; - for (pic = menu_cachepics, i = 0;i < menu_numcachepics;pic++, i++) + crc = CRC_Block(path, strlen(path)); + hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; + for (pic = cachepichash[hashkey];pic;pic = pic->chain) if (!strcmp (path, pic->name)) - return &pic->pic; + return pic; - if (menu_numcachepics == MAX_CACHED_PICS) - Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); - menu_numcachepics++; + if (numcachepics == MAX_CACHED_PICS) + Sys_Error ("numcachepics == MAX_CACHED_PICS"); + pic = cachepics + (numcachepics++); strcpy (pic->name, path); + // link into list + pic->chain = cachepichash[hashkey]; + cachepichash[hashkey] = pic; - // FIXME: move this to menu code - // HACK HACK HACK --- we need to keep the bytes for - // the translatable player picture just for the menu - // configuration dialog - if (!strcmp (path, "gfx/menuplyr.lmp")) + // load the pic from disk + pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true); + if (pic->tex == NULL && (p = W_GetLumpName (path))) { - dat = (qpic_t *)COM_LoadFile (path, false); - if (!dat) - Sys_Error("unable to load gfx/menuplyr.lmp"); - SwapPic (dat); - - memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); + if (!strcmp(path, "conchars")) + { + qbyte *pix; + // conchars is a raw image and with the wrong transparent color + pix = (qbyte *)p; + for (i = 0;i < 128 * 128;i++) + if (pix[i] == 0) + pix[i] = 255; + pic->tex = R_LoadTexture (drawtexturepool, path, 128, 128, pix, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); + } + else + pic->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); } + if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga")) + pic->tex = draw_generatemousepointer(); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1.tga")) + pic->tex = draw_generatecrosshair(0); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2.tga")) + pic->tex = draw_generatecrosshair(1); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair3.tga")) + pic->tex = draw_generatecrosshair(2); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair4.tga")) + pic->tex = draw_generatecrosshair(3); + if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5.tga")) + pic->tex = draw_generatecrosshair(4); + if (pic->tex == NULL) + Sys_Error ("Draw_CachePic: failed to load %s", path); + + pic->width = R_TextureWidth(pic->tex); + pic->height = R_TextureHeight(pic->tex); + return pic; +} - // load the pic from disk - if ((tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true))) +cachepic_t *Draw_NewPic(char *picname, int width, int height, int alpha, qbyte *pixels) +{ + int crc, hashkey; + cachepic_t *pic; + + crc = CRC_Block(picname, strlen(picname)); + hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; + for (pic = cachepichash[hashkey];pic;pic = pic->chain) + if (!strcmp (picname, pic->name)) + break; + + if (pic) { - // load the pic from an image file - pic->pic.width = image_width; - pic->pic.height = image_height; - gl = (glpic_t *)pic->pic.data; - gl->tex = tex; - return &pic->pic; + if (pic->tex && R_TextureWidth(pic->tex) == width && R_TextureHeight(pic->tex) == height && (R_TextureHasAlpha(pic->tex) != 0) == (alpha != 0)) + { + R_UpdateTexture(pic->tex, pixels); + return pic; + } } else { - qpic_t *p; - // load the pic from gfx.wad - p = W_GetLumpName (path); - if (!p) - Sys_Error ("Draw_CachePic: failed to load %s", path); - pic->pic.width = p->width; - pic->pic.height = p->height; - gl = (glpic_t *)pic->pic.data; - gl->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - return &pic->pic; + if (pic == NULL) + { + if (numcachepics == MAX_CACHED_PICS) + Sys_Error ("numcachepics == MAX_CACHED_PICS"); + pic = cachepics + (numcachepics++); + strcpy (pic->name, picname); + // link into list + pic->chain = cachepichash[hashkey]; + cachepichash[hashkey] = pic; + } + } + + pic->width = width; + pic->height = height; + if (pic->tex) + R_FreeTexture(pic->tex); + pic->tex = R_LoadTexture (drawtexturepool, picname, width, height, pixels, TEXTYPE_RGBA, alpha ? TEXF_ALPHA : 0); + return pic; +} + +void Draw_FreePic(char *picname) +{ + int crc; + int hashkey; + cachepic_t *pic; + // this doesn't really free the pic, but does free it's texture + crc = CRC_Block(picname, strlen(picname)); + hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; + for (pic = cachepichash[hashkey];pic;pic = pic->chain) + { + if (!strcmp (picname, pic->name)) + { + R_FreeTexture(pic->tex); + pic->width = 0; + pic->height = 0; + return; + } } } @@ -125,472 +327,376 @@ Draw_Init */ static void gl_draw_start(void) { - int i; - byte *draw_chars; - - menu_numcachepics = 0; - drawtexturepool = R_AllocTexturePool(); - char_texture = loadtextureimage (drawtexturepool, "conchars", 0, 0, false, false, true); - if (!char_texture) - { - draw_chars = W_GetLumpName ("conchars"); - // convert font to proper transparent color - for (i = 0;i < 128 * 128;i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; - - // now turn into texture - char_texture = R_LoadTexture (drawtexturepool, "charset", 128, 128, draw_chars, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - } - conbacktex = loadtextureimage(drawtexturepool, "gfx/conback", 0, 0, false, false, true); + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); + + char_texture = Draw_CachePic("conchars")->tex; } static void gl_draw_shutdown(void) { R_FreeTexturePool(&drawtexturepool); - menu_numcachepics = 0; + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); } -void SHOWLMP_clear(void); static void gl_draw_newmap(void) { - SHOWLMP_clear(); } -extern char engineversion[40]; -int engineversionx, engineversiony; - void GL_Draw_Init (void) { - int i; Cvar_RegisterVariable (&scr_conalpha); - for (i = 0;i < 40 && engineversion[i];i++) - engineversion[i] |= 0x80; // shift to orange - engineversionx = vid.conwidth - strlen(engineversion) * 8 - 8; - engineversiony = vid.conheight - 8; - - menu_numcachepics = 0; + numcachepics = 0; + memset(cachepichash, 0, sizeof(cachepichash)); R_RegisterModule("GL_Draw", gl_draw_start, gl_draw_shutdown, gl_draw_newmap); } -/* -================ -Draw_Character +extern cvar_t gl_mesh_drawmode; +extern int gl_maxdrawrangeelementsvertices; +extern int gl_maxdrawrangeelementsindices; -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. -================ -*/ -void Draw_Character (int x, int y, int num) +void R_DrawQueue(void) { - int row, col; - float frow, fcol, size; + int pos, num, chartexnum, overbright; + float x, y, w, h, s, t, u, v; + cachepic_t *pic; + drawqueue_t *dq; + char *str, *currentpic; + int batch, batchcount, additive; + unsigned int color; + drawqueuemesh_t *mesh; - if (num == 32) - return; // space + if (!r_render.integer) + return; - num &= 255; - - if (y <= -8) - return; // totally off screen + qglViewport(vid.realx, vid.realy, vid.realwidth, vid.realheight); - row = num>>4; - col = num&15; + qglMatrixMode(GL_PROJECTION); + qglLoadIdentity(); + qglOrtho(0, vid.conwidth, vid.conheight, 0, -99999, 99999); - frow = row*0.0625; - fcol = col*0.0625; - size = 0.0625; + qglMatrixMode(GL_MODELVIEW); + qglLoadIdentity(); - if (!r_render.integer) - return; - glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture)); - CHECKGLERROR - // LordHavoc: NEAREST mode on text if not scaling up - if (vid.realwidth <= (int) vid.conwidth) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - CHECKGLERROR - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - CHECKGLERROR - } + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_CULL_FACE); + qglEnable(GL_BLEND); + qglEnable(GL_TEXTURE_2D); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - if (lighthalf) - glColor3f(0.5f,0.5f,0.5f); - else - glColor3f(1.0f,1.0f,1.0f); - CHECKGLERROR - glBegin (GL_QUADS); - glTexCoord2f (fcol, frow); - glVertex2f (x, y); - glTexCoord2f (fcol + size, frow); - glVertex2f (x+8, y); - glTexCoord2f (fcol + size, frow + size); - glVertex2f (x+8, y+8); - glTexCoord2f (fcol, frow + size); - glVertex2f (x, y+8); - glEnd (); - CHECKGLERROR - - // LordHavoc: revert to LINEAR mode -// if (vid.realwidth <= (int) vid.conwidth) -// { -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// } -} + chartexnum = R_GetTexture(char_texture); -/* -================ -Draw_String -================ -*/ -// LordHavoc: sped this up a lot, and added maxlen -void Draw_String (int x, int y, char *str, int maxlen) -{ - int num; - float frow, fcol; - if (!r_render.integer) - return; - if (y <= -8 || y >= (int) vid.conheight || x >= (int) vid.conwidth || *str == 0) // completely offscreen or no text to print - return; - if (maxlen < 1) - maxlen = strlen(str); - else if (maxlen > (int) strlen(str)) - maxlen = strlen(str); - glBindTexture(GL_TEXTURE_2D, R_GetTexture(char_texture)); - - // LordHavoc: NEAREST mode on text if not scaling up - if (vid.realwidth <= (int) vid.conwidth) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - CHECKGLERROR - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - CHECKGLERROR - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - CHECKGLERROR - } + additive = false; + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + currentpic = ""; + pic = NULL; + qglBindTexture(GL_TEXTURE_2D, 0); + color = 0; + qglColor4ub(0,0,0,0); - if (lighthalf) - glColor3f(0.5f,0.5f,0.5f); - else - glColor3f(1.0f,1.0f,1.0f); - CHECKGLERROR - glBegin (GL_QUADS); - while (maxlen-- && x < (int) vid.conwidth) // stop rendering when out of characters or room + overbright = v_overbrightbits.integer; + batch = false; + batchcount = 0; + for (pos = 0;pos < r_refdef.drawqueuesize;pos += ((drawqueue_t *)(r_refdef.drawqueue + pos))->size) { - if ((num = *str++) != 32) // skip spaces + dq = (drawqueue_t *)(r_refdef.drawqueue + pos); + if (dq->flags & DRAWFLAG_ADDITIVE) { - 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); + if (!additive) + { + if (batch) + { + batch = false; + qglEnd(); + } + additive = true; + qglBlendFunc(GL_SRC_ALPHA, GL_ONE); + } } - x += 8; - } - glEnd (); - CHECKGLERROR + else + { + if (additive) + { + if (batch) + { + batch = false; + qglEnd(); + } + additive = false; + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + if (color != dq->color) + { + color = dq->color; + qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF)); + } + if (batch && batchcount > 128) + { + batch = false; + qglEnd(); + } + x = dq->x; + y = dq->y; + w = dq->scalex; + h = dq->scaley; + switch(dq->command) + { + case DRAWQUEUE_PIC: + str = (char *)(dq + 1); + if (*str) + { + if (strcmp(str, currentpic)) + { + if (batch) + { + batch = false; + qglEnd(); + } + currentpic = str; + pic = Draw_CachePic(str); + qglBindTexture(GL_TEXTURE_2D, R_GetTexture(pic->tex)); + } + if (w == 0) + w = pic->width; + if (h == 0) + h = pic->height; + if (!batch) + { + batch = true; + qglBegin(GL_TRIANGLES); + batchcount = 0; + } + qglTexCoord2f (0, 0);qglVertex2f (x , y ); + qglTexCoord2f (1, 0);qglVertex2f (x+w, y ); + qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h); + qglTexCoord2f (0, 0);qglVertex2f (x , y ); + qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h); + qglTexCoord2f (0, 1);qglVertex2f (x , y+h); + batchcount++; + } + else + { + if (currentpic[0]) + { + if (batch) + { + batch = false; + qglEnd(); + } + currentpic = ""; + qglBindTexture(GL_TEXTURE_2D, 0); + } + if (!batch) + { + batch = true; + qglBegin(GL_TRIANGLES); + batchcount = 0; + } + qglTexCoord2f (0, 0);qglVertex2f (x , y ); + qglTexCoord2f (1, 0);qglVertex2f (x+w, y ); + qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h); + qglTexCoord2f (0, 0);qglVertex2f (x , y ); + qglTexCoord2f (1, 1);qglVertex2f (x+w, y+h); + qglTexCoord2f (0, 1);qglVertex2f (x , y+h); + batchcount++; + } + break; + case DRAWQUEUE_STRING: + str = (char *)(dq + 1); + if (strcmp("conchars", currentpic)) + { + if (batch) + { + batch = false; + qglEnd(); + } + currentpic = "conchars"; + qglBindTexture(GL_TEXTURE_2D, chartexnum); + } + if (!batch) + { + batch = true; + qglBegin(GL_TRIANGLES); + batchcount = 0; + } + while ((num = *str++) && x < vid.conwidth) + { + if (num != ' ') + { + s = (num & 15)*0.0625f + (0.5f / 256.0f); + t = (num >> 4)*0.0625f + (0.5f / 256.0f); + u = 0.0625f - (1.0f / 256.0f); + v = 0.0625f - (1.0f / 256.0f); + qglTexCoord2f (s , t );qglVertex2f (x , y ); + qglTexCoord2f (s+u, t );qglVertex2f (x+w, y ); + qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h); + qglTexCoord2f (s , t );qglVertex2f (x , y ); + qglTexCoord2f (s+u, t+v);qglVertex2f (x+w, y+h); + qglTexCoord2f (s , t+v);qglVertex2f (x , y+h); + batchcount++; + } + x += w; + } + break; + case DRAWQUEUE_MESH: + if (batch) + { + batch = false; + qglEnd(); + } + mesh = (void *)(dq + 1); + qglBindTexture(GL_TEXTURE_2D, R_GetTexture(mesh->texture)); - // LordHavoc: revert to LINEAR mode -// if (vid.realwidth < (int) vid.conwidth) -// { -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// } -} + if (gl_mesh_drawmode.integer < 0) + Cvar_SetValueQuick(&gl_mesh_drawmode, 0); + if (gl_mesh_drawmode.integer > 3) + Cvar_SetValueQuick(&gl_mesh_drawmode, 3); + if (gl_mesh_drawmode.integer >= 3 && qglDrawRangeElements == NULL) + Cvar_SetValueQuick(&gl_mesh_drawmode, 2); -void Draw_AdditiveString (int x, int y, char *str, int maxlen) -{ - if (!r_render.integer) - return; - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - CHECKGLERROR - Draw_String(x, y, str, maxlen); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - CHECKGLERROR -} + if (gl_mesh_drawmode.integer > 0) + { + qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), mesh->vertices);CHECKGLERROR + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoords);CHECKGLERROR + qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), mesh->colors);CHECKGLERROR + qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR + } -void Draw_GenericPic (rtexture_t *tex, float red, float green, float blue, float alpha, int x, int y, int width, int height) -{ - if (!r_render.integer) - return; - if (lighthalf) - glColor4f(red * 0.5f, green * 0.5f, blue * 0.5f, alpha); - else - glColor4f(red, green, blue, alpha); - CHECKGLERROR - glBindTexture(GL_TEXTURE_2D, R_GetTexture(tex)); - CHECKGLERROR - 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 (); + if (gl_mesh_drawmode.integer >= 3/* && (mesh->numvertices) <= gl_maxdrawrangeelementsvertices && (mesh->numindices) <= gl_maxdrawrangeelementsindices*/) + { + // GL 1.2 or GL 1.1 with extension + GL_LockArray(0, mesh->numvertices); + qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertices, mesh->numindices, GL_UNSIGNED_INT, mesh->indices); + CHECKGLERROR + GL_UnlockArray(); + } + else if (gl_mesh_drawmode.integer >= 2) + { + // GL 1.1 + GL_LockArray(0, mesh->numvertices); + qglDrawElements(GL_TRIANGLES, mesh->numindices, GL_UNSIGNED_INT, mesh->indices); + CHECKGLERROR + GL_UnlockArray(); + } + else if (gl_mesh_drawmode.integer >= 1) + { + int i; + // GL 1.1 + // feed it manually using glArrayElement + GL_LockArray(0, mesh->numvertices); + qglBegin(GL_TRIANGLES); + for (i = 0;i < mesh->numindices;i++) + qglArrayElement(mesh->indices[i]); + qglEnd(); + CHECKGLERROR + GL_UnlockArray(); + } + else + { + int i, in; + // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver + // feed it manually + qglBegin(GL_TRIANGLES); + for (i = 0;i < mesh->numindices;i++) + { + in = mesh->indices[i]; + qglColor4ub(mesh->colors[in * 4], mesh->colors[in * 4 + 1], mesh->colors[in * 4 + 2], mesh->colors[in * 4 + 3]); + qglTexCoord2f(mesh->texcoords[in * 2], mesh->texcoords[in * 2 + 1]); + qglVertex3f(mesh->vertices[in * 3], mesh->vertices[in * 3 + 1], mesh->vertices[in * 3 + 2]); + } + qglEnd(); + CHECKGLERROR + } + if (gl_mesh_drawmode.integer > 0) + { + qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR + } + // restore color, since it got trashed by using color array + qglColor4ub((qbyte)(((color >> 24) & 0xFF) >> overbright), (qbyte)(((color >> 16) & 0xFF) >> overbright), (qbyte)(((color >> 8) & 0xFF) >> overbright), (qbyte)(color & 0xFF)); + CHECKGLERROR + currentpic = "\0"; + break; + } + } + if (batch) + qglEnd(); CHECKGLERROR -} - -/* -============= -Draw_AlphaPic -============= -*/ -void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) -{ - if (pic) - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,alpha, x,y,pic->width, pic->height); -} - -/* -============= -Draw_Pic -============= -*/ -void Draw_Pic (int x, int y, qpic_t *pic) -{ - if (pic) - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height); -} - - -void Draw_AdditivePic (int x, int y, qpic_t *pic) -{ - if (pic) + if (!v_hwgamma.integer) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + qglDisable(GL_TEXTURE_2D); CHECKGLERROR - Draw_GenericPic(((glpic_t *)pic->data)->tex, 1,1,1,1, x,y,pic->width, pic->height); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + t = v_contrast.value * (float) (1 << v_overbrightbits.integer); + if (t >= 1.01f) + { + qglBlendFunc (GL_DST_COLOR, GL_ONE); + CHECKGLERROR + qglBegin (GL_TRIANGLES); + while (t >= 1.01f) + { + num = (int) ((t - 1.0f) * 255.0f); + if (num > 255) + num = 255; + qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255); + qglVertex2f (-5000, -5000); + qglVertex2f (10000, -5000); + qglVertex2f (-5000, 10000); + t *= 0.5; + } + qglEnd (); + CHECKGLERROR + } + else if (t <= 0.99f) + { + qglBlendFunc(GL_ZERO, GL_SRC_COLOR); + CHECKGLERROR + qglBegin(GL_TRIANGLES); + num = (int) (t * 255.0f); + qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255); + qglVertex2f (-5000, -5000); + qglVertex2f (10000, -5000); + qglVertex2f (-5000, 10000); + qglEnd(); + CHECKGLERROR + } + if (v_brightness.value >= 0.01f) + { + qglBlendFunc (GL_ONE, GL_ONE); + CHECKGLERROR + num = (int) (v_brightness.value * 255.0f); + qglColor4ub ((qbyte) num, (qbyte) num, (qbyte) num, 255); + CHECKGLERROR + qglBegin (GL_TRIANGLES); + qglVertex2f (-5000, -5000); + qglVertex2f (10000, -5000); + qglVertex2f (-5000, 10000); + qglEnd (); + CHECKGLERROR + } + qglEnable(GL_TEXTURE_2D); CHECKGLERROR } -} - - -/* -============= -Draw_PicTranslate - -Only used for the player color selection menu -============= -*/ -void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation) -{ - int i, c; - byte *trans, *src, *dest; - rtexture_t *rt; - - if (pic == NULL) - return; - - c = pic->width * pic->height; - src = menuplyr_pixels; - dest = trans = Mem_Alloc(tempmempool, c); - for (i = 0;i < c;i++) - *dest++ = translation[*src++]; - - rt = R_LoadTexture (drawtexturepool, "translatedplayerpic", pic->width, pic->height, trans, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE); - Mem_Free(trans); - - if (!r_render.integer) - return; - Draw_GenericPic (rt, 1,1,1,1, x, y, pic->width, pic->height); -} - - -/* -================ -Draw_ConsoleBackground - -================ -*/ -void Draw_ConsoleBackground (int lines) -{ - Draw_GenericPic (conbacktex, 1,1,1,scr_conalpha.value * lines / vid.conheight, 0, lines - vid.conheight, vid.conwidth, vid.conheight); - // LordHavoc: draw version - Draw_String(engineversionx, lines - vid.conheight + engineversiony, engineversion, 9999); -} - -/* -============= -Draw_Fill - -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.integer) - return; - glDisable (GL_TEXTURE_2D); - CHECKGLERROR - if (lighthalf) - { - byte *tempcolor = (byte *)&d_8to24table[c]; - glColor4ub ((byte) (tempcolor[0] >> 1), (byte) (tempcolor[1] >> 1), (byte) (tempcolor[2] >> 1), tempcolor[3]); - } - else - glColor4ubv ((byte *)&d_8to24table[c]); - CHECKGLERROR - - glBegin (GL_QUADS); - - glVertex2f (x,y); - glVertex2f (x+w, y); - glVertex2f (x+w, y+h); - glVertex2f (x, y+h); - - glEnd (); - CHECKGLERROR - glColor3f(1,1,1); - CHECKGLERROR - glEnable (GL_TEXTURE_2D); - CHECKGLERROR -} -//============================================================================= - -//============================================================================= - -/* -================ -GL_Set2D - -Setup as if the screen was 320*200 -================ -*/ -void GL_Set2D (void) -{ - if (!r_render.integer) - return; - glViewport (vid.realx, vid.realy, vid.realwidth, vid.realheight); - CHECKGLERROR - - glMatrixMode(GL_PROJECTION); - CHECKGLERROR - glLoadIdentity (); - CHECKGLERROR - glOrtho (0, vid.conwidth, vid.conheight, 0, -99999, 99999); - CHECKGLERROR - - glMatrixMode(GL_MODELVIEW); - CHECKGLERROR - glLoadIdentity (); - CHECKGLERROR - glDisable (GL_DEPTH_TEST); - CHECKGLERROR - glDisable (GL_CULL_FACE); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CHECKGLERROR - glEnable (GL_BLEND); + qglEnable (GL_CULL_FACE); CHECKGLERROR - glEnable(GL_TEXTURE_2D); + qglEnable (GL_DEPTH_TEST); CHECKGLERROR - - // LordHavoc: added this - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_BLEND); CHECKGLERROR - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - CHECKGLERROR - - glColor3f(1,1,1); + qglColor4ub (255, 255, 255, 255); CHECKGLERROR } -// LordHavoc: SHOWLMP stuff -#define SHOWLMP_MAXLABELS 256 -typedef struct showlmp_s -{ - qboolean isactive; - float x; - float y; - char label[32]; - char pic[128]; -} showlmp_t; - -showlmp_t showlmp[SHOWLMP_MAXLABELS]; - -void SHOWLMP_decodehide(void) -{ - int i; - byte *lmplabel; - lmplabel = MSG_ReadString(); - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0) - { - showlmp[i].isactive = false; - return; - } -} - -void SHOWLMP_decodeshow(void) -{ - int i, k; - byte lmplabel[256], picname[256]; - float x, y; - strcpy(lmplabel,MSG_ReadString()); - strcpy(picname, MSG_ReadString()); - if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk - { - x = MSG_ReadByte(); - y = MSG_ReadByte(); - } - else - { - x = MSG_ReadShort(); - y = MSG_ReadShort(); - } - k = -1; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive) - { - if (strcmp(showlmp[i].label, lmplabel) == 0) - { - k = i; - break; // drop out to replace it - } - } - else if (k < 0) // find first empty one to replace - k = i; - if (k < 0) - return; // none found to replace - // change existing one - showlmp[k].isactive = true; - strcpy(showlmp[k].label, lmplabel); - strcpy(showlmp[k].pic, picname); - showlmp[k].x = x; - showlmp[k].y = y; -} - -void SHOWLMP_drawall(void) -{ - int i; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - if (showlmp[i].isactive) - Draw_Pic(showlmp[i].x, showlmp[i].y, Draw_CachePic(showlmp[i].pic)); -} - -void SHOWLMP_clear(void) -{ - int i; - for (i = 0;i < SHOWLMP_MAXLABELS;i++) - showlmp[i].isactive = false; -}