renders: Add RBSP initial support

Surfaces/faces/tetures flags is incorrect.
This commit is contained in:
Denis Pauk 2024-04-11 00:35:39 +03:00
parent c13074758a
commit 7a5154bd6b
6 changed files with 859 additions and 16 deletions

View file

@ -417,19 +417,12 @@ Mod_CalcSurfaceExtents(const int *surfedges, mvertex_t *vertexes, medge_t *edges
}
}
/*
=================
Mod_LoadTexinfo
extra for skybox in soft render
=================
*/
void
Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
Mod_LoadTexinfoRBSP(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
const byte *mod_base, const lump_t *l, findimage_t find_image,
struct image_s *notexture, maptype_t maptype)
{
texinfo_t *in;
texrinfo_t *in;
mtexinfo_t *out, *step;
int i, count;
@ -442,6 +435,7 @@ Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
}
count = l->filelen / sizeof(*in);
/* extra for skybox in soft render */
out = Hunk_Alloc((count + EXTRA_LUMP_TEXINFO) * sizeof(*out));
*texinfo = out;
@ -498,6 +492,105 @@ Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
}
}
void
Mod_LoadTexinfoQ2(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
const byte *mod_base, const lump_t *l, findimage_t find_image,
struct image_s *notexture, maptype_t maptype)
{
texinfo_t *in;
mtexinfo_t *out, *step;
int i, count;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, name);
}
count = l->filelen / sizeof(*in);
/* extra for skybox in soft render */
out = Hunk_Alloc((count + EXTRA_LUMP_TEXINFO) * sizeof(*out));
*texinfo = out;
*numtexinfo = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
struct image_s *image;
int j, next;
for (j = 0; j < 4; j++)
{
out->vecs[0][j] = LittleFloat(in->vecs[0][j]);
out->vecs[1][j] = LittleFloat(in->vecs[1][j]);
}
/* Convert flags for game type */
out->flags = Mod_LoadSurfConvertFlags(LittleLong(in->flags), maptype);
next = LittleLong(in->nexttexinfo);
if (next > 0)
{
out->next = *texinfo + next;
}
else
{
/*
* Fix for the problem where the game
* domed core when loading a new level.
*/
out->next = NULL;
}
image = GetTexImage(in->texture, find_image);
if (!image)
{
R_Printf(PRINT_ALL, "%s: Couldn't load %s\n",
__func__, in->texture);
image = notexture;
}
out->image = image;
}
// count animation frames
for (i=0 ; i<count ; i++)
{
out = (*texinfo) + i;
out->numframes = 1;
for (step = out->next ; step && step != out ; step=step->next)
{
out->numframes++;
}
}
}
/*
=================
Mod_LoadTexinfo
extra for skybox in soft render
=================
*/
void
Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo,
const byte *mod_base, const lump_t *l, findimage_t find_image,
struct image_s *notexture, maptype_t maptype)
{
if (maptype == map_sin)
{
Mod_LoadTexinfoRBSP(name, texinfo, numtexinfo, mod_base, l, find_image,
notexture, maptype);
}
else
{
Mod_LoadTexinfoQ2(name, texinfo, numtexinfo, mod_base, l, find_image,
notexture, maptype);
}
}
/*
=================
Mod_LoadEdges
@ -1283,6 +1376,80 @@ calcTexinfoAndFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl
return ret;
}
static int
calcRBSPTexinfoAndFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl)
{
drface_t* face_in = (void *)(mod_base + fl->fileofs);
const texrinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs);
if (fl->filelen % sizeof(*face_in) || tl->filelen % sizeof(*texinfo_in))
{
// will error out when actually loading it
return 0;
}
int ret = 0;
int face_count = fl->filelen / sizeof(*face_in);
int texinfo_count = tl->filelen / sizeof(*texinfo_in);
{
int baseSize = (face_count + EXTRA_LUMP_FACES) * sizeof(msurface_t);
baseSize = (baseSize + 31) & ~31;
ret += baseSize;
int ti_size = texinfo_count * sizeof(mtexinfo_t);
ti_size = (ti_size + 31) & ~31;
ret += ti_size;
}
int numWarpFaces = 0;
for (int surfnum = 0; surfnum < face_count; surfnum++, face_in++)
{
int numverts = LittleShort(face_in->numedges);
int ti = LittleShort(face_in->texinfo);
if ((ti < 0) || (ti >= texinfo_count))
{
return 0; // will error out
}
int texFlags = LittleLong(texinfo_in[ti].flags);
/* set the drawing flags */
if (texFlags & SURF_WARP)
{
if (numverts > 60)
return 0; // will error out in R_SubdividePolygon()
// R_SubdivideSurface(out, loadmodel); /* cut up polygon for warps */
// for each (pot. recursive) call to R_SubdividePolygon():
// sizeof(mpoly_t) + ((numverts - 4) + 2) * sizeof(mvtx_t)
// this is tricky, how much is allocated depends on the size of the surface
// which we don't know (we'd need the vertices etc to know, but we can't load
// those without allocating...)
// so we just count warped faces and use a generous estimate below
++numWarpFaces;
}
else
{
// LM_BuildPolygonFromSurface(out);
// => poly = Hunk_Alloc(sizeof(mpoly_t) + (numverts - 4) * sizeof(mvtx_t));
int polySize = sizeof(mpoly_t) + (numverts - 4) * sizeof(mvtx_t);
polySize = (polySize + 31) & ~31;
ret += polySize;
}
}
// yeah, this is a bit hacky, but it looks like for each warped face
// 256-55000 bytes are allocated (usually on the lower end),
// so just assume 48k per face to be safe
ret += numWarpFaces * 49152;
return ret;
}
static int
calcTexinfoAndQFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl)
{
@ -1371,8 +1538,18 @@ Mod_CalcNonModelLumpHunkSize(const byte *mod_base, const dheader_t *header,
{
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_EDGES],
sizeof(dedge_t), sizeof(medge_t), EXTRA_LUMP_EDGES);
hunkSize += calcTexinfoAndFacesSize(mod_base,
&header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
if (maptype == map_sin)
{
hunkSize += calcRBSPTexinfoAndFacesSize(mod_base,
&header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
}
else
{
hunkSize += calcTexinfoAndFacesSize(mod_base,
&header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
}
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFFACES],
sizeof(short), sizeof(msurface_t *), 0); // yes, out is indeed a pointer!

View file

@ -307,6 +307,134 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
LM_EndBuildingLightmaps();
}
static void
Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum, lminfosize;
const dlminfo_t *lminfos;
msurface_t *out;
drface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if ((lminfos != NULL) &&
(lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces))
{
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum, lightofs;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
if (out->numedges < 3)
{
Com_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
Com_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleShort(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
Com_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out);
lightofs = in->lightofs;
}
Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata,
out, in->styles, lightofs);
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
}
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
static void
Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
@ -530,7 +658,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
if ((header->ident == IDBSPHEADER) ||
(header->ident == RBSPHEADER))
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
if (maptype == map_sin)
{
Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
else
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
}
else
{

View file

@ -308,6 +308,134 @@ Mod_LoadFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l,
LM_EndBuildingLightmaps();
}
static void
Mod_LoadRFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum, lminfosize;
const dlminfo_t *lminfos;
msurface_t *out;
drface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if ((lminfos != NULL) &&
(lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces))
{
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum, lightofs;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
if (out->numedges < 3)
{
Com_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
Com_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleShort(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
Com_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out);
lightofs = in->lightofs;
}
Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata,
out, in->styles, lightofs);
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
}
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
static void
Mod_LoadQFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
@ -531,7 +659,14 @@ Mod_LoadBrushModel(gl3model_t *mod, const void *buffer, int modfilelen)
if ((header->ident == IDBSPHEADER) ||
(header->ident == RBSPHEADER))
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
if (maptype == map_sin)
{
Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
else
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
}
else
{

View file

@ -308,6 +308,134 @@ Mod_LoadFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l,
LM_EndBuildingLightmaps();
}
static void
Mod_LoadRFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum, lminfosize;
const dlminfo_t *lminfos;
msurface_t *out;
drface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if ((lminfos != NULL) &&
(lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces))
{
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum, lightofs;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
if (out->numedges < 3)
{
Com_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
Com_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleShort(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
Com_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out);
lightofs = in->lightofs;
}
Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata,
out, in->styles, lightofs);
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
}
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
static void
Mod_LoadQFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
@ -531,7 +659,14 @@ Mod_LoadBrushModel(gl4model_t *mod, const void *buffer, int modfilelen)
if ((header->ident == IDBSPHEADER) ||
(header->ident == RBSPHEADER))
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
if (maptype == map_sin)
{
Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
else
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
}
else
{

View file

@ -303,6 +303,125 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
}
static void
Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum;
msurface_t *out;
drface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum, lightofs;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleLong(in->numedges);
if (out->numedges < 3)
{
Com_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleLong(in->planenum);
side = LittleLong(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
Com_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleLong(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
Com_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = -1;
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out);
lightofs = in->lightofs;
}
Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata,
out, in->styles, in->lightofs);
if (!out->texinfo->image)
continue;
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
continue;
}
}
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
continue;
}
//==============
// this marks flowing surfaces as turbulent.
if (out->texinfo->flags & SURF_FLOWING)
{
out->flags |= SURF_DRAWTURB;
for (i=0 ; i<2 ; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
continue;
}
//==============
}
}
static void
Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
@ -517,7 +636,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
if ((header->ident == IDBSPHEADER) ||
(header->ident == RBSPHEADER))
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
if (maptype == map_sin)
{
Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
else
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
}
else
{

View file

@ -282,6 +282,134 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
LM_EndBuildingLightmaps();
}
static void
Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum, lminfosize;
const dlminfo_t *lminfos;
msurface_t *out;
drface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if ((lminfos != NULL) &&
(lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces))
{
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum, lightofs;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
if (out->numedges < 3)
{
Com_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
Com_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleShort(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
Com_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out);
lightofs = in->lightofs;
}
Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata,
out, in->styles, lightofs);
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes,
loadmodel->edges, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
}
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
static void
Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
@ -505,7 +633,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
if ((header->ident == IDBSPHEADER) ||
(header->ident == RBSPHEADER))
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
if (maptype == map_sin)
{
Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
else
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
}
}
else
{