#include "r_shadow.h"
#include "polygon.h"
#include "curves.h"
+#include "wad.h"
+
// note: model_shared.c sets up r_notexture, and r_surf_notexture
}
}
+/*
+=============
+R_Q1BSP_LoadSplitSky
+
+A sky texture is 256*128, with the right side being a masked overlay
+==============
+*/
+void R_Q1BSP_LoadSplitSky (qbyte *src, int width, int height, int bytesperpixel)
+{
+ int i, j;
+ unsigned solidpixels[128*128], alphapixels[128*128];
+
+ // if sky isn't the right size, just use it as a solid layer
+ if (width != 256 || height != 128)
+ {
+ loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", width, height, src, bytesperpixel == 4 ? TEXTYPE_RGBA : TEXTYPE_PALETTE, TEXF_PRECACHE, bytesperpixel == 1 ? palette_complete : NULL);
+ loadmodel->brush.alphaskytexture = NULL;;
+ return;
+ }
+
+ if (bytesperpixel == 4)
+ {
+ for (i = 0;i < 128;i++)
+ {
+ for (j = 0;j < 128;j++)
+ {
+ solidpixels[(i*128) + j] = ((unsigned *)src)[i*256+j+128];
+ alphapixels[(i*128) + j] = ((unsigned *)src)[i*256+j];
+ }
+ }
+ }
+ else
+ {
+ // make an average value for the back to avoid
+ // a fringe on the top level
+ int p, r, g, b;
+ union
+ {
+ unsigned int i;
+ unsigned char b[4];
+ }
+ rgba;
+ r = g = b = 0;
+ for (i = 0;i < 128;i++)
+ {
+ for (j = 0;j < 128;j++)
+ {
+ rgba.i = palette_complete[src[i*256 + j + 128]];
+ r += rgba.b[0];
+ g += rgba.b[1];
+ b += rgba.b[2];
+ }
+ }
+ rgba.b[0] = r/(128*128);
+ rgba.b[1] = g/(128*128);
+ rgba.b[2] = b/(128*128);
+ rgba.b[3] = 0;
+ for (i = 0;i < 128;i++)
+ {
+ for (j = 0;j < 128;j++)
+ {
+ solidpixels[(i*128) + j] = palette_complete[src[i*256 + j + 128]];
+ alphapixels[(i*128) + j] = (p = src[i*256 + j]) ? palette_complete[p] : rgba.i;
+ }
+ }
+ }
+
+ loadmodel->brush.solidskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_solidtexture", 128, 128, (qbyte *) solidpixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
+ loadmodel->brush.alphaskytexture = R_LoadTexture2D(loadmodel->texturepool, "sky_alphatexture", 128, 128, (qbyte *) alphapixels, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
+}
+
static void Mod_Q1BSP_LoadTextures(lump_t *l)
{
int i, j, k, num, max, altmax, mtwidth, mtheight, *dofs, incomplete;
data = loadimagepixels(tx->name, false, 0, 0);
if (data)
{
- if (image_width == 256 && image_height == 128)
- {
- R_InitSky(data, 4);
- Mem_Free(data);
- }
- else
- {
- Mem_Free(data);
- Con_Printf("Invalid replacement texture for sky \"%s\" in %\"%s\", must be 256x128 pixels\n", tx->name, loadmodel->name);
- if (mtdata != NULL)
- R_InitSky(mtdata, 1);
- }
+ R_Q1BSP_LoadSplitSky(data, image_width, image_height, 4);
+ Mem_Free(data);
}
else if (mtdata != NULL)
- R_InitSky(mtdata, 1);
+ R_Q1BSP_LoadSplitSky(mtdata, mtwidth, mtheight, 1);
}
}
else
extern void R_Q1BSP_Draw(entity_render_t *ent);
extern void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
extern void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist);
-extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist);
+extern void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
void Mod_Q1BSP_Load(model_t *mod, void *buffer)
{
int i, j, k;
mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
if (loadmodel->isworldmodel)
- {
Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
- // until we get a texture for it...
- R_ResetQuakeSky();
- }
// swap all the lumps
mod_base = (qbyte *)header;
Host_Error("Mod_Q2BSP_Load: %s has wrong version number (%i, should be %i)", mod->name, i, Q2BSPVERSION);
mod->brush.ishlbsp = false;
if (loadmodel->isworldmodel)
- {
Cvar_SetValue("halflifebsp", mod->brush.ishlbsp);
- // until we get a texture for it...
- R_ResetQuakeSky();
- }
mod_base = (qbyte *)header;
else if (numparameters >= 3 && !strcasecmp(parameter[0], "animmap"))
strlcpy(firstpasstexturename, parameter[2], sizeof(firstpasstexturename));
}
+ if (!strcasecmp(parameter[0], "alphafunc"))
+ flags2 |= Q3TEXTUREFLAG_ALPHATEST;
// break out a level if it was }
if (!strcasecmp(com_token, "}"))
break;
// force transparent render path for a number of odd
// shader effects to avoid bogging down the normal
// render path unnecessarily
- if (flags2 & (Q3TEXTUREFLAG_ADDITIVE | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+ if (flags2 & (Q3TEXTUREFLAG_ADDITIVE | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2 | Q3TEXTUREFLAG_ALPHATEST))
flags |= Q3SURFACEPARM_TRANS;
// add shader to list (shadername and flags)
// actually here we just poke into the texture settings
// out->surfaceparms |= Q3SURFACEPARM_TRANS;
}
if (!Mod_LoadSkinFrame(&out->skin, out->name, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, true, true))
- Mod_LoadSkinFrame(&out->skin, out->firstpasstexturename, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, true, true);
+ if (!Mod_LoadSkinFrame(&out->skin, out->firstpasstexturename, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, true, true))
+ Con_Printf("%s: texture loading for shader \"%s\" failed (first layer \"%s\" not found either)\n", loadmodel->name, out->name, out->firstpasstexturename);
}
- Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
+ if (c)
+ Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
}
static void Mod_Q3BSP_LoadPlanes(lump_t *l)
else
out->effect = loadmodel->brushq3.data_effects + n;
n = LittleLong(in->lightmapindex);
- if (n < -1 || n >= loadmodel->brushq3.num_lightmaps)
+ if (n >= loadmodel->brushq3.num_lightmaps)
{
- Con_DPrintf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->texture->name, n, loadmodel->brushq3.num_lightmaps);
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->texture->name, n, loadmodel->brushq3.num_lightmaps);
n = -1;
}
+ else if (n < 0)
+ n = -1;
if (n == -1)
out->lightmaptexture = NULL;
else
// leafs to find real number of clusters
loadmodel->brush.num_pvsclusters = 1;
for (i = 0;i < loadmodel->brushq3.num_leafs;i++)
- loadmodel->brush.num_pvsclusters = min(loadmodel->brush.num_pvsclusters, loadmodel->brushq3.data_leafs[i].clusterindex + 1);
+ loadmodel->brush.num_pvsclusters = max(loadmodel->brush.num_pvsclusters, loadmodel->brushq3.data_leafs[i].clusterindex + 1);
// create clusters
loadmodel->brush.num_pvsclusterbytes = (loadmodel->brush.num_pvsclusters + 7) / 8;
extern void R_Q3BSP_Draw(struct entity_render_s *ent);
extern void R_Q3BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
extern void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist);
-extern void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist);
+extern void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist);
void Mod_Q3BSP_Load(model_t *mod, void *buffer)
{
int i, j, numshadowmeshtriangles;
if (i != Q3BSPVERSION)
Host_Error("Mod_Q3BSP_Load: %s has wrong version number (%i, should be %i)", mod->name, i, Q3BSPVERSION);
if (mod->isworldmodel)
- {
Cvar_SetValue("halflifebsp", false);
- // until we get a texture for it...
- R_ResetQuakeSky();
- }
mod->soundfromcenter = true;
mod->TraceBox = Mod_Q3BSP_TraceBox;