mirror of
https://github.com/nzp-team/glquake.git
synced 2025-03-15 07:00:57 +00:00
Implement skybox support
This commit is contained in:
parent
a05cf67b4b
commit
c708c4d8a8
7 changed files with 296 additions and 574 deletions
|
@ -395,7 +395,7 @@ void Mod_LoadTextures (lump_t *l)
|
|||
memcpy ( tx+1, mt+1, pixels);
|
||||
|
||||
|
||||
if (!Q_strncmp(mt->name,"sky",3))
|
||||
if (loadmodel->bspversion != HL_BSPVERSION && !Q_strncmp(mt->name,"sky",3))
|
||||
{
|
||||
R_InitSky (tx);
|
||||
}
|
||||
|
|
|
@ -265,7 +265,9 @@ void R_Init (void)
|
|||
R_InitParticles ();
|
||||
R_InitOtherTextures ();
|
||||
R_InitParticleTexture ();
|
||||
Fog_Init ();
|
||||
|
||||
Sky_Init (); //johnfitz
|
||||
Fog_Init (); //johnfitz
|
||||
|
||||
#ifdef GLTEST
|
||||
Test_Init ();
|
||||
|
@ -455,6 +457,8 @@ void R_NewMap (void)
|
|||
R_ClearParticles ();
|
||||
|
||||
GL_BuildLightmaps ();
|
||||
|
||||
Sky_NewMap (); //johnfitz -- skybox in worldspawn
|
||||
Fog_NewMap (); // johnfitz -- global fog in worldspawn
|
||||
|
||||
// identify sky texture
|
||||
|
@ -470,9 +474,7 @@ void R_NewMap (void)
|
|||
mirrortexturenum = i;
|
||||
cl.worldmodel->textures[i]->texturechain = NULL;
|
||||
}
|
||||
#ifdef QUAKE2
|
||||
R_LoadSkys ();
|
||||
#endif
|
||||
//R_LoadSkys ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
extern int skytexturenum;
|
||||
|
||||
#ifndef GL_RGBA4
|
||||
#define GL_RGBA4 0
|
||||
#endif
|
||||
|
@ -58,6 +56,8 @@ byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT];
|
|||
msurface_t *skychain = NULL;
|
||||
msurface_t *waterchain = NULL;
|
||||
|
||||
extern char skybox_name[32];
|
||||
|
||||
void R_RenderDynamicLightmaps (msurface_t *fa);
|
||||
|
||||
/*
|
||||
|
@ -774,8 +774,9 @@ void R_RenderBrushPoly (msurface_t *fa)
|
|||
c_brush_polys++;
|
||||
|
||||
if (fa->flags & SURF_DRAWSKY)
|
||||
{ // warp texture, no lightmaps
|
||||
EmitBothSkyLayers (fa);
|
||||
{
|
||||
if (strcmp(skybox_name, "") == 0)
|
||||
EmitBothSkyLayers (fa);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1066,7 @@ void DrawTextureChains (void)
|
|||
GL_DisableMultitexture();
|
||||
|
||||
if (skychain) {
|
||||
R_DrawSkyChain(skychain);
|
||||
//R_DrawSkyChain(skychain);
|
||||
skychain = NULL;
|
||||
}
|
||||
|
||||
|
@ -1080,8 +1081,6 @@ void DrawTextureChains (void)
|
|||
s = t->texturechain;
|
||||
if (!s)
|
||||
continue;
|
||||
if (i == skytexturenum)
|
||||
R_DrawSkyChain (s);
|
||||
else if (i == mirrortexturenum && r_mirroralpha.value != 1.0)
|
||||
{
|
||||
R_MirrorChain (s);
|
||||
|
@ -1360,14 +1359,14 @@ void R_RecursiveWorldNode (mnode_t *node)
|
|||
surf->texturechain = surf->texinfo->texture->texturechain;
|
||||
surf->texinfo->texture->texturechain = surf;
|
||||
}
|
||||
} else if (surf->flags & SURF_DRAWSKY) {
|
||||
} /*else if (surf->flags & SURF_DRAWSKY) {
|
||||
surf->texturechain = skychain;
|
||||
skychain = surf;
|
||||
} else if (surf->flags & SURF_DRAWTURB) {
|
||||
surf->texturechain = waterchain;
|
||||
waterchain = surf;
|
||||
} else
|
||||
R_DrawSequentialPoly (surf);
|
||||
R_DrawSequentialPoly (surf);*/
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1454,9 +1453,10 @@ void R_DrawWorld (void)
|
|||
|
||||
glColor3f (1,1,1);
|
||||
memset (lightmap_polys, 0, sizeof(lightmap_polys));
|
||||
#ifdef QUAKE2
|
||||
|
||||
R_ClearSkyBox ();
|
||||
#endif
|
||||
if (strcmp(skybox_name, "") != 0)
|
||||
R_DrawSkyBox();
|
||||
|
||||
R_RecursiveWorldNode (cl.worldmodel->nodes);
|
||||
|
||||
|
@ -1466,10 +1466,6 @@ void R_DrawWorld (void)
|
|||
|
||||
R_BlendLightmaps();
|
||||
|
||||
#ifdef QUAKE2
|
||||
R_DrawSkyBox ();
|
||||
#endif
|
||||
|
||||
Fog_EnableGFog ();
|
||||
}
|
||||
|
||||
|
@ -1789,10 +1785,10 @@ void GL_BuildLightmaps (void)
|
|||
GL_CreateSurfaceLightmap (m->surfaces + i);
|
||||
if ( m->surfaces[i].flags & SURF_DRAWTURB )
|
||||
continue;
|
||||
#ifndef QUAKE2
|
||||
|
||||
if ( m->surfaces[i].flags & SURF_DRAWSKY )
|
||||
continue;
|
||||
#endif
|
||||
|
||||
BuildSurfaceDisplayList (m->surfaces + i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -793,7 +793,7 @@ SCR_DrawLoadScreen
|
|||
* TheSmashers
|
||||
*/
|
||||
|
||||
// 50 character limit
|
||||
// 47 character limit
|
||||
|
||||
double loadingtimechange;
|
||||
int loadingdot;
|
||||
|
@ -802,14 +802,14 @@ char *lodinglinetext;
|
|||
qpic_t *awoo;
|
||||
char *ReturnLoadingtex (void)
|
||||
{
|
||||
int StringNum = Random_Int(74);
|
||||
int StringNum = Random_Int(80);
|
||||
switch(StringNum)
|
||||
{
|
||||
case 1:
|
||||
return "Released in 1996, Quake is over 25 years old!";
|
||||
break;
|
||||
case 2:
|
||||
return "Use the Kar98-k to be the hero we want you to be!";
|
||||
return "Use the Kar98k to be the hero we need!";
|
||||
break;
|
||||
case 3:
|
||||
return "Lots of modern engines are based on Quake!";
|
||||
|
@ -827,10 +827,10 @@ char *ReturnLoadingtex (void)
|
|||
return "NZ:P has been downloaded over 500,000 times!";
|
||||
break;
|
||||
case 8:
|
||||
return "NZ:P was made mainly by 3 guys around the world!";
|
||||
return "A lot of people have worked on NZ:P!";
|
||||
break;
|
||||
case 9:
|
||||
return "Blubswillrule: known as \"blubs\", is from the USA.";
|
||||
return "Blubswillrule, or \"blubs\", is from the US.";
|
||||
break;
|
||||
case 10:
|
||||
return "Jukki is from Finland.";
|
||||
|
@ -851,7 +851,7 @@ char *ReturnLoadingtex (void)
|
|||
return "Try Retro Mode, it's in the Graphics Settings!";
|
||||
break;
|
||||
case 16:
|
||||
return "Tired of our maps? Make your own or download some!";
|
||||
return "Tired of our maps? Go make your own!";
|
||||
break;
|
||||
case 17:
|
||||
return "Slay zombies & be grateful.";
|
||||
|
@ -866,7 +866,7 @@ char *ReturnLoadingtex (void)
|
|||
return "Please surround yourself with zombies!";
|
||||
break;
|
||||
case 21:
|
||||
return "Don't play for too long, or zombies will eat you.";
|
||||
return "Don't play for too long.. zombies may eat you.";
|
||||
break;
|
||||
case 22:
|
||||
return "That was epic... EPIC FOR THE WIIIN!"; //why
|
||||
|
@ -908,7 +908,7 @@ char *ReturnLoadingtex (void)
|
|||
return "Also check out \"Halo Revamped\" for 3DS!";
|
||||
break;
|
||||
case 35:
|
||||
return "MotoLegacy, or \"Ian\", is from the USA.";
|
||||
return "CypressImplex, or \"Ivy\", is from the USA.";
|
||||
break;
|
||||
case 36:
|
||||
return "Zombies don't like bullets.";
|
||||
|
@ -920,7 +920,7 @@ char *ReturnLoadingtex (void)
|
|||
return "Removed Herobrine";
|
||||
break;
|
||||
case 39:
|
||||
return "Pack-a-Punch the Kar98k to get to round infinity.";
|
||||
return "Pack-a-Punch the Kar98k to get to round 100000.";
|
||||
break;
|
||||
case 40:
|
||||
return "I feel like I'm being gaslit.";
|
||||
|
@ -1007,7 +1007,7 @@ char *ReturnLoadingtex (void)
|
|||
return "i want that twink Obliterated";
|
||||
break;
|
||||
case 68:
|
||||
return "i think he's started the femboy transition process";
|
||||
return "i think he started the femboy transition process";
|
||||
break;
|
||||
case 69:
|
||||
return "nice";
|
||||
|
@ -1019,11 +1019,29 @@ char *ReturnLoadingtex (void)
|
|||
return "yeah pog female bikers";
|
||||
break;
|
||||
case 72:
|
||||
return "This is either a stroke of genius or just a stroke";
|
||||
return "Its either a stroke of genius or just a stroke";
|
||||
break;
|
||||
case 73:
|
||||
return "Play some Custom Maps!";
|
||||
break;
|
||||
case 74:
|
||||
return "Real OGs play on \"Old\" 3DS models!";
|
||||
break;
|
||||
case 75:
|
||||
return "Adding this tip improved framerate by 39%!";
|
||||
break;
|
||||
case 76:
|
||||
return "The NZ in NZP stands for New Zealand!";
|
||||
break;
|
||||
case 77:
|
||||
return "The P in NZP stands for Professional!";
|
||||
break;
|
||||
case 78:
|
||||
return "Remember to stay hydrated!";
|
||||
break;
|
||||
case 79:
|
||||
return "cofe";
|
||||
break;
|
||||
}
|
||||
return "wut wut";
|
||||
}
|
||||
|
|
783
source/gl_warp.c
783
source/gl_warp.c
|
@ -29,6 +29,12 @@ int solidskytexture;
|
|||
int alphaskytexture;
|
||||
float speedscale; // for top sky and bottom sky
|
||||
|
||||
int skytexorder[5] = {0,2,1,3,4};
|
||||
int skyimage[5]; // Where sky images are stored
|
||||
char skybox_name[32] = ""; //name of current skybox, or "" if no skybox
|
||||
// cut off down for half skybox
|
||||
char *suf[5] = {"rt", "bk", "lf", "ft", "up" };
|
||||
|
||||
msurface_t *warpface;
|
||||
|
||||
extern cvar_t gl_subdivide_size;
|
||||
|
@ -336,352 +342,170 @@ void R_DrawSkyChain (msurface_t *s)
|
|||
=================================================================
|
||||
*/
|
||||
|
||||
#ifdef QUAKE2
|
||||
|
||||
|
||||
#define SKY_TEX 2000
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PCX Loading
|
||||
|
||||
=================================================================
|
||||
==================
|
||||
Sky_LoadSkyBox
|
||||
==================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
//char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
void Sky_LoadSkyBox(char* name)
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned data; // unbounded
|
||||
} pcx_t;
|
||||
if (strcmp(skybox_name, name) == 0)
|
||||
return; //no change
|
||||
|
||||
byte *pcx_rgb;
|
||||
|
||||
/*
|
||||
============
|
||||
LoadPCX
|
||||
============
|
||||
*/
|
||||
void LoadPCX (FILE *f)
|
||||
{
|
||||
pcx_t *pcx, pcxbuf;
|
||||
byte palette[768];
|
||||
byte *pix;
|
||||
int x, y;
|
||||
int dataByte, runLength;
|
||||
int count;
|
||||
|
||||
//
|
||||
// parse the PCX file
|
||||
//
|
||||
fread (&pcxbuf, 1, sizeof(pcxbuf), f);
|
||||
|
||||
pcx = &pcxbuf;
|
||||
|
||||
if (pcx->manufacturer != 0x0a
|
||||
|| pcx->version != 5
|
||||
|| pcx->encoding != 1
|
||||
|| pcx->bits_per_pixel != 8
|
||||
|| pcx->xmax >= 320
|
||||
|| pcx->ymax >= 256)
|
||||
{
|
||||
Con_Printf ("Bad pcx file\n");
|
||||
//turn off skybox if sky is set to ""
|
||||
if (name[0] == '0') {
|
||||
skybox_name[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// seek to palette
|
||||
fseek (f, -768, SEEK_END);
|
||||
fread (palette, 1, 768, f);
|
||||
// Do sides one way and top another, bottom is not done
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int mark = Hunk_LowMark ();
|
||||
|
||||
fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
|
||||
|
||||
count = (pcx->xmax+1) * (pcx->ymax+1);
|
||||
pcx_rgb = malloc( count * 4);
|
||||
|
||||
for (y=0 ; y<=pcx->ymax ; y++)
|
||||
{
|
||||
pix = pcx_rgb + 4*y*(pcx->xmax+1);
|
||||
for (x=0 ; x<=pcx->ymax ; )
|
||||
if(!(skyimage[i] = loadtextureimage (va("gfx/env/%s%s", name, suf[i]), 0, 0, false, false)) &&
|
||||
!(skyimage[i] = loadtextureimage (va("gfx/env/%s_%s", name, suf[i]), 0, 0, false, false)))
|
||||
{
|
||||
dataByte = fgetc(f);
|
||||
|
||||
if((dataByte & 0xC0) == 0xC0)
|
||||
{
|
||||
runLength = dataByte & 0x3F;
|
||||
dataByte = fgetc(f);
|
||||
Con_Printf("Sky: %s[%s] not found, used std\n", name, suf[i]);
|
||||
if(!(skyimage[i] = loadtextureimage (va("gfx/env/skybox%s", suf[i]), 0, 0, false, false)))
|
||||
{
|
||||
Sys_Error("STD SKY NOT FOUND!");
|
||||
}
|
||||
else
|
||||
runLength = 1;
|
||||
|
||||
while(runLength-- > 0)
|
||||
{
|
||||
pix[0] = palette[dataByte*3];
|
||||
pix[1] = palette[dataByte*3+1];
|
||||
pix[2] = palette[dataByte*3+2];
|
||||
pix[3] = 255;
|
||||
pix += 4;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
Hunk_FreeToLowMark (mark);
|
||||
}
|
||||
|
||||
int mark = Hunk_LowMark ();
|
||||
if(!(skyimage[4] = loadtextureimage (va("gfx/env/%sup", name), 0, 0, false, false)) &&
|
||||
!(skyimage[4] = loadtextureimage (va("gfx/env/%s_up", name), 0, 0, false, false)))
|
||||
{
|
||||
Con_Printf("Sky: %s[%s] not found, used std\n", name, suf[4]);
|
||||
if(!(skyimage[4] = loadtextureimage (va("gfx/env/skybox%s", suf[4]), 0, 0, false, false)))
|
||||
{
|
||||
Sys_Error("STD SKY NOT FOUND!");
|
||||
}
|
||||
|
||||
}
|
||||
Hunk_FreeToLowMark (mark);
|
||||
|
||||
strcpy(skybox_name, name);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sky_NewMap
|
||||
=================
|
||||
*/
|
||||
void Sky_NewMap (void)
|
||||
{
|
||||
char key[128], value[4096];
|
||||
char *data;
|
||||
|
||||
//purge old sky textures
|
||||
//UnloadSkyTexture ();
|
||||
|
||||
//
|
||||
// initially no sky
|
||||
//
|
||||
Sky_LoadSkyBox (""); //not used
|
||||
|
||||
//
|
||||
// read worldspawn (this is so ugly, and shouldn't it be done on the server?)
|
||||
//
|
||||
data = cl.worldmodel->entities;
|
||||
if (!data)
|
||||
return; //FIXME: how could this possibly ever happen? -- if there's no
|
||||
// worldspawn then the sever wouldn't send the loadmap message to the client
|
||||
|
||||
data = COM_Parse(data);
|
||||
|
||||
if (!data) //should never happen
|
||||
return; // error
|
||||
|
||||
if (com_token[0] != '{') //should never happen
|
||||
return; // error
|
||||
|
||||
while (1)
|
||||
{
|
||||
data = COM_Parse(data);
|
||||
|
||||
if (!data)
|
||||
return; // error
|
||||
|
||||
if (com_token[0] == '}')
|
||||
break; // end of worldspawn
|
||||
|
||||
if (com_token[0] == '_')
|
||||
strcpy(key, com_token + 1);
|
||||
else
|
||||
strcpy(key, com_token);
|
||||
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
||||
key[strlen(key)-1] = 0;
|
||||
|
||||
data = COM_Parse(data);
|
||||
if (!data)
|
||||
return; // error
|
||||
|
||||
strcpy(value, com_token);
|
||||
|
||||
if (!strcmp("sky", key))
|
||||
Sky_LoadSkyBox(value);
|
||||
else if (!strcmp("skyname", key)) //half-life
|
||||
Sky_LoadSkyBox(value);
|
||||
else if (!strcmp("qlsky", key)) //quake lives
|
||||
Sky_LoadSkyBox(value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=========================================================
|
||||
|
||||
TARGA LOADING
|
||||
|
||||
=========================================================
|
||||
=================
|
||||
Sky_SkyCommand_f
|
||||
=================
|
||||
*/
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
TargaHeader targa_header;
|
||||
byte *targa_rgba;
|
||||
|
||||
int fgetLittleShort (FILE *f)
|
||||
void Sky_SkyCommand_f (void)
|
||||
{
|
||||
byte b1, b2;
|
||||
|
||||
b1 = fgetc(f);
|
||||
b2 = fgetc(f);
|
||||
|
||||
return (short)(b1 + b2*256);
|
||||
switch (Cmd_Argc())
|
||||
{
|
||||
case 1:
|
||||
Con_Printf("\"sky\" is \"%s\"\n", skybox_name);
|
||||
break;
|
||||
case 2:
|
||||
Sky_LoadSkyBox(Cmd_Argv(1));
|
||||
break;
|
||||
default:
|
||||
Con_Printf("usage: sky <skyname>\n");
|
||||
}
|
||||
}
|
||||
|
||||
int fgetLittleLong (FILE *f)
|
||||
{
|
||||
byte b1, b2, b3, b4;
|
||||
|
||||
b1 = fgetc(f);
|
||||
b2 = fgetc(f);
|
||||
b3 = fgetc(f);
|
||||
b4 = fgetc(f);
|
||||
|
||||
return b1 + (b2<<8) + (b3<<16) + (b4<<24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadTGA
|
||||
Sky_Init
|
||||
=============
|
||||
*/
|
||||
void LoadTGA (FILE *fin)
|
||||
{
|
||||
int columns, rows, numPixels;
|
||||
byte *pixbuf;
|
||||
int row, column;
|
||||
|
||||
targa_header.id_length = fgetc(fin);
|
||||
targa_header.colormap_type = fgetc(fin);
|
||||
targa_header.image_type = fgetc(fin);
|
||||
|
||||
targa_header.colormap_index = fgetLittleShort(fin);
|
||||
targa_header.colormap_length = fgetLittleShort(fin);
|
||||
targa_header.colormap_size = fgetc(fin);
|
||||
targa_header.x_origin = fgetLittleShort(fin);
|
||||
targa_header.y_origin = fgetLittleShort(fin);
|
||||
targa_header.width = fgetLittleShort(fin);
|
||||
targa_header.height = fgetLittleShort(fin);
|
||||
targa_header.pixel_size = fgetc(fin);
|
||||
targa_header.attributes = fgetc(fin);
|
||||
|
||||
if (targa_header.image_type!=2
|
||||
&& targa_header.image_type!=10)
|
||||
Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
|
||||
|
||||
if (targa_header.colormap_type !=0
|
||||
|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
|
||||
Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
targa_rgba = malloc (numPixels*4);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
|
||||
|
||||
if (targa_header.image_type==2) { // Uncompressed, RGB images
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; column++) {
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
alphabyte = getc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type==10) { // Runlength encoded RGB images
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
for(row=rows-1; row>=0; row--) {
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
for(column=0; column<columns; ) {
|
||||
packetHeader=getc(fin);
|
||||
packetSize = 1 + (packetHeader & 0x7f);
|
||||
if (packetHeader & 0x80) { // run-length packet
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
alphabyte = getc(fin);
|
||||
break;
|
||||
}
|
||||
|
||||
for(j=0;j<packetSize;j++) {
|
||||
*pixbuf++=red;
|
||||
*pixbuf++=green;
|
||||
*pixbuf++=blue;
|
||||
*pixbuf++=alphabyte;
|
||||
column++;
|
||||
if (column==columns) { // run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
for(j=0;j<packetSize;j++) {
|
||||
switch (targa_header.pixel_size) {
|
||||
case 24:
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = getc(fin);
|
||||
green = getc(fin);
|
||||
red = getc(fin);
|
||||
alphabyte = getc(fin);
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
}
|
||||
column++;
|
||||
if (column==columns) { // pixel packet run spans across rows
|
||||
column=0;
|
||||
if (row>0)
|
||||
row--;
|
||||
else
|
||||
goto breakOut;
|
||||
pixbuf = targa_rgba + row*columns*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_LoadSkys
|
||||
==================
|
||||
*/
|
||||
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
void R_LoadSkys (void)
|
||||
void Sky_Init (void)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
char name[64];
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
GL_Bind (SKY_TEX + i);
|
||||
sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
|
||||
COM_FOpenFile (name, &f);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf ("Couldn't load %s\n", name);
|
||||
continue;
|
||||
}
|
||||
LoadTGA (f);
|
||||
// LoadPCX (f);
|
||||
Cmd_AddCommand ("sky",Sky_SkyCommand_f);
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
|
||||
// glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
|
||||
|
||||
free (targa_rgba);
|
||||
// free (pcx_rgb);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
for (i=0; i<5; i++)
|
||||
skyimage[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
vec3_t skyclip[6] = {
|
||||
static vec3_t skyclip[6] = {
|
||||
{1,1,0},
|
||||
{1,-1,0},
|
||||
{0,-1,1},
|
||||
{0,1,1},
|
||||
{1,0,1},
|
||||
{-1,0,1}
|
||||
{-1,0,1}
|
||||
};
|
||||
int c_sky;
|
||||
|
||||
// 1 = s, 2 = t, 3 = 2048
|
||||
int st_to_vec[6][3] =
|
||||
static int st_to_vec[6][3] =
|
||||
{
|
||||
{3,-1,2},
|
||||
{-3,1,2},
|
||||
|
@ -697,7 +521,7 @@ int st_to_vec[6][3] =
|
|||
};
|
||||
|
||||
// s = [0]/[2], t = [1]/[2]
|
||||
int vec_to_st[6][3] =
|
||||
static int vec_to_st[6][3] =
|
||||
{
|
||||
{-2,3,1},
|
||||
{2,3,-1},
|
||||
|
@ -712,212 +536,7 @@ int vec_to_st[6][3] =
|
|||
// {1,2,-3}
|
||||
};
|
||||
|
||||
float skymins[2][6], skymaxs[2][6];
|
||||
|
||||
void DrawSkyPolygon (int nump, vec3_t vecs)
|
||||
{
|
||||
int i,j;
|
||||
vec3_t v, av;
|
||||
float s, t, dv;
|
||||
int axis;
|
||||
float *vp;
|
||||
|
||||
c_sky++;
|
||||
#if 0
|
||||
glBegin (GL_POLYGON);
|
||||
for (i=0 ; i<nump ; i++, vecs+=3)
|
||||
{
|
||||
VectorAdd(vecs, r_origin, v);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd();
|
||||
return;
|
||||
#endif
|
||||
// decide which face it maps to
|
||||
VectorCopy (vec3_origin, v);
|
||||
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
|
||||
{
|
||||
VectorAdd (vp, v, v);
|
||||
}
|
||||
av[0] = fabs(v[0]);
|
||||
av[1] = fabs(v[1]);
|
||||
av[2] = fabs(v[2]);
|
||||
if (av[0] > av[1] && av[0] > av[2])
|
||||
{
|
||||
if (v[0] < 0)
|
||||
axis = 1;
|
||||
else
|
||||
axis = 0;
|
||||
}
|
||||
else if (av[1] > av[2] && av[1] > av[0])
|
||||
{
|
||||
if (v[1] < 0)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v[2] < 0)
|
||||
axis = 5;
|
||||
else
|
||||
axis = 4;
|
||||
}
|
||||
|
||||
// project new texture coords
|
||||
for (i=0 ; i<nump ; i++, vecs+=3)
|
||||
{
|
||||
j = vec_to_st[axis][2];
|
||||
if (j > 0)
|
||||
dv = vecs[j - 1];
|
||||
else
|
||||
dv = -vecs[-j - 1];
|
||||
|
||||
j = vec_to_st[axis][0];
|
||||
if (j < 0)
|
||||
s = -vecs[-j -1] / dv;
|
||||
else
|
||||
s = vecs[j-1] / dv;
|
||||
j = vec_to_st[axis][1];
|
||||
if (j < 0)
|
||||
t = -vecs[-j -1] / dv;
|
||||
else
|
||||
t = vecs[j-1] / dv;
|
||||
|
||||
if (s < skymins[0][axis])
|
||||
skymins[0][axis] = s;
|
||||
if (t < skymins[1][axis])
|
||||
skymins[1][axis] = t;
|
||||
if (s > skymaxs[0][axis])
|
||||
skymaxs[0][axis] = s;
|
||||
if (t > skymaxs[1][axis])
|
||||
skymaxs[1][axis] = t;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_CLIP_VERTS 64
|
||||
void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
|
||||
{
|
||||
float *norm;
|
||||
float *v;
|
||||
qboolean front, back;
|
||||
float d, e;
|
||||
float dists[MAX_CLIP_VERTS];
|
||||
int sides[MAX_CLIP_VERTS];
|
||||
vec3_t newv[2][MAX_CLIP_VERTS];
|
||||
int newc[2];
|
||||
int i, j;
|
||||
|
||||
if (nump > MAX_CLIP_VERTS-2)
|
||||
Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
|
||||
if (stage == 6)
|
||||
{ // fully clipped, so draw it
|
||||
DrawSkyPolygon (nump, vecs);
|
||||
return;
|
||||
}
|
||||
|
||||
front = back = false;
|
||||
norm = skyclip[stage];
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
d = DotProduct (v, norm);
|
||||
if (d > ON_EPSILON)
|
||||
{
|
||||
front = true;
|
||||
sides[i] = SIDE_FRONT;
|
||||
}
|
||||
else if (d < ON_EPSILON)
|
||||
{
|
||||
back = true;
|
||||
sides[i] = SIDE_BACK;
|
||||
}
|
||||
else
|
||||
sides[i] = SIDE_ON;
|
||||
dists[i] = d;
|
||||
}
|
||||
|
||||
if (!front || !back)
|
||||
{ // not clipped
|
||||
ClipSkyPolygon (nump, vecs, stage+1);
|
||||
return;
|
||||
}
|
||||
|
||||
// clip it
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
VectorCopy (vecs, (vecs+(i*3)) );
|
||||
newc[0] = newc[1] = 0;
|
||||
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
switch (sides[i])
|
||||
{
|
||||
case SIDE_FRONT:
|
||||
VectorCopy (v, newv[0][newc[0]]);
|
||||
newc[0]++;
|
||||
break;
|
||||
case SIDE_BACK:
|
||||
VectorCopy (v, newv[1][newc[1]]);
|
||||
newc[1]++;
|
||||
break;
|
||||
case SIDE_ON:
|
||||
VectorCopy (v, newv[0][newc[0]]);
|
||||
newc[0]++;
|
||||
VectorCopy (v, newv[1][newc[1]]);
|
||||
newc[1]++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
||||
continue;
|
||||
|
||||
d = dists[i] / (dists[i] - dists[i+1]);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
e = v[j] + d*(v[j+3] - v[j]);
|
||||
newv[0][newc[0]][j] = e;
|
||||
newv[1][newc[1]][j] = e;
|
||||
}
|
||||
newc[0]++;
|
||||
newc[1]++;
|
||||
}
|
||||
|
||||
// continue
|
||||
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
|
||||
ClipSkyPolygon (newc[1], newv[1][0], stage+1);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawSkyChain
|
||||
=================
|
||||
*/
|
||||
void R_DrawSkyChain (msurface_t *s)
|
||||
{
|
||||
msurface_t *fa;
|
||||
|
||||
int i;
|
||||
vec3_t verts[MAX_CLIP_VERTS];
|
||||
glpoly_t *p;
|
||||
|
||||
c_sky = 0;
|
||||
GL_Bind(solidskytexture);
|
||||
|
||||
// calculate vertex values for sky box
|
||||
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
{
|
||||
for (p=fa->polys ; p ; p=p->next)
|
||||
{
|
||||
for (i=0 ; i<p->numverts ; i++)
|
||||
{
|
||||
VectorSubtract (p->verts[i], r_origin, verts[i]);
|
||||
}
|
||||
ClipSkyPolygon (p->numverts, verts[0], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float skymins[2][6], skymaxs[2][6];
|
||||
|
||||
/*
|
||||
==============
|
||||
|
@ -928,7 +547,7 @@ void R_ClearSkyBox (void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
for (i=0 ; i<5 ; i++)
|
||||
{
|
||||
skymins[0][i] = skymins[1][i] = 9999;
|
||||
skymaxs[0][i] = skymaxs[1][i] = -9999;
|
||||
|
@ -978,50 +597,134 @@ void MakeSkyVec (float s, float t, int axis)
|
|||
R_DrawSkyBox
|
||||
==============
|
||||
*/
|
||||
int skytexorder[6] = {0,2,1,3,4,5};
|
||||
|
||||
float skynormals[5][3] = {
|
||||
{ 1.f, 0.f, 0.f },
|
||||
{ -1.f, 0.f, 0.f },
|
||||
{ 0.f, 1.f, 0.f },
|
||||
{ 0.f, -1.f, 0.f },
|
||||
{ 0.f, 0.f, 1.f }
|
||||
};
|
||||
|
||||
float skyrt[5][3] = {
|
||||
{ 0.f, -1.f, 0.f },
|
||||
{ 0.f, 1.f, 0.f },
|
||||
{ 1.f, 0.f, 0.f },
|
||||
{ -1.f, 0.f, 0.f },
|
||||
{ 0.f, -1.f, 0.f }
|
||||
};
|
||||
|
||||
float skyup[5][3] = {
|
||||
{ 0.f, 0.f, 1.f },
|
||||
{ 0.f, 0.f, 1.f },
|
||||
{ 0.f, 0.f, 1.f },
|
||||
{ 0.f, 0.f, 1.f },
|
||||
{ -1.f, 0.f, 0.f }
|
||||
};
|
||||
|
||||
void R_DrawSkyBox (void)
|
||||
{
|
||||
int i, j, k;
|
||||
vec3_t v;
|
||||
float s, t;
|
||||
|
||||
#if 0
|
||||
glEnable (GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glColor4f (1,1,1,0.5);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
#endif
|
||||
for (i=0 ; i<6 ; i++)
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
float skydepth = 256.f;
|
||||
|
||||
for (i=0 ; i<5 ; i++)
|
||||
{
|
||||
const int vertex_count = 4;
|
||||
glvert_t sky_vertices[vertex_count];
|
||||
|
||||
// check if poly needs to be drawn at all
|
||||
float dot = DotProduct(skynormals[i], vpn);
|
||||
// < 0 check would work at fov 90 or less, just guess a value that's high enough?
|
||||
if (dot < -0.25f) continue;
|
||||
|
||||
GL_Bind(skyimage[skytexorder[i]]);
|
||||
|
||||
// if direction is not up, cut "down" vector to zero to only render half cube
|
||||
//float upnegfact = i == 4 ? 1.0f : 0.0f;
|
||||
float upnegfact = 1.0f;
|
||||
|
||||
float skyboxtexsize = 256.f;
|
||||
// move ever so slightly less towards forward to make edges overlap a bit, just to not have shimmering pixels between sky edges
|
||||
float forwardfact = 0.99f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
sky_vertices[0].s = 0.5f / skyboxtexsize;
|
||||
sky_vertices[0].t = (skyboxtexsize - .5f) / skyboxtexsize;
|
||||
sky_vertices[0].x = r_origin[0] + (forwardfact * skynormals[i][0] - skyrt[i][0] - skyup[i][0] * upnegfact) * skydepth;
|
||||
sky_vertices[0].y = r_origin[1] + (forwardfact * skynormals[i][1] - skyrt[i][1] - skyup[i][1] * upnegfact) * skydepth;
|
||||
sky_vertices[0].z = r_origin[2] + (forwardfact * skynormals[i][2] - skyrt[i][2] - skyup[i][2] * upnegfact) * skydepth;
|
||||
v[0] = sky_vertices[0].x;
|
||||
v[1] = sky_vertices[0].y;
|
||||
v[2] = sky_vertices[0].z;
|
||||
glTexCoord2f (sky_vertices[0].s, sky_vertices[0].t);
|
||||
glVertex3fv (v);
|
||||
|
||||
sky_vertices[1].s = 0.5f / skyboxtexsize;
|
||||
sky_vertices[1].t = 0.5f / skyboxtexsize;
|
||||
sky_vertices[1].x = r_origin[0] + (forwardfact * skynormals[i][0] - skyrt[i][0] + skyup[i][0]) * skydepth;
|
||||
sky_vertices[1].y = r_origin[1] + (forwardfact * skynormals[i][1] - skyrt[i][1] + skyup[i][1]) * skydepth;
|
||||
sky_vertices[1].z = r_origin[2] + (forwardfact * skynormals[i][2] - skyrt[i][2] + skyup[i][2]) * skydepth;
|
||||
v[0] = sky_vertices[1].x;
|
||||
v[1] = sky_vertices[1].y;
|
||||
v[2] = sky_vertices[1].z;
|
||||
glTexCoord2f (sky_vertices[1].s, sky_vertices[1].t);
|
||||
glVertex3fv (v);
|
||||
|
||||
sky_vertices[2].s = (skyboxtexsize - .5f) / skyboxtexsize;
|
||||
sky_vertices[2].t = 0.5f / skyboxtexsize;
|
||||
sky_vertices[2].x = r_origin[0] + (forwardfact * skynormals[i][0] + skyrt[i][0] + skyup[i][0]) * skydepth;
|
||||
sky_vertices[2].y = r_origin[1] + (forwardfact * skynormals[i][1] + skyrt[i][1] + skyup[i][1]) * skydepth;
|
||||
sky_vertices[2].z = r_origin[2] + (forwardfact * skynormals[i][2] + skyrt[i][2] + skyup[i][2]) * skydepth;
|
||||
v[0] = sky_vertices[2].x;
|
||||
v[1] = sky_vertices[2].y;
|
||||
v[2] = sky_vertices[2].z;
|
||||
glTexCoord2f (sky_vertices[2].s, sky_vertices[2].t);
|
||||
glVertex3fv (v);
|
||||
|
||||
sky_vertices[3].s = (skyboxtexsize - .5f) / skyboxtexsize;
|
||||
sky_vertices[3].t = (skyboxtexsize - .5f) / skyboxtexsize;
|
||||
sky_vertices[3].x = r_origin[0] + (forwardfact * skynormals[i][0] + skyrt[i][0] - skyup[i][0] * upnegfact) * skydepth;
|
||||
sky_vertices[3].y = r_origin[1] + (forwardfact * skynormals[i][1] + skyrt[i][1] - skyup[i][1] * upnegfact) * skydepth;
|
||||
sky_vertices[3].z = r_origin[2] + (forwardfact * skynormals[i][2] + skyrt[i][2] - skyup[i][2] * upnegfact) * skydepth;
|
||||
v[0] = sky_vertices[3].x;
|
||||
v[1] = sky_vertices[3].y;
|
||||
v[2] = sky_vertices[3].z;
|
||||
glTexCoord2f (sky_vertices[3].s, sky_vertices[3].t);
|
||||
glVertex3fv (v);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
/*
|
||||
for (i=0 ; i<5 ; i++)
|
||||
{
|
||||
if (skymins[0][i] >= skymaxs[0][i]
|
||||
|| skymins[1][i] >= skymaxs[1][i])
|
||||
continue;
|
||||
|
||||
GL_Bind (SKY_TEX+skytexorder[i]);
|
||||
#if 0
|
||||
skymins[0][i] = -1;
|
||||
skymins[1][i] = -1;
|
||||
skymaxs[0][i] = 1;
|
||||
skymaxs[1][i] = 1;
|
||||
#endif
|
||||
GL_Bind (skyimage[skytexorder[i]]);
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
MakeSkyVec (skymins[0][i], skymins[1][i], i);
|
||||
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
|
||||
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
|
||||
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
|
||||
glEnd ();
|
||||
}
|
||||
#if 0
|
||||
glDisable (GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glColor4f (1,1,1,0.5);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
#endif
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//===============================================================
|
||||
|
||||
/*
|
||||
|
|
|
@ -332,6 +332,9 @@ void Fog_NewMap (void);
|
|||
void Fog_Init (void);
|
||||
void Fog_SetupState (void);
|
||||
|
||||
void Sky_Init (void);
|
||||
void Sky_NewMap (void);
|
||||
|
||||
qboolean VID_Is8bit(void);
|
||||
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ int main (int argc, char **argv)
|
|||
CFGU_GetSystemModel(&model);
|
||||
cfguExit();
|
||||
|
||||
if(model != CFG_MODEL_2DS)
|
||||
if(model != CFG_MODEL_2DS && new3ds_flag == true)
|
||||
gfxSetWide(true);
|
||||
|
||||
chdir("sdmc:/3ds/nzportable");
|
||||
|
|
Loading…
Reference in a new issue