Home | History | Annotate | Download | only in jni
      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 */
     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.
     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 
     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 */
    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 */
    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 */
    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 */
    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 */
    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 
    478 void D_FlushCaches (void)
    479 {
    480 }
    481