gl_draw.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // draw.c -- this is the only file outside the refresh that touches the
  16. // vid buffer
  17. #include "quakedef.h"
  18. #define GL_COLOR_INDEX8_EXT 0x80E5
  19. extern unsigned char d_15to8table[65536];
  20. cvar_t gl_nobind = {"gl_nobind", "0"};
  21. cvar_t gl_max_size = {"gl_max_size", "1024"};
  22. cvar_t gl_picmip = {"gl_picmip", "0"};
  23. byte *draw_chars; // 8*8 graphic characters
  24. qpic_t *draw_disc;
  25. qpic_t *draw_backtile;
  26. int translate_texture;
  27. int char_texture;
  28. typedef struct
  29. {
  30. int texnum;
  31. float sl, tl, sh, th;
  32. } glpic_t;
  33. byte conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)];
  34. qpic_t *conback = (qpic_t *)&conback_buffer;
  35. int gl_lightmap_format = 4;
  36. int gl_solid_format = 3;
  37. int gl_alpha_format = 4;
  38. int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
  39. int gl_filter_max = GL_LINEAR;
  40. int texels;
  41. typedef struct
  42. {
  43. int texnum;
  44. char identifier[64];
  45. int width, height;
  46. qboolean mipmap;
  47. } gltexture_t;
  48. #define MAX_GLTEXTURES 1024
  49. gltexture_t gltextures[MAX_GLTEXTURES];
  50. int numgltextures;
  51. void GL_Bind (int texnum)
  52. {
  53. if (gl_nobind.value)
  54. texnum = char_texture;
  55. if (currenttexture == texnum)
  56. return;
  57. currenttexture = texnum;
  58. #ifdef _WIN32
  59. bindTexFunc (GL_TEXTURE_2D, texnum);
  60. #else
  61. glBindTexture(GL_TEXTURE_2D, texnum);
  62. #endif
  63. }
  64. /*
  65. =============================================================================
  66. scrap allocation
  67. Allocate all the little status bar obejcts into a single texture
  68. to crutch up stupid hardware / drivers
  69. =============================================================================
  70. */
  71. #define MAX_SCRAPS 2
  72. #define BLOCK_WIDTH 256
  73. #define BLOCK_HEIGHT 256
  74. int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
  75. byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4];
  76. qboolean scrap_dirty;
  77. int scrap_texnum;
  78. // returns a texture number and the position inside it
  79. int Scrap_AllocBlock (int w, int h, int *x, int *y)
  80. {
  81. int i, j;
  82. int best, best2;
  83. int bestx;
  84. int texnum;
  85. for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
  86. {
  87. best = BLOCK_HEIGHT;
  88. for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  89. {
  90. best2 = 0;
  91. for (j=0 ; j<w ; j++)
  92. {
  93. if (scrap_allocated[texnum][i+j] >= best)
  94. break;
  95. if (scrap_allocated[texnum][i+j] > best2)
  96. best2 = scrap_allocated[texnum][i+j];
  97. }
  98. if (j == w)
  99. { // this is a valid spot
  100. *x = i;
  101. *y = best = best2;
  102. }
  103. }
  104. if (best + h > BLOCK_HEIGHT)
  105. continue;
  106. for (i=0 ; i<w ; i++)
  107. scrap_allocated[texnum][*x + i] = best + h;
  108. return texnum;
  109. }
  110. Sys_Error ("Scrap_AllocBlock: full");
  111. }
  112. int scrap_uploads;
  113. void Scrap_Upload (void)
  114. {
  115. int texnum;
  116. scrap_uploads++;
  117. for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++) {
  118. GL_Bind(scrap_texnum + texnum);
  119. GL_Upload8 (scrap_texels[texnum], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
  120. }
  121. scrap_dirty = false;
  122. }
  123. //=============================================================================
  124. /* Support Routines */
  125. typedef struct cachepic_s
  126. {
  127. char name[MAX_QPATH];
  128. qpic_t pic;
  129. byte padding[32]; // for appended glpic
  130. } cachepic_t;
  131. #define MAX_CACHED_PICS 128
  132. cachepic_t menu_cachepics[MAX_CACHED_PICS];
  133. int menu_numcachepics;
  134. byte menuplyr_pixels[4096];
  135. int pic_texels;
  136. int pic_count;
  137. qpic_t *Draw_PicFromWad (char *name)
  138. {
  139. qpic_t *p;
  140. glpic_t *gl;
  141. p = W_GetLumpName (name);
  142. gl = (glpic_t *)p->data;
  143. // load little ones into the scrap
  144. if (p->width < 64 && p->height < 64)
  145. {
  146. int x, y;
  147. int i, j, k;
  148. int texnum;
  149. texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
  150. scrap_dirty = true;
  151. k = 0;
  152. for (i=0 ; i<p->height ; i++)
  153. for (j=0 ; j<p->width ; j++, k++)
  154. scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k];
  155. texnum += scrap_texnum;
  156. gl->texnum = texnum;
  157. gl->sl = (x+0.01)/(float)BLOCK_WIDTH;
  158. gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH;
  159. gl->tl = (y+0.01)/(float)BLOCK_WIDTH;
  160. gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
  161. pic_count++;
  162. pic_texels += p->width*p->height;
  163. }
  164. else
  165. {
  166. gl->texnum = GL_LoadPicTexture (p);
  167. gl->sl = 0;
  168. gl->sh = 1;
  169. gl->tl = 0;
  170. gl->th = 1;
  171. }
  172. return p;
  173. }
  174. /*
  175. ================
  176. Draw_CachePic
  177. ================
  178. */
  179. qpic_t *Draw_CachePic (char *path)
  180. {
  181. cachepic_t *pic;
  182. int i;
  183. qpic_t *dat;
  184. glpic_t *gl;
  185. for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
  186. if (!strcmp (path, pic->name))
  187. return &pic->pic;
  188. if (menu_numcachepics == MAX_CACHED_PICS)
  189. Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
  190. menu_numcachepics++;
  191. strcpy (pic->name, path);
  192. //
  193. // load the pic from disk
  194. //
  195. dat = (qpic_t *)COM_LoadTempFile (path);
  196. if (!dat)
  197. Sys_Error ("Draw_CachePic: failed to load %s", path);
  198. SwapPic (dat);
  199. // HACK HACK HACK --- we need to keep the bytes for
  200. // the translatable player picture just for the menu
  201. // configuration dialog
  202. if (!strcmp (path, "gfx/menuplyr.lmp"))
  203. memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
  204. pic->pic.width = dat->width;
  205. pic->pic.height = dat->height;
  206. gl = (glpic_t *)pic->pic.data;
  207. gl->texnum = GL_LoadPicTexture (dat);
  208. gl->sl = 0;
  209. gl->sh = 1;
  210. gl->tl = 0;
  211. gl->th = 1;
  212. return &pic->pic;
  213. }
  214. void Draw_CharToConback (int num, byte *dest)
  215. {
  216. int row, col;
  217. byte *source;
  218. int drawline;
  219. int x;
  220. row = num>>4;
  221. col = num&15;
  222. source = draw_chars + (row<<10) + (col<<3);
  223. drawline = 8;
  224. while (drawline--)
  225. {
  226. for (x=0 ; x<8 ; x++)
  227. if (source[x] != 255)
  228. dest[x] = 0x60 + source[x];
  229. source += 128;
  230. dest += 320;
  231. }
  232. }
  233. typedef struct
  234. {
  235. char *name;
  236. int minimize, maximize;
  237. } glmode_t;
  238. glmode_t modes[] = {
  239. {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
  240. {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
  241. {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
  242. {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
  243. {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
  244. {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
  245. };
  246. /*
  247. ===============
  248. Draw_TextureMode_f
  249. ===============
  250. */
  251. void Draw_TextureMode_f (void)
  252. {
  253. int i;
  254. gltexture_t *glt;
  255. if (Cmd_Argc() == 1)
  256. {
  257. for (i=0 ; i< 6 ; i++)
  258. if (gl_filter_min == modes[i].minimize)
  259. {
  260. Con_Printf ("%s\n", modes[i].name);
  261. return;
  262. }
  263. Con_Printf ("current filter is unknown???\n");
  264. return;
  265. }
  266. for (i=0 ; i< 6 ; i++)
  267. {
  268. if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
  269. break;
  270. }
  271. if (i == 6)
  272. {
  273. Con_Printf ("bad filter name\n");
  274. return;
  275. }
  276. gl_filter_min = modes[i].minimize;
  277. gl_filter_max = modes[i].maximize;
  278. // change all the existing mipmap texture objects
  279. for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  280. {
  281. if (glt->mipmap)
  282. {
  283. GL_Bind (glt->texnum);
  284. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  285. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  286. }
  287. }
  288. }
  289. /*
  290. ===============
  291. Draw_Init
  292. ===============
  293. */
  294. void Draw_Init (void)
  295. {
  296. int i;
  297. qpic_t *cb;
  298. byte *dest, *src;
  299. int x, y;
  300. char ver[40];
  301. glpic_t *gl;
  302. int start;
  303. byte *ncdata;
  304. int f, fstep;
  305. Cvar_RegisterVariable (&gl_nobind);
  306. Cvar_RegisterVariable (&gl_max_size);
  307. Cvar_RegisterVariable (&gl_picmip);
  308. // 3dfx can only handle 256 wide textures
  309. if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) ||
  310. strstr((char *)gl_renderer, "Glide"))
  311. Cvar_Set ("gl_max_size", "256");
  312. Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
  313. // load the console background and the charset
  314. // by hand, because we need to write the version
  315. // string into the background before turning
  316. // it into a texture
  317. draw_chars = W_GetLumpName ("conchars");
  318. for (i=0 ; i<256*64 ; i++)
  319. if (draw_chars[i] == 0)
  320. draw_chars[i] = 255; // proper transparent color
  321. // now turn them into textures
  322. char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true);
  323. start = Hunk_LowMark();
  324. cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp");
  325. if (!cb)
  326. Sys_Error ("Couldn't load gfx/conback.lmp");
  327. SwapPic (cb);
  328. // hack the version number directly into the pic
  329. #if defined(__linux__)
  330. sprintf (ver, "(Linux %2.2f, gl %4.2f) %4.2f", (float)LINUX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION);
  331. #else
  332. sprintf (ver, "(gl %4.2f) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION);
  333. #endif
  334. dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
  335. y = strlen(ver);
  336. for (x=0 ; x<y ; x++)
  337. Draw_CharToConback (ver[x], dest+(x<<3));
  338. #if 0
  339. conback->width = vid.conwidth;
  340. conback->height = vid.conheight;
  341. // scale console to vid size
  342. dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
  343. for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
  344. {
  345. src = cb->data + cb->width * (y*cb->height/vid.conheight);
  346. if (vid.conwidth == cb->width)
  347. memcpy (dest, src, vid.conwidth);
  348. else
  349. {
  350. f = 0;
  351. fstep = cb->width*0x10000/vid.conwidth;
  352. for (x=0 ; x<vid.conwidth ; x+=4)
  353. {
  354. dest[x] = src[f>>16];
  355. f += fstep;
  356. dest[x+1] = src[f>>16];
  357. f += fstep;
  358. dest[x+2] = src[f>>16];
  359. f += fstep;
  360. dest[x+3] = src[f>>16];
  361. f += fstep;
  362. }
  363. }
  364. }
  365. #else
  366. conback->width = cb->width;
  367. conback->height = cb->height;
  368. ncdata = cb->data;
  369. #endif
  370. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  371. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  372. gl = (glpic_t *)conback->data;
  373. gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false);
  374. gl->sl = 0;
  375. gl->sh = 1;
  376. gl->tl = 0;
  377. gl->th = 1;
  378. conback->width = vid.width;
  379. conback->height = vid.height;
  380. // free loaded console
  381. Hunk_FreeToLowMark(start);
  382. // save a texture slot for translated picture
  383. translate_texture = texture_extension_number++;
  384. // save slots for scraps
  385. scrap_texnum = texture_extension_number;
  386. texture_extension_number += MAX_SCRAPS;
  387. //
  388. // get the other pics we need
  389. //
  390. draw_disc = Draw_PicFromWad ("disc");
  391. draw_backtile = Draw_PicFromWad ("backtile");
  392. }
  393. /*
  394. ================
  395. Draw_Character
  396. Draws one 8*8 graphics character with 0 being transparent.
  397. It can be clipped to the top of the screen to allow the console to be
  398. smoothly scrolled off.
  399. ================
  400. */
  401. void Draw_Character (int x, int y, int num)
  402. {
  403. byte *dest;
  404. byte *source;
  405. unsigned short *pusdest;
  406. int drawline;
  407. int row, col;
  408. float frow, fcol, size;
  409. if (num == 32)
  410. return; // space
  411. num &= 255;
  412. if (y <= -8)
  413. return; // totally off screen
  414. row = num>>4;
  415. col = num&15;
  416. frow = row*0.0625;
  417. fcol = col*0.0625;
  418. size = 0.0625;
  419. GL_Bind (char_texture);
  420. glBegin (GL_QUADS);
  421. glTexCoord2f (fcol, frow);
  422. glVertex2f (x, y);
  423. glTexCoord2f (fcol + size, frow);
  424. glVertex2f (x+8, y);
  425. glTexCoord2f (fcol + size, frow + size);
  426. glVertex2f (x+8, y+8);
  427. glTexCoord2f (fcol, frow + size);
  428. glVertex2f (x, y+8);
  429. glEnd ();
  430. }
  431. /*
  432. ================
  433. Draw_String
  434. ================
  435. */
  436. void Draw_String (int x, int y, char *str)
  437. {
  438. while (*str)
  439. {
  440. Draw_Character (x, y, *str);
  441. str++;
  442. x += 8;
  443. }
  444. }
  445. /*
  446. ================
  447. Draw_DebugChar
  448. Draws a single character directly to the upper right corner of the screen.
  449. This is for debugging lockups by drawing different chars in different parts
  450. of the code.
  451. ================
  452. */
  453. void Draw_DebugChar (char num)
  454. {
  455. }
  456. /*
  457. =============
  458. Draw_AlphaPic
  459. =============
  460. */
  461. void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
  462. {
  463. byte *dest, *source;
  464. unsigned short *pusdest;
  465. int v, u;
  466. glpic_t *gl;
  467. if (scrap_dirty)
  468. Scrap_Upload ();
  469. gl = (glpic_t *)pic->data;
  470. glDisable(GL_ALPHA_TEST);
  471. glEnable (GL_BLEND);
  472. // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  473. // glCullFace(GL_FRONT);
  474. glColor4f (1,1,1,alpha);
  475. GL_Bind (gl->texnum);
  476. glBegin (GL_QUADS);
  477. glTexCoord2f (gl->sl, gl->tl);
  478. glVertex2f (x, y);
  479. glTexCoord2f (gl->sh, gl->tl);
  480. glVertex2f (x+pic->width, y);
  481. glTexCoord2f (gl->sh, gl->th);
  482. glVertex2f (x+pic->width, y+pic->height);
  483. glTexCoord2f (gl->sl, gl->th);
  484. glVertex2f (x, y+pic->height);
  485. glEnd ();
  486. glColor4f (1,1,1,1);
  487. glEnable(GL_ALPHA_TEST);
  488. glDisable (GL_BLEND);
  489. }
  490. /*
  491. =============
  492. Draw_Pic
  493. =============
  494. */
  495. void Draw_Pic (int x, int y, qpic_t *pic)
  496. {
  497. byte *dest, *source;
  498. unsigned short *pusdest;
  499. int v, u;
  500. glpic_t *gl;
  501. if (scrap_dirty)
  502. Scrap_Upload ();
  503. gl = (glpic_t *)pic->data;
  504. glColor4f (1,1,1,1);
  505. GL_Bind (gl->texnum);
  506. glBegin (GL_QUADS);
  507. glTexCoord2f (gl->sl, gl->tl);
  508. glVertex2f (x, y);
  509. glTexCoord2f (gl->sh, gl->tl);
  510. glVertex2f (x+pic->width, y);
  511. glTexCoord2f (gl->sh, gl->th);
  512. glVertex2f (x+pic->width, y+pic->height);
  513. glTexCoord2f (gl->sl, gl->th);
  514. glVertex2f (x, y+pic->height);
  515. glEnd ();
  516. }
  517. /*
  518. =============
  519. Draw_TransPic
  520. =============
  521. */
  522. void Draw_TransPic (int x, int y, qpic_t *pic)
  523. {
  524. byte *dest, *source, tbyte;
  525. unsigned short *pusdest;
  526. int v, u;
  527. if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  528. (unsigned)(y + pic->height) > vid.height)
  529. {
  530. Sys_Error ("Draw_TransPic: bad coordinates");
  531. }
  532. Draw_Pic (x, y, pic);
  533. }
  534. /*
  535. =============
  536. Draw_TransPicTranslate
  537. Only used for the player color selection menu
  538. =============
  539. */
  540. void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
  541. {
  542. int v, u, c;
  543. unsigned trans[64*64], *dest;
  544. byte *src;
  545. int p;
  546. GL_Bind (translate_texture);
  547. c = pic->width * pic->height;
  548. dest = trans;
  549. for (v=0 ; v<64 ; v++, dest += 64)
  550. {
  551. src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width];
  552. for (u=0 ; u<64 ; u++)
  553. {
  554. p = src[(u*pic->width)>>6];
  555. if (p == 255)
  556. dest[u] = p;
  557. else
  558. dest[u] = d_8to24table[translation[p]];
  559. }
  560. }
  561. glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  562. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  563. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  564. glColor3f (1,1,1);
  565. glBegin (GL_QUADS);
  566. glTexCoord2f (0, 0);
  567. glVertex2f (x, y);
  568. glTexCoord2f (1, 0);
  569. glVertex2f (x+pic->width, y);
  570. glTexCoord2f (1, 1);
  571. glVertex2f (x+pic->width, y+pic->height);
  572. glTexCoord2f (0, 1);
  573. glVertex2f (x, y+pic->height);
  574. glEnd ();
  575. }
  576. /*
  577. ================
  578. Draw_ConsoleBackground
  579. ================
  580. */
  581. void Draw_ConsoleBackground (int lines)
  582. {
  583. int y = (vid.height * 3) >> 2;
  584. if (lines > y)
  585. Draw_Pic(0, lines - vid.height, conback);
  586. else
  587. Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
  588. }
  589. /*
  590. =============
  591. Draw_TileClear
  592. This repeats a 64*64 tile graphic to fill the screen around a sized down
  593. refresh window.
  594. =============
  595. */
  596. void Draw_TileClear (int x, int y, int w, int h)
  597. {
  598. glColor3f (1,1,1);
  599. GL_Bind (*(int *)draw_backtile->data);
  600. glBegin (GL_QUADS);
  601. glTexCoord2f (x/64.0, y/64.0);
  602. glVertex2f (x, y);
  603. glTexCoord2f ( (x+w)/64.0, y/64.0);
  604. glVertex2f (x+w, y);
  605. glTexCoord2f ( (x+w)/64.0, (y+h)/64.0);
  606. glVertex2f (x+w, y+h);
  607. glTexCoord2f ( x/64.0, (y+h)/64.0 );
  608. glVertex2f (x, y+h);
  609. glEnd ();
  610. }
  611. /*
  612. =============
  613. Draw_Fill
  614. Fills a box of pixels with a single color
  615. =============
  616. */
  617. void Draw_Fill (int x, int y, int w, int h, int c)
  618. {
  619. glDisable (GL_TEXTURE_2D);
  620. glColor3f (host_basepal[c*3]/255.0,
  621. host_basepal[c*3+1]/255.0,
  622. host_basepal[c*3+2]/255.0);
  623. glBegin (GL_QUADS);
  624. glVertex2f (x,y);
  625. glVertex2f (x+w, y);
  626. glVertex2f (x+w, y+h);
  627. glVertex2f (x, y+h);
  628. glEnd ();
  629. glColor3f (1,1,1);
  630. glEnable (GL_TEXTURE_2D);
  631. }
  632. //=============================================================================
  633. /*
  634. ================
  635. Draw_FadeScreen
  636. ================
  637. */
  638. void Draw_FadeScreen (void)
  639. {
  640. glEnable (GL_BLEND);
  641. glDisable (GL_TEXTURE_2D);
  642. glColor4f (0, 0, 0, 0.8);
  643. glBegin (GL_QUADS);
  644. glVertex2f (0,0);
  645. glVertex2f (vid.width, 0);
  646. glVertex2f (vid.width, vid.height);
  647. glVertex2f (0, vid.height);
  648. glEnd ();
  649. glColor4f (1,1,1,1);
  650. glEnable (GL_TEXTURE_2D);
  651. glDisable (GL_BLEND);
  652. Sbar_Changed();
  653. }
  654. //=============================================================================
  655. /*
  656. ================
  657. Draw_BeginDisc
  658. Draws the little blue disc in the corner of the screen.
  659. Call before beginning any disc IO.
  660. ================
  661. */
  662. void Draw_BeginDisc (void)
  663. {
  664. if (!draw_disc)
  665. return;
  666. glDrawBuffer (GL_FRONT);
  667. Draw_Pic (vid.width - 24, 0, draw_disc);
  668. glDrawBuffer (GL_BACK);
  669. }
  670. /*
  671. ================
  672. Draw_EndDisc
  673. Erases the disc icon.
  674. Call after completing any disc IO
  675. ================
  676. */
  677. void Draw_EndDisc (void)
  678. {
  679. }
  680. /*
  681. ================
  682. GL_Set2D
  683. Setup as if the screen was 320*200
  684. ================
  685. */
  686. void GL_Set2D (void)
  687. {
  688. glViewport (glx, gly, glwidth, glheight);
  689. glMatrixMode(GL_PROJECTION);
  690. glLoadIdentity ();
  691. glOrtho (0, vid.width, vid.height, 0, -99999, 99999);
  692. glMatrixMode(GL_MODELVIEW);
  693. glLoadIdentity ();
  694. glDisable (GL_DEPTH_TEST);
  695. glDisable (GL_CULL_FACE);
  696. glDisable (GL_BLEND);
  697. glEnable (GL_ALPHA_TEST);
  698. // glDisable (GL_ALPHA_TEST);
  699. glColor4f (1,1,1,1);
  700. }
  701. //====================================================================
  702. /*
  703. ================
  704. GL_FindTexture
  705. ================
  706. */
  707. int GL_FindTexture (char *identifier)
  708. {
  709. int i;
  710. gltexture_t *glt;
  711. for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  712. {
  713. if (!strcmp (identifier, glt->identifier))
  714. return gltextures[i].texnum;
  715. }
  716. return -1;
  717. }
  718. /*
  719. ================
  720. GL_ResampleTexture
  721. ================
  722. */
  723. void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight)
  724. {
  725. int i, j;
  726. unsigned *inrow;
  727. unsigned frac, fracstep;
  728. fracstep = inwidth*0x10000/outwidth;
  729. for (i=0 ; i<outheight ; i++, out += outwidth)
  730. {
  731. inrow = in + inwidth*(i*inheight/outheight);
  732. frac = fracstep >> 1;
  733. for (j=0 ; j<outwidth ; j+=4)
  734. {
  735. out[j] = inrow[frac>>16];
  736. frac += fracstep;
  737. out[j+1] = inrow[frac>>16];
  738. frac += fracstep;
  739. out[j+2] = inrow[frac>>16];
  740. frac += fracstep;
  741. out[j+3] = inrow[frac>>16];
  742. frac += fracstep;
  743. }
  744. }
  745. }
  746. /*
  747. ================
  748. GL_Resample8BitTexture -- JACK
  749. ================
  750. */
  751. void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight)
  752. {
  753. int i, j;
  754. unsigned char *inrow;
  755. unsigned frac, fracstep;
  756. fracstep = inwidth*0x10000/outwidth;
  757. for (i=0 ; i<outheight ; i++, out += outwidth)
  758. {
  759. inrow = in + inwidth*(i*inheight/outheight);
  760. frac = fracstep >> 1;
  761. for (j=0 ; j<outwidth ; j+=4)
  762. {
  763. out[j] = inrow[frac>>16];
  764. frac += fracstep;
  765. out[j+1] = inrow[frac>>16];
  766. frac += fracstep;
  767. out[j+2] = inrow[frac>>16];
  768. frac += fracstep;
  769. out[j+3] = inrow[frac>>16];
  770. frac += fracstep;
  771. }
  772. }
  773. }
  774. /*
  775. ================
  776. GL_MipMap
  777. Operates in place, quartering the size of the texture
  778. ================
  779. */
  780. void GL_MipMap (byte *in, int width, int height)
  781. {
  782. int i, j;
  783. byte *out;
  784. width <<=2;
  785. height >>= 1;
  786. out = in;
  787. for (i=0 ; i<height ; i++, in+=width)
  788. {
  789. for (j=0 ; j<width ; j+=8, out+=4, in+=8)
  790. {
  791. out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
  792. out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
  793. out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
  794. out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
  795. }
  796. }
  797. }
  798. /*
  799. ================
  800. GL_MipMap8Bit
  801. Mipping for 8 bit textures
  802. ================
  803. */
  804. void GL_MipMap8Bit (byte *in, int width, int height)
  805. {
  806. int i, j;
  807. unsigned short r,g,b;
  808. byte *out, *at1, *at2, *at3, *at4;
  809. // width <<=2;
  810. height >>= 1;
  811. out = in;
  812. for (i=0 ; i<height ; i++, in+=width)
  813. {
  814. for (j=0 ; j<width ; j+=2, out+=1, in+=2)
  815. {
  816. at1 = (byte *) (d_8to24table + in[0]);
  817. at2 = (byte *) (d_8to24table + in[1]);
  818. at3 = (byte *) (d_8to24table + in[width+0]);
  819. at4 = (byte *) (d_8to24table + in[width+1]);
  820. r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5;
  821. g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5;
  822. b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5;
  823. out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
  824. }
  825. }
  826. }
  827. /*
  828. ===============
  829. GL_Upload32
  830. ===============
  831. */
  832. void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha)
  833. {
  834. int samples;
  835. static unsigned scaled[1024*512]; // [512*256];
  836. int scaled_width, scaled_height;
  837. for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  838. ;
  839. for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  840. ;
  841. scaled_width >>= (int)gl_picmip.value;
  842. scaled_height >>= (int)gl_picmip.value;
  843. if (scaled_width > gl_max_size.value)
  844. scaled_width = gl_max_size.value;
  845. if (scaled_height > gl_max_size.value)
  846. scaled_height = gl_max_size.value;
  847. if (scaled_width * scaled_height > sizeof(scaled)/4)
  848. Sys_Error ("GL_LoadTexture: too big");
  849. samples = alpha ? gl_alpha_format : gl_solid_format;
  850. #if 0
  851. if (mipmap)
  852. gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  853. else if (scaled_width == width && scaled_height == height)
  854. glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  855. else
  856. {
  857. gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
  858. scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
  859. glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  860. }
  861. #else
  862. texels += scaled_width * scaled_height;
  863. if (scaled_width == width && scaled_height == height)
  864. {
  865. if (!mipmap)
  866. {
  867. glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  868. goto done;
  869. }
  870. memcpy (scaled, data, width*height*4);
  871. }
  872. else
  873. GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
  874. glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  875. if (mipmap)
  876. {
  877. int miplevel;
  878. miplevel = 0;
  879. while (scaled_width > 1 || scaled_height > 1)
  880. {
  881. GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
  882. scaled_width >>= 1;
  883. scaled_height >>= 1;
  884. if (scaled_width < 1)
  885. scaled_width = 1;
  886. if (scaled_height < 1)
  887. scaled_height = 1;
  888. miplevel++;
  889. glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  890. }
  891. }
  892. done: ;
  893. #endif
  894. if (mipmap)
  895. {
  896. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  897. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  898. }
  899. else
  900. {
  901. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  902. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  903. }
  904. }
  905. void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha)
  906. {
  907. int i, s;
  908. qboolean noalpha;
  909. int p;
  910. static unsigned j;
  911. int samples;
  912. static unsigned char scaled[1024*512]; // [512*256];
  913. int scaled_width, scaled_height;
  914. s = width*height;
  915. // if there are no transparent pixels, make it a 3 component
  916. // texture even if it was specified as otherwise
  917. if (alpha)
  918. {
  919. noalpha = true;
  920. for (i=0 ; i<s ; i++)
  921. {
  922. if (data[i] == 255)
  923. noalpha = false;
  924. }
  925. if (alpha && noalpha)
  926. alpha = false;
  927. }
  928. for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  929. ;
  930. for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  931. ;
  932. scaled_width >>= (int)gl_picmip.value;
  933. scaled_height >>= (int)gl_picmip.value;
  934. if (scaled_width > gl_max_size.value)
  935. scaled_width = gl_max_size.value;
  936. if (scaled_height > gl_max_size.value)
  937. scaled_height = gl_max_size.value;
  938. if (scaled_width * scaled_height > sizeof(scaled))
  939. Sys_Error ("GL_LoadTexture: too big");
  940. samples = 1; // alpha ? gl_alpha_format : gl_solid_format;
  941. texels += scaled_width * scaled_height;
  942. if (scaled_width == width && scaled_height == height)
  943. {
  944. if (!mipmap)
  945. {
  946. glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
  947. goto done;
  948. }
  949. memcpy (scaled, data, width*height);
  950. }
  951. else
  952. GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
  953. glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  954. if (mipmap)
  955. {
  956. int miplevel;
  957. miplevel = 0;
  958. while (scaled_width > 1 || scaled_height > 1)
  959. {
  960. GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
  961. scaled_width >>= 1;
  962. scaled_height >>= 1;
  963. if (scaled_width < 1)
  964. scaled_width = 1;
  965. if (scaled_height < 1)
  966. scaled_height = 1;
  967. miplevel++;
  968. glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  969. }
  970. }
  971. done: ;
  972. if (mipmap)
  973. {
  974. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  975. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  976. }
  977. else
  978. {
  979. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  980. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  981. }
  982. }
  983. /*
  984. ===============
  985. GL_Upload8
  986. ===============
  987. */
  988. void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha)
  989. {
  990. static unsigned trans[640*480]; // FIXME, temporary
  991. int i, s;
  992. qboolean noalpha;
  993. int p;
  994. s = width*height;
  995. // if there are no transparent pixels, make it a 3 component
  996. // texture even if it was specified as otherwise
  997. if (alpha)
  998. {
  999. noalpha = true;
  1000. for (i=0 ; i<s ; i++)
  1001. {
  1002. p = data[i];
  1003. if (p == 255)
  1004. noalpha = false;
  1005. trans[i] = d_8to24table[p];
  1006. }
  1007. if (alpha && noalpha)
  1008. alpha = false;
  1009. }
  1010. else
  1011. {
  1012. if (s&3)
  1013. Sys_Error ("GL_Upload8: s&3");
  1014. for (i=0 ; i<s ; i+=4)
  1015. {
  1016. trans[i] = d_8to24table[data[i]];
  1017. trans[i+1] = d_8to24table[data[i+1]];
  1018. trans[i+2] = d_8to24table[data[i+2]];
  1019. trans[i+3] = d_8to24table[data[i+3]];
  1020. }
  1021. }
  1022. if (VID_Is8bit() && !alpha && (data!=scrap_texels[0])) {
  1023. GL_Upload8_EXT (data, width, height, mipmap, alpha);
  1024. return;
  1025. }
  1026. GL_Upload32 (trans, width, height, mipmap, alpha);
  1027. }
  1028. /*
  1029. ================
  1030. GL_LoadTexture
  1031. ================
  1032. */
  1033. int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha)
  1034. {
  1035. qboolean noalpha;
  1036. int i, p, s;
  1037. gltexture_t *glt;
  1038. // see if the texture is allready present
  1039. if (identifier[0])
  1040. {
  1041. for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  1042. {
  1043. if (!strcmp (identifier, glt->identifier))
  1044. {
  1045. if (width != glt->width || height != glt->height)
  1046. Sys_Error ("GL_LoadTexture: cache mismatch");
  1047. return gltextures[i].texnum;
  1048. }
  1049. }
  1050. }
  1051. else {
  1052. glt = &gltextures[numgltextures];
  1053. numgltextures++;
  1054. }
  1055. strcpy (glt->identifier, identifier);
  1056. glt->texnum = texture_extension_number;
  1057. glt->width = width;
  1058. glt->height = height;
  1059. glt->mipmap = mipmap;
  1060. GL_Bind(texture_extension_number );
  1061. GL_Upload8 (data, width, height, mipmap, alpha);
  1062. texture_extension_number++;
  1063. return texture_extension_number-1;
  1064. }
  1065. /*
  1066. ================
  1067. GL_LoadPicTexture
  1068. ================
  1069. */
  1070. int GL_LoadPicTexture (qpic_t *pic)
  1071. {
  1072. return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true);
  1073. }
  1074. /****************************************/
  1075. static GLenum oldtarget = TEXTURE0_SGIS;
  1076. void GL_SelectTexture (GLenum target)
  1077. {
  1078. if (!gl_mtexable)
  1079. return;
  1080. qglSelectTextureSGIS(target);
  1081. if (target == oldtarget)
  1082. return;
  1083. cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture;
  1084. currenttexture = cnttextures[target-TEXTURE0_SGIS];
  1085. oldtarget = target;
  1086. }