Handle sky textures with non-standard sizes

This commit is contained in:
Andrei Drexler 2021-12-05 14:10:50 +02:00 committed by Ozkan Sezer
parent 9502aaff25
commit 7f4e1c13e7

View file

@ -95,44 +95,38 @@ A sky texture is 256*128, with the left side being a masked overlay
void Sky_LoadTexture (texture_t *mt) void Sky_LoadTexture (texture_t *mt)
{ {
char texturename[64]; char texturename[64];
int i, j, p, r, g, b, count; unsigned x, y, p, r, g, b, count, halfwidth, *rgba;
byte *src; byte *src, *front_data, *back_data;
static byte front_data[128*128]; //FIXME: Hunk_Alloc
static byte back_data[128*128]; //FIXME: Hunk_Alloc
unsigned *rgba;
if (mt->width != 256 || mt->height != 128) if (mt->width != 256 || mt->height != 128)
Sys_Error ("Sky texture %s has wrong size (%d x %d)", mt->name, mt->width, mt->height); {
Con_Warning ("Sky texture %s is %d x %d, expected 256 x 128\n", mt->name, mt->width, mt->height);
if (mt->width < 2 || mt->height < 1)
return;
}
halfwidth = mt->width / 2;
back_data = (byte *) Hunk_AllocName (halfwidth*mt->height*2, "skytex");
front_data = back_data + halfwidth*mt->height;
src = (byte *)(mt + 1); src = (byte *)(mt + 1);
// extract back layer and upload // extract back layer and upload
for (i=0 ; i<128 ; i++) for (y=0 ; y<mt->height ; y++)
for (j=0 ; j<128 ; j++) memcpy (back_data + y*halfwidth, src + halfwidth + y*mt->width, halfwidth);
back_data[(i*128) + j] = src[i*256 + j + 128];
q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name); q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name);
solidskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, back_data, "", (src_offset_t)back_data, TEXPREF_NONE); solidskytexture = TexMgr_LoadImage (loadmodel, texturename, halfwidth, mt->height, SRC_INDEXED, back_data, "", (src_offset_t)back_data, TEXPREF_NONE);
// extract front layer and upload // extract front layer and upload
for (i=0 ; i<128 ; i++)
for (j=0 ; j<128 ; j++)
{
front_data[(i*128) + j] = src[i*256 + j];
if (front_data[(i*128) + j] == 0)
front_data[(i*128) + j] = 255;
}
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name);
alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
// calculate r_fastsky color based on average of all opaque foreground colors
r = g = b = count = 0; r = g = b = count = 0;
for (i=0 ; i<128 ; i++) for (y=0 ; y<mt->height ; src+=mt->width, front_data+=halfwidth, y++)
for (j=0 ; j<128 ; j++)
{ {
p = src[i*256 + j]; for (x=0 ; x<halfwidth ; x++)
if (p != 0) {
p = src[x];
if (p == 0)
p = 255;
else
{ {
rgba = &d_8to24table[p]; rgba = &d_8to24table[p];
r += ((byte *)rgba)[0]; r += ((byte *)rgba)[0];
@ -140,7 +134,15 @@ void Sky_LoadTexture (texture_t *mt)
b += ((byte *)rgba)[2]; b += ((byte *)rgba)[2];
count++; count++;
} }
front_data[x] = p;
} }
}
front_data = back_data + halfwidth*mt->height;
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name);
alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, halfwidth, mt->height, SRC_INDEXED, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA);
// calculate r_fastsky color based on average of all opaque foreground colors
skyflatcolor[0] = (float)r/(count*255); skyflatcolor[0] = (float)r/(count*255);
skyflatcolor[1] = (float)g/(count*255); skyflatcolor[1] = (float)g/(count*255);
skyflatcolor[2] = (float)b/(count*255); skyflatcolor[2] = (float)b/(count*255);
@ -156,23 +158,30 @@ Quake64 sky textures are 32*64
void Sky_LoadTextureQ64 (texture_t *mt) void Sky_LoadTextureQ64 (texture_t *mt)
{ {
char texturename[64]; char texturename[64];
int i, p, r, g, b, count; unsigned i, p, r, g, b, count, halfheight, *rgba;
byte *front, *back, *front_rgba; byte *front, *back, *front_rgba;
unsigned *rgba;
if (mt->width != 32 || mt->height != 64)
{
Con_DWarning ("Q64 sky texture %s is %d x %d, expected 32 x 64\n", mt->name, mt->width, mt->height);
if (mt->width < 1 || mt->height < 2)
return;
}
// pointers to both layer textures // pointers to both layer textures
halfheight = mt->height / 2;
front = (byte *)(mt+1); front = (byte *)(mt+1);
back = (byte *)(mt+1) + (32*32); back = (byte *)(mt+1) + mt->width*halfheight;
front_rgba = (byte *) Hunk_Alloc(4*(32*32)); front_rgba = (byte *) Hunk_AllocName (4*mt->width*halfheight, "q64_skytex");
// Normal indexed texture for the back layer // Normal indexed texture for the back layer
q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name); q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name);
solidskytexture = TexMgr_LoadImage (loadmodel, texturename, 32, 32, SRC_INDEXED, back, "", (src_offset_t)back, TEXPREF_NONE); solidskytexture = TexMgr_LoadImage (loadmodel, texturename, mt->width, halfheight, SRC_INDEXED, back, "", (src_offset_t)back, TEXPREF_NONE);
// front layer, convert to RGBA and upload // front layer, convert to RGBA and upload
p = r = g = b = count = 0; p = r = g = b = count = 0;
for (i=0 ; i < (32*32) ; i++) for (i=mt->width*halfheight ; i!=0 ; i--)
{ {
rgba = &d_8to24table[*front++]; rgba = &d_8to24table[*front++];
@ -191,7 +200,7 @@ void Sky_LoadTextureQ64 (texture_t *mt)
} }
q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name); q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name);
alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, 32, 32, SRC_RGBA, front_rgba, "", (src_offset_t)front_rgba, TEXPREF_NONE); alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, mt->width, halfheight, SRC_RGBA, front_rgba, "", (src_offset_t)front_rgba, TEXPREF_ALPHA);
// calculate r_fastsky color based on average of all opaque foreground colors // calculate r_fastsky color based on average of all opaque foreground colors
skyflatcolor[0] = (float)r/(count*255); skyflatcolor[0] = (float)r/(count*255);
@ -331,7 +340,7 @@ void Sky_NewMap (void)
if (!strcmp("skyfog", key)) if (!strcmp("skyfog", key))
skyfog = atof(value); skyfog = atof(value);
#if 1 //also accept non-standard keys #if 1 /* also accept non-standard keys */
else if (!strcmp("skyname", key)) //half-life else if (!strcmp("skyname", key)) //half-life
Sky_LoadSkyBox(value); Sky_LoadSkyBox(value);
else if (!strcmp("qlsky", key)) //quake lives else if (!strcmp("qlsky", key)) //quake lives
@ -768,7 +777,7 @@ void Sky_DrawSkyBox (void)
GL_Bind (skybox_textures[skytexorder[i]]); GL_Bind (skybox_textures[skytexorder[i]]);
#if 1 //FIXME: this is to avoid tjunctions until i can do it the right way #if 1 /* FIXME: this is to avoid tjunctions until i can do it the right way */
skymins[0][i] = -1; skymins[0][i] = -1;
skymins[1][i] = -1; skymins[1][i] = -1;
skymaxs[0][i] = 1; skymaxs[0][i] = 1;