Implement skybox support

This commit is contained in:
Ian 2023-10-13 13:54:40 -04:00
parent a05cf67b4b
commit c708c4d8a8
7 changed files with 296 additions and 574 deletions

View File

@ -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);
}

View File

@ -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 ();
}

View File

@ -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,7 +774,8 @@ void R_RenderBrushPoly (msurface_t *fa)
c_brush_polys++;
if (fa->flags & SURF_DRAWSKY)
{ // warp texture, no lightmaps
{
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);
}
}

View File

@ -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";
}

View File

@ -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,341 +342,159 @@ 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);
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++)
// Do sides one way and top another, bottom is not done
for (int i = 0; i < 4; i++)
{
pix = pcx_rgb + 4*y*(pcx->xmax+1);
for (x=0 ; x<=pcx->ymax ; )
{
dataByte = fgetc(f);
int mark = Hunk_LowMark ();
if((dataByte & 0xC0) == 0xC0)
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)))
{
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!");
}
}
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
runLength = 1;
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
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++;
}
}
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);
}
int fgetLittleLong (FILE *f)
switch (Cmd_Argc())
{
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);
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");
}
}
/*
=============
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},
@ -681,7 +505,7 @@ vec3_t skyclip[6] = {
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,49 +597,133 @@ 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_BLEND);
glDisable(GL_ALPHA_TEST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
#endif
for (i=0 ; i<6 ; i++)
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
//===============================================================

View File

@ -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);

View File

@ -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");