• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 // r_misc.c
21 
22 #include "quakedef.h"
23 
24 
25 
26 /*
27 ==================
28 R_InitTextures
29 ==================
30 */
R_InitTextures(void)31 void	R_InitTextures (void)
32 {
33   int		x,y, m;
34   byte	*dest;
35 
36 // create a simple checkerboard texture for the default
37   r_notexture_mip = (texture_t*) Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture");
38 
39   r_notexture_mip->width = r_notexture_mip->height = 16;
40   r_notexture_mip->offsets[0] = sizeof(texture_t);
41   r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16;
42   r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8;
43   r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4;
44 
45   for (m=0 ; m<4 ; m++)
46   {
47     dest = (byte *)r_notexture_mip + r_notexture_mip->offsets[m];
48     for (y=0 ; y< (16>>m) ; y++)
49       for (x=0 ; x< (16>>m) ; x++)
50       {
51         if (  (y< (8>>m) ) ^ (x< (8>>m) ) )
52           *dest++ = 0;
53         else
54           *dest++ = 0xff;
55       }
56   }
57 }
58 
59 byte	dottexture[8][8] =
60 {
61   {0,1,1,0,0,0,0,0},
62   {1,1,1,1,0,0,0,0},
63   {1,1,1,1,0,0,0,0},
64   {0,1,1,0,0,0,0,0},
65   {0,0,0,0,0,0,0,0},
66   {0,0,0,0,0,0,0,0},
67   {0,0,0,0,0,0,0,0},
68   {0,0,0,0,0,0,0,0},
69 };
70 // Initialize particle texture, can be called multiple times.
R_InitParticleTexture2(void)71 void R_InitParticleTexture2 (void)
72 {
73   int		x,y;
74   byte	data[8][8][4];
75 
76   //
77   // particle texture
78   //
79     GL_Bind(particletexture);
80 
81   for (x=0 ; x<8 ; x++)
82   {
83     for (y=0 ; y<8 ; y++)
84     {
85       data[y][x][0] = 255;
86       data[y][x][1] = 255;
87       data[y][x][2] = 255;
88       data[y][x][3] = dottexture[x][y]*255;
89     }
90   }
91   glTexImage2DHelper (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
92 
93   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
94 
95   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
96   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
97 }
98 
R_InitParticleTexture(void)99 void R_InitParticleTexture (void)
100 {
101   particletexture = texture_extension_number++;
102   R_InitParticleTexture2();
103 }
104 
105 /*
106 ===============
107 R_Envmap_f
108 
109 Grab six views for environment mapping tests
110 ===============
111 */
R_Envmap_f(void)112 void R_Envmap_f (void)
113 {
114 #ifdef USE_OPENGLES
115   // Not implemented
116 #else
117   byte	buffer[256*256*4];
118   char	name[1024];
119 
120   glDrawBuffer  (GL_FRONT);
121   glReadBuffer  (GL_FRONT);
122   envmap = true;
123 
124   r_refdef.vrect.x = 0;
125   r_refdef.vrect.y = 0;
126   r_refdef.vrect.width = 256;
127   r_refdef.vrect.height = 256;
128 
129   r_refdef.viewangles[0] = 0;
130   r_refdef.viewangles[1] = 0;
131   r_refdef.viewangles[2] = 0;
132   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
133   R_RenderView ();
134   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
135   COM_WriteFile ("env0.rgb", buffer, sizeof(buffer));
136 
137   r_refdef.viewangles[1] = 90;
138   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
139   R_RenderView ();
140   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
141   COM_WriteFile ("env1.rgb", buffer, sizeof(buffer));
142 
143   r_refdef.viewangles[1] = 180;
144   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
145   R_RenderView ();
146   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
147   COM_WriteFile ("env2.rgb", buffer, sizeof(buffer));
148 
149   r_refdef.viewangles[1] = 270;
150   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
151   R_RenderView ();
152   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
153   COM_WriteFile ("env3.rgb", buffer, sizeof(buffer));
154 
155   r_refdef.viewangles[0] = -90;
156   r_refdef.viewangles[1] = 0;
157   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
158   R_RenderView ();
159   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
160   COM_WriteFile ("env4.rgb", buffer, sizeof(buffer));
161 
162   r_refdef.viewangles[0] = 90;
163   r_refdef.viewangles[1] = 0;
164   GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
165   R_RenderView ();
166   glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
167   COM_WriteFile ("env5.rgb", buffer, sizeof(buffer));
168 
169   envmap = false;
170   glDrawBuffer  (GL_BACK);
171   glReadBuffer  (GL_BACK);
172   GL_EndRendering ();
173 #endif
174 }
175 
176 /*
177 ===============
178 R_Init
179 ===============
180 */
R_Init(void)181 void R_Init (void)
182 {
183   extern byte *hunk_base;
184   extern cvar_t gl_finish;
185 
186   Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
187   Cmd_AddCommand ("envmap", R_Envmap_f);
188   Cmd_AddCommand ("pointfile", R_ReadPointFile_f);
189 
190   Cvar_RegisterVariable (&r_norefresh);
191   Cvar_RegisterVariable (&r_lightmap);
192   Cvar_RegisterVariable (&r_fullbright);
193   Cvar_RegisterVariable (&r_drawentities);
194   Cvar_RegisterVariable (&r_drawviewmodel);
195   Cvar_RegisterVariable (&r_shadows);
196   Cvar_RegisterVariable (&r_mirroralpha);
197   Cvar_RegisterVariable (&r_wateralpha);
198   Cvar_RegisterVariable (&r_dynamic);
199   Cvar_RegisterVariable (&r_novis);
200   Cvar_RegisterVariable (&r_speeds);
201 
202   Cvar_RegisterVariable (&gl_finish);
203   Cvar_RegisterVariable (&gl_clear);
204   Cvar_RegisterVariable (&gl_texsort);
205 
206    if (gl_mtexable)
207     Cvar_SetValue ("gl_texsort", 0.0);
208 
209   Cvar_RegisterVariable (&gl_cull);
210   Cvar_RegisterVariable (&gl_smoothmodels);
211   Cvar_RegisterVariable (&gl_affinemodels);
212   Cvar_RegisterVariable (&gl_polyblend);
213   Cvar_RegisterVariable (&gl_flashblend);
214   Cvar_RegisterVariable (&gl_playermip);
215   Cvar_RegisterVariable (&gl_nocolors);
216 
217   Cvar_RegisterVariable (&gl_keeptjunctions);
218   Cvar_RegisterVariable (&gl_reporttjunctions);
219 
220   Cvar_RegisterVariable (&gl_doubleeyes);
221 
222   R_InitParticles ();
223   R_InitParticleTexture ();
224 
225 #ifdef GLTEST
226   Test_Init ();
227 #endif
228 
229   playertextures = texture_extension_number;
230   texture_extension_number += 16;
231 }
232 
233 /*
234 ===============
235 R_TranslatePlayerSkin
236 
237 Translates a skin texture by the per-player color lookup
238 ===============
239 */
R_TranslatePlayerSkin(int playernum)240 void R_TranslatePlayerSkin (int playernum)
241 {
242   int		top, bottom;
243   byte	translate[256];
244   unsigned	translate32[256];
245   int		i, j, s;
246   model_t	*model;
247   aliashdr_t *paliashdr;
248   byte	*original;
249   unsigned*	pixels;
250   unsigned    *out;
251   unsigned	scaled_width, scaled_height;
252   int			inwidth, inheight;
253   byte		*inrow;
254   unsigned	frac, fracstep;
255   extern	byte		**player_8bit_texels_tbl;
256 
257   GL_DisableMultitexture();
258 
259   top = cl.scores[playernum].colors & 0xf0;
260   bottom = (cl.scores[playernum].colors &15)<<4;
261 
262   for (i=0 ; i<256 ; i++)
263     translate[i] = i;
264 
265   for (i=0 ; i<16 ; i++)
266   {
267     if (top < 128)	// the artists made some backwards ranges.  sigh.
268       translate[TOP_RANGE+i] = top+i;
269     else
270       translate[TOP_RANGE+i] = top+15-i;
271 
272     if (bottom < 128)
273       translate[BOTTOM_RANGE+i] = bottom+i;
274     else
275       translate[BOTTOM_RANGE+i] = bottom+15-i;
276   }
277 
278   //
279   // locate the original skin pixels
280   //
281   currententity = &cl_entities[1+playernum];
282   model = currententity->model;
283   if (!model)
284     return;		// player doesn't have a model yet
285   if (model->type != mod_alias)
286     return; // only translate skins on alias models
287 
288   paliashdr = (aliashdr_t *)Mod_Extradata (model);
289   s = paliashdr->skinwidth * paliashdr->skinheight;
290   if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) {
291     Con_Printf("(%d): Invalid player skin #%d\n", playernum, currententity->skinnum);
292     original = (byte *)paliashdr + paliashdr->texels[0];
293   } else
294     original = (byte *)paliashdr + paliashdr->texels[currententity->skinnum];
295   if (s & 3)
296     Sys_Error ("R_TranslateSkin: s&3");
297 
298   inwidth = paliashdr->skinwidth;
299   inheight = paliashdr->skinheight;
300 
301   // because this happens during gameplay, do it fast
302   // instead of sending it through gl_upload 8
303     GL_Bind(playertextures + playernum);
304 
305 #if 0
306   byte	translated[320*200];
307 
308   for (i=0 ; i<s ; i+=4)
309   {
310     translated[i] = translate[original[i]];
311     translated[i+1] = translate[original[i+1]];
312     translated[i+2] = translate[original[i+2]];
313     translated[i+3] = translate[original[i+3]];
314   }
315 
316 
317   // don't mipmap these, because it takes too long
318   GL_Upload8 (translated, paliashdr->skinwidth, paliashdr->skinheight, false, false, true);
319 #else
320   scaled_width = (unsigned int) (gl_max_size.value < 512 ? gl_max_size.value : 512);
321   scaled_height = (unsigned int) (gl_max_size.value < 256 ? gl_max_size.value : 256);
322 
323   // allow users to crunch sizes down even more if they want
324   scaled_width >>= (int)gl_playermip.value;
325   scaled_height >>= (int)gl_playermip.value;
326 
327 #define PIXEL_COUNT (512*256)
328 #define PIXELS_SIZE (PIXEL_COUNT * sizeof(unsigned))
329 
330   pixels = (unsigned*) malloc(PIXELS_SIZE);
331   if(!pixels)
332   {
333     Sys_Error("Out of memory.");
334   }
335 
336   if (VID_Is8bit()) { // 8bit texture upload
337     byte *out2;
338 
339     out2 = (byte *)pixels;
340     memset(pixels, 0, PIXELS_SIZE);
341     fracstep = inwidth*0x10000/scaled_width;
342     for (i=0 ; i< (int) scaled_height ; i++, out2 += scaled_width)
343     {
344       inrow = original + inwidth*(i*inheight/scaled_height);
345       frac = fracstep >> 1;
346       for (j=0 ; j< (int) scaled_width ; j+=4)
347       {
348         out2[j] = translate[inrow[frac>>16]];
349         frac += fracstep;
350         out2[j+1] = translate[inrow[frac>>16]];
351         frac += fracstep;
352         out2[j+2] = translate[inrow[frac>>16]];
353         frac += fracstep;
354         out2[j+3] = translate[inrow[frac>>16]];
355         frac += fracstep;
356       }
357     }
358 
359     GL_Upload8_EXT ((byte *)pixels, scaled_width, scaled_height, false, false);
360   }
361   else
362   {
363 
364     for (i=0 ; i<256 ; i++)
365       translate32[i] = d_8to24table[translate[i]];
366 
367     out = pixels;
368     fracstep = inwidth*0x10000/scaled_width;
369     for (i=0 ; i< (int) scaled_height ; i++, out += scaled_width)
370     {
371       inrow = original + inwidth*(i*inheight/scaled_height);
372       frac = fracstep >> 1;
373       for (j=0 ; j< (int) scaled_width ; j+=4)
374       {
375         out[j] = translate32[inrow[frac>>16]];
376         frac += fracstep;
377         out[j+1] = translate32[inrow[frac>>16]];
378         frac += fracstep;
379         out[j+2] = translate32[inrow[frac>>16]];
380         frac += fracstep;
381         out[j+3] = translate32[inrow[frac>>16]];
382         frac += fracstep;
383       }
384     }
385     glTexImage2DHelper (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
386 
387     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
388     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
389     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
390   }
391 #endif
392   free(pixels);
393 }
394 
395 
396 /*
397 ===============
398 R_NewMap
399 ===============
400 */
R_NewMap(void)401 void R_NewMap (void)
402 {
403   int		i;
404 
405   for (i=0 ; i<256 ; i++)
406     d_lightstylevalue[i] = 264;		// normal light value
407 
408   memset (&r_worldentity, 0, sizeof(r_worldentity));
409   r_worldentity.model = cl.worldmodel;
410 
411 // clear out efrags in case the level hasn't been reloaded
412 // FIXME: is this one short?
413   for (i=0 ; i<cl.worldmodel->numleafs ; i++)
414     cl.worldmodel->leafs[i].efrags = NULL;
415 
416   r_viewleaf = NULL;
417   R_ClearParticles ();
418 
419   GL_BuildLightmaps ();
420 
421   // identify sky texture
422   skytexturenum = -1;
423   mirrortexturenum = -1;
424   for (i=0 ; i<cl.worldmodel->numtextures ; i++)
425   {
426     if (!cl.worldmodel->textures[i])
427       continue;
428     if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) )
429       skytexturenum = i;
430     if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) )
431       mirrortexturenum = i;
432      cl.worldmodel->textures[i]->texturechain = NULL;
433   }
434 #ifdef QUAKE2
435   R_LoadSkys ();
436 #endif
437 }
438 
439 
440 /*
441 ====================
442 R_TimeRefresh_f
443 
444 For program optimization
445 ====================
446 */
R_TimeRefresh_f(void)447 void R_TimeRefresh_f (void)
448 {
449 #ifdef USE_OPENGLES
450   // Not implemented
451   Con_Printf("TimeRefresh not implemented.\n");
452 #else
453   int			i;
454   float		start, stop, time;
455   int			startangle;
456   vrect_t		vr;
457 
458   glDrawBuffer  (GL_FRONT);
459   glFinish ();
460 
461   start = Sys_FloatTime ();
462   for (i=0 ; i<128 ; i++)
463   {
464     r_refdef.viewangles[1] = i/128.0*360.0;
465     R_RenderView ();
466   }
467 
468   glFinish ();
469   stop = Sys_FloatTime ();
470   time = stop-start;
471   Con_Printf ("%f seconds (%f fps)\n", time, 128/time);
472 
473   glDrawBuffer  (GL_BACK);
474   GL_EndRendering ();
475 #endif
476 }
477 
D_FlushCaches(void)478 void D_FlushCaches (void)
479 {
480 }
481