12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379 |
- /*
- Copyright (C) 1996-1997 Id Software, Inc.
- 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.
- 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.
- 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 the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- // draw.c -- this is the only file outside the refresh that touches the
- // vid buffer
- #include "quakedef.h"
- extern unsigned char d_15to8table[65536];
- extern cvar_t crosshair, cl_crossx, cl_crossy, crosshaircolor;
- cvar_t gl_nobind = {"gl_nobind", "0"};
- cvar_t gl_max_size = {"gl_max_size", "1024"};
- cvar_t gl_picmip = {"gl_picmip", "0"};
- byte *draw_chars; // 8*8 graphic characters
- qpic_t *draw_disc;
- qpic_t *draw_backtile;
- int translate_texture;
- int char_texture;
- int cs_texture; // crosshair texture
- 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
- };
- typedef struct
- {
- int texnum;
- 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_lightmap_format = 4;
- int gl_solid_format = 3;
- int gl_alpha_format = 4;
- 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;
- } gltexture_t;
- #define MAX_GLTEXTURES 1024
- gltexture_t gltextures[MAX_GLTEXTURES];
- int numgltextures;
- void GL_Bind (int texnum)
- {
- if (gl_nobind.value)
- texnum = char_texture;
- if (currenttexture == texnum)
- return;
- currenttexture = texnum;
- #ifdef _WIN32
- bindTexFunc (GL_TEXTURE_2D, texnum);
- #else
- glBindTexture (GL_TEXTURE_2D, texnum);
- #endif
- }
- /*
- =============================================================================
- scrap allocation
- Allocate all the little status bar obejcts into a single texture
- to crutch up stupid hardware / drivers
- =============================================================================
- */
- #define MAX_SCRAPS 1
- #define BLOCK_WIDTH 256
- #define BLOCK_HEIGHT 256
- 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)
- {
- int i, j;
- int best, best2;
- int texnum;
- for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
- {
- best = BLOCK_HEIGHT;
- for (i=0 ; i<BLOCK_WIDTH-w ; i++)
- {
- best2 = 0;
- for (j=0 ; j<w ; j++)
- {
- if (scrap_allocated[texnum][i+j] >= best)
- break;
- if (scrap_allocated[texnum][i+j] > best2)
- best2 = scrap_allocated[texnum][i+j];
- }
- if (j == w)
- { // this is a valid spot
- *x = i;
- *y = best = best2;
- }
- }
- if (best + h > BLOCK_HEIGHT)
- continue;
- for (i=0 ; i<w ; i++)
- scrap_allocated[texnum][*x + i] = best + h;
- return texnum;
- }
- Sys_Error ("Scrap_AllocBlock: full");
- return 0;
- }
- int scrap_uploads;
- void Scrap_Upload (void)
- {
- scrap_uploads++;
- GL_Bind(scrap_texnum);
- GL_Upload8 (scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
- scrap_dirty = false;
- }
- //=============================================================================
- /* Support Routines */
- typedef struct cachepic_s
- {
- char name[MAX_QPATH];
- qpic_t pic;
- byte padding[32]; // for appended glpic
- } cachepic_t;
- #define MAX_CACHED_PICS 128
- cachepic_t menu_cachepics[MAX_CACHED_PICS];
- int menu_numcachepics;
- byte menuplyr_pixels[4096];
- int pic_texels;
- int pic_count;
- qpic_t *Draw_PicFromWad (char *name)
- {
- qpic_t *p;
- glpic_t *gl;
- p = W_GetLumpName (name);
- gl = (glpic_t *)p->data;
- // load little ones into the scrap
- if (p->width < 64 && p->height < 64)
- {
- int x, y;
- int i, j, k;
- int texnum;
- texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
- scrap_dirty = true;
- k = 0;
- 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];
- texnum += scrap_texnum;
- gl->texnum = 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;
- gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
- pic_count++;
- pic_texels += p->width*p->height;
- }
- else
- {
- gl->texnum = GL_LoadPicTexture (p);
- gl->sl = 0;
- gl->sh = 1;
- gl->tl = 0;
- gl->th = 1;
- }
- return p;
- }
- /*
- ================
- Draw_CachePic
- ================
- */
- qpic_t *Draw_CachePic (char *path)
- {
- cachepic_t *pic;
- int i;
- qpic_t *dat;
- glpic_t *gl;
- for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
- if (!strcmp (path, pic->name))
- return &pic->pic;
- if (menu_numcachepics == MAX_CACHED_PICS)
- Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
- menu_numcachepics++;
- strcpy (pic->name, path);
- //
- // load the pic from disk
- //
- dat = (qpic_t *)COM_LoadTempFile (path);
- if (!dat)
- Sys_Error ("Draw_CachePic: failed to load %s", path);
- SwapPic (dat);
- // 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"))
- memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
- pic->pic.width = dat->width;
- pic->pic.height = dat->height;
- gl = (glpic_t *)pic->pic.data;
- gl->texnum = GL_LoadPicTexture (dat);
- gl->sl = 0;
- gl->sh = 1;
- gl->tl = 0;
- gl->th = 1;
- 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}
- };
- /*
- ===============
- Draw_TextureMode_f
- ===============
- */
- void Draw_TextureMode_f (void)
- {
- int i;
- gltexture_t *glt;
- if (Cmd_Argc() == 1)
- {
- 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;
- }
- 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;
- }
- gl_filter_min = modes[i].minimize;
- gl_filter_max = modes[i].maximize;
- // change all the existing mipmap texture objects
- for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
- {
- if (glt->mipmap)
- {
- GL_Bind (glt->texnum);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
- }
- }
- }
- /*
- ===============
- Draw_Init
- ===============
- */
- void Draw_Init (void)
- {
- int i;
- qpic_t *cb;
- byte *dest;
- int x;
- char ver[40];
- glpic_t *gl;
- int start;
- byte *ncdata;
- Cvar_RegisterVariable (&gl_nobind);
- Cvar_RegisterVariable (&gl_max_size);
- Cvar_RegisterVariable (&gl_picmip);
- // 3dfx can only handle 256 wide textures
- if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) ||
- !Q_strncasecmp ((char *)gl_renderer, "Mesa",4))
- Cvar_Set ("gl_max_size", "256");
- Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_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);
- // Draw_CrosshairAdjust();
- cs_texture = GL_LoadTexture ("crosshair", 8, 8, cs_data, false, true);
- start = Hunk_LowMark ();
- cb = (qpic_t *)COM_LoadHunkFile ("gfx/conback.lmp");
- if (!cb)
- Sys_Error ("Couldn't load gfx/conback.lmp");
- SwapPic (cb);
- sprintf (ver, "%4.2f", VERSION);
- dest = cb->data + 320 + 320*186 - 11 - 8*strlen(ver);
- for (x=0 ; x<strlen(ver) ; x++)
- Draw_CharToConback (ver[x], dest+(x<<3));
- #if 0
- conback->width = vid.conwidth;
- conback->height = vid.conheight;
- // scale console to vid size
- dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
- for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
- {
- src = cb->data + cb->width * (y*cb->height/vid.conheight);
- if (vid.conwidth == cb->width)
- memcpy (dest, src, vid.conwidth);
- else
- {
- f = 0;
- fstep = cb->width*0x10000/vid.conwidth;
- for (x=0 ; x<vid.conwidth ; x+=4)
- {
- dest[x] = src[f>>16];
- f += fstep;
- dest[x+1] = src[f>>16];
- f += fstep;
- dest[x+2] = src[f>>16];
- f += fstep;
- dest[x+3] = src[f>>16];
- f += fstep;
- }
- }
- }
- #else
- conback->width = cb->width;
- conback->height = cb->height;
- ncdata = cb->data;
- #endif
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl = (glpic_t *)conback->data;
- gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false);
- gl->sl = 0;
- gl->sh = 1;
- gl->tl = 0;
- gl->th = 1;
- conback->width = vid.conwidth;
- conback->height = vid.conheight;
- // free loaded console
- Hunk_FreeToLowMark (start);
- // 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");
- draw_backtile = Draw_PicFromWad ("backtile");
- }
- /*
- ================
- Draw_Character
- 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)
- {
- int row, col;
- float frow, fcol, size;
- if (num == 32)
- return; // space
- num &= 255;
-
- if (y <= -8)
- return; // totally off screen
- row = num>>4;
- col = num&15;
- frow = row*0.0625;
- fcol = col*0.0625;
- size = 0.0625;
- GL_Bind (char_texture);
- 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 ();
- }
- /*
- ================
- Draw_String
- ================
- */
- void Draw_String (int x, int y, char *str)
- {
- while (*str)
- {
- Draw_Character (x, y, *str);
- str++;
- x += 8;
- }
- }
- /*
- ================
- Draw_Alt_String
- ================
- */
- void Draw_Alt_String (int x, int y, char *str)
- {
- while (*str)
- {
- Draw_Character (x, y, (*str) | 0x80);
- str++;
- x += 8;
- }
- }
- void Draw_Crosshair(void)
- {
- int x, y;
- extern vrect_t scr_vrect;
- unsigned char *pColor;
- if (crosshair.value == 2) {
- x = scr_vrect.x + scr_vrect.width/2 - 3 + cl_crossx.value;
- y = scr_vrect.y + scr_vrect.height/2 - 3 + cl_crossy.value;
- glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- pColor = (unsigned char *) &d_8to24table[(byte) crosshaircolor.value];
- glColor4ubv ( pColor );
- GL_Bind (cs_texture);
- glBegin (GL_QUADS);
- glTexCoord2f (0, 0);
- glVertex2f (x - 4, y - 4);
- glTexCoord2f (1, 0);
- glVertex2f (x+12, y-4);
- glTexCoord2f (1, 1);
- glVertex2f (x+12, y+12);
- glTexCoord2f (0, 1);
- glVertex2f (x - 4, y+12);
- glEnd ();
-
- glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
- } else if (crosshair.value)
- Draw_Character (scr_vrect.x + scr_vrect.width/2-4 + cl_crossx.value,
- scr_vrect.y + scr_vrect.height/2-4 + cl_crossy.value,
- '+');
- }
- /*
- ================
- Draw_DebugChar
- Draws a single character directly to the upper right corner of the screen.
- This is for debugging lockups by drawing different chars in different parts
- of the code.
- ================
- */
- void Draw_DebugChar (char num)
- {
- }
- /*
- =============
- Draw_Pic
- =============
- */
- void Draw_Pic (int x, int y, qpic_t *pic)
- {
- glpic_t *gl;
- if (scrap_dirty)
- Scrap_Upload ();
- gl = (glpic_t *)pic->data;
- glColor4f (1,1,1,1);
- GL_Bind (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);
- glEnd ();
- }
- /*
- =============
- Draw_AlphaPic
- =============
- */
- void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
- {
- glpic_t *gl;
- 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 (1,1,1,alpha);
- GL_Bind (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);
- glEnd ();
- glColor4f (1,1,1,1);
- glEnable(GL_ALPHA_TEST);
- glDisable (GL_BLEND);
- }
- void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height)
- {
- glpic_t *gl;
- float newsl, newtl, newsh, newth;
- float oldglwidth, oldglheight;
- if (scrap_dirty)
- Scrap_Upload ();
- gl = (glpic_t *)pic->data;
-
- oldglwidth = gl->sh - gl->sl;
- oldglheight = gl->th - gl->tl;
- 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;
-
- glColor4f (1,1,1,1);
- GL_Bind (gl->texnum);
- glBegin (GL_QUADS);
- glTexCoord2f (newsl, newtl);
- glVertex2f (x, y);
- glTexCoord2f (newsh, newtl);
- glVertex2f (x+width, y);
- glTexCoord2f (newsh, newth);
- glVertex2f (x+width, y+height);
- glTexCoord2f (newsl, newth);
- glVertex2f (x, y+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");
- }
-
- Draw_Pic (x, y, pic);
- }
- /*
- =============
- 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 trans[64*64], *dest;
- byte *src;
- int p;
- GL_Bind (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);
- 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);
- glEnd ();
- }
- /*
- ================
- Draw_ConsoleBackground
- ================
- */
- void Draw_ConsoleBackground (int lines)
- {
- char ver[80];
- int x, i;
- int y;
- y = (vid.height * 3) >> 2;
- if (lines > y)
- Draw_Pic(0, lines-vid.height, conback);
- else
- Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
- // hack the version number directly into the pic
- // y = lines-186;
- y = lines-14;
- if (!cls.download) {
- #ifdef __linux__
- sprintf (ver, "LinuxGL (%4.2f) QuakeWorld", LINUX_VERSION);
- #else
- sprintf (ver, "GL (%4.2f) QuakeWorld", GLQUAKE_VERSION);
- #endif
- x = vid.conwidth - (strlen(ver)*8 + 11) - (vid.conwidth*8/320)*7;
- for (i=0 ; i<strlen(ver) ; i++)
- Draw_Character (x + i * 8, y, ver[i] | 0x80);
- }
- }
- /*
- =============
- Draw_TileClear
- This repeats a 64*64 tile graphic to fill the screen around a sized down
- refresh window.
- =============
- */
- void Draw_TileClear (int x, int y, int w, int h)
- {
- glColor3f (1,1,1);
- GL_Bind (*(int *)draw_backtile->data);
- glBegin (GL_QUADS);
- glTexCoord2f (x/64.0, y/64.0);
- glVertex2f (x, y);
- 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);
- glEnd ();
- }
- /*
- =============
- Draw_Fill
- Fills a box of pixels with a single color
- =============
- */
- void Draw_Fill (int x, int y, int w, int h, int c)
- {
- 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);
- glBegin (GL_QUADS);
- glVertex2f (x,y);
- glVertex2f (x+w, y);
- glVertex2f (x+w, y+h);
- glVertex2f (x, y+h);
- glEnd ();
- glColor3f (1,1,1);
- glEnable (GL_TEXTURE_2D);
- }
- //=============================================================================
- /*
- ================
- Draw_FadeScreen
- ================
- */
- void Draw_FadeScreen (void)
- {
- glEnable (GL_BLEND);
- glDisable (GL_TEXTURE_2D);
- glColor4f (0, 0, 0, 0.8);
- glBegin (GL_QUADS);
- glVertex2f (0,0);
- glVertex2f (vid.width, 0);
- glVertex2f (vid.width, vid.height);
- glVertex2f (0, vid.height);
- glEnd ();
- glColor4f (1,1,1,1);
- glEnable (GL_TEXTURE_2D);
- glDisable (GL_BLEND);
- Sbar_Changed();
- }
- //=============================================================================
- /*
- ================
- Draw_BeginDisc
- Draws the little blue disc in the corner of the screen.
- Call before beginning any disc IO.
- ================
- */
- void Draw_BeginDisc (void)
- {
- if (!draw_disc)
- return;
- glDrawBuffer (GL_FRONT);
- Draw_Pic (vid.width - 24, 0, draw_disc);
- glDrawBuffer (GL_BACK);
- }
- /*
- ================
- Draw_EndDisc
- Erases the disc icon.
- Call after completing any disc IO
- ================
- */
- void Draw_EndDisc (void)
- {
- }
- /*
- ================
- GL_Set2D
- Setup as if the screen was 320*200
- ================
- */
- void GL_Set2D (void)
- {
- glViewport (glx, gly, glwidth, glheight);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity ();
- glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity ();
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_CULL_FACE);
- glDisable (GL_BLEND);
- glEnable (GL_ALPHA_TEST);
- // glDisable (GL_ALPHA_TEST);
- glColor4f (1,1,1,1);
- }
- //====================================================================
- /*
- ================
- GL_FindTexture
- ================
- */
- int GL_FindTexture (char *identifier)
- {
- int i;
- gltexture_t *glt;
- for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
- {
- if (!strcmp (identifier, glt->identifier))
- return gltextures[i].texnum;
- }
- return -1;
- }
- /*
- ================
- GL_ResampleTexture
- ================
- */
- void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight)
- {
- int i, j;
- unsigned *inrow;
- unsigned frac, fracstep;
- fracstep = inwidth*0x10000/outwidth;
- for (i=0 ; i<outheight ; i++, out += outwidth)
- {
- inrow = in + inwidth*(i*inheight/outheight);
- frac = fracstep >> 1;
- for (j=0 ; j<outwidth ; j+=4)
- {
- out[j] = inrow[frac>>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_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<outheight ; i++, out += outwidth)
- {
- inrow = in + inwidth*(i*inheight/outheight);
- frac = fracstep >> 1;
- for (j=0 ; j<outwidth ; j+=4)
- {
- out[j] = inrow[frac>>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<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;
- }
- }
- }
- /*
- ================
- GL_MipMap8Bit
- Mipping for 8 bit textures
- ================
- */
- void GL_MipMap8Bit (byte *in, int width, int height)
- {
- int i, j;
- byte *out;
- unsigned short r,g,b;
- byte *at1, *at2, *at3, *at4;
- height >>= 1;
- out = in;
- 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)];
- }
- }
- /*
- ===============
- GL_Upload32
- ===============
- */
- void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha)
- {
- int samples;
- static unsigned scaled[1024*512]; // [512*256];
- int scaled_width, scaled_height;
- 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 (scaled_width * scaled_height > sizeof(scaled)/4)
- Sys_Error ("GL_LoadTexture: too big");
- samples = alpha ? gl_alpha_format : gl_solid_format;
- #if 0
- if (mipmap)
- gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
- else if (scaled_width == width && scaled_height == height)
- glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
- else
- {
- gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
- 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;
- if (scaled_width == width && scaled_height == height)
- {
- if (!mipmap)
- {
- glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- goto done;
- }
- memcpy (scaled, data, width*height*4);
- }
- 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);
- }
- }
- done: ;
- #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);
- }
- }
- void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha)
- {
- int i, s;
- qboolean noalpha;
- int samples;
- static unsigned char scaled[1024*512]; // [512*256];
- int scaled_width, scaled_height;
- s = width*height;
- // 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 ; i<s ; i++)
- {
- if (data[i] == 255)
- noalpha = false;
- }
- if (alpha && noalpha)
- alpha = false;
- }
- 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 (scaled_width * scaled_height > sizeof(scaled))
- Sys_Error ("GL_LoadTexture: too big");
- samples = 1; // alpha ? gl_alpha_format : gl_solid_format;
- 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;
- }
- memcpy (scaled, data, width*height);
- }
- else
- GL_Resample8BitTexture (data, width, height, 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);
- }
- }
- extern qboolean VID_Is8bit();
- /*
- ===============
- GL_Upload8
- ===============
- */
- void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha)
- {
- static unsigned trans[640*480]; // FIXME, temporary
- int i, s;
- qboolean noalpha;
- int p;
- s = width*height;
- // 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 ; i<s ; i++)
- {
- p = data[i];
- if (p == 255)
- noalpha = false;
- trans[i] = d_8to24table[p];
- }
- if (alpha && noalpha)
- alpha = false;
- }
- else
- {
- if (s&3)
- Sys_Error ("GL_Upload8: s&3");
- for (i=0 ; i<s ; i+=4)
- {
- trans[i] = d_8to24table[data[i]];
- trans[i+1] = d_8to24table[data[i+1]];
- trans[i+2] = d_8to24table[data[i+2]];
- trans[i+3] = d_8to24table[data[i+3]];
- }
- }
- if (VID_Is8bit() && !alpha && (data!=scrap_texels[0])) {
- GL_Upload8_EXT (data, width, height, mipmap, alpha);
- return;
- }
- GL_Upload32 (trans, width, height, mipmap, alpha);
- }
- /*
- ================
- GL_LoadTexture
- ================
- */
- int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha)
- {
- int i;
- gltexture_t *glt;
- // see if the texture is allready present
- if (identifier[0])
- {
- for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
- {
- if (!strcmp (identifier, glt->identifier))
- {
- if (width != glt->width || height != glt->height)
- Sys_Error ("GL_LoadTexture: cache mismatch");
- return gltextures[i].texnum;
- }
- }
- }
- else
- glt = &gltextures[numgltextures];
- numgltextures++;
- strcpy (glt->identifier, identifier);
- glt->texnum = texture_extension_number;
- glt->width = width;
- glt->height = height;
- glt->mipmap = mipmap;
- GL_Bind(texture_extension_number );
- GL_Upload8 (data, width, height, mipmap, alpha);
- texture_extension_number++;
- return texture_extension_number-1;
- }
- /*
- ================
- GL_LoadPicTexture
- ================
- */
- int GL_LoadPicTexture (qpic_t *pic)
- {
- return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true);
- }
- /****************************************/
- static GLenum oldtarget = TEXTURE0_SGIS;
- void GL_SelectTexture (GLenum target)
- {
- if (!gl_mtexable)
- return;
- #ifndef __linux__ // no multitexture under Linux yet
- qglSelectTextureSGIS(target);
- #endif
- if (target == oldtarget)
- return;
- cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture;
- currenttexture = cnttextures[target-TEXTURE0_SGIS];
- oldtarget = target;
- }
|