mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- implement drawing sides with lightmaps
- misc bug fixes in lump loading and format
This commit is contained in:
parent
2f8cff90b6
commit
3f3769afdb
6 changed files with 77 additions and 41 deletions
|
@ -1219,6 +1219,7 @@ struct side_t
|
|||
uint16_t Flags;
|
||||
int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order.
|
||||
FLightNode * lighthead; // all dynamic lights that may affect this wall
|
||||
LightmapSurface *lightmap[4];
|
||||
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
|
||||
int numsegs;
|
||||
int sidenum;
|
||||
|
@ -1461,8 +1462,6 @@ struct line_t
|
|||
int healthgroup; // [ZZ] this is the "destructible object" id
|
||||
int linenum;
|
||||
|
||||
LightmapSurface *lightmap[4];
|
||||
|
||||
DVector2 Delta() const
|
||||
{
|
||||
return delta;
|
||||
|
@ -1682,7 +1681,7 @@ struct LightmapSurface
|
|||
{
|
||||
SurfaceType Type;
|
||||
subsector_t *Subsector;
|
||||
line_t *Line;
|
||||
side_t *Side;
|
||||
sector_t *ControlSector;
|
||||
uint32_t LightmapNum;
|
||||
float *TexCoords;
|
||||
|
|
|
@ -3292,7 +3292,7 @@ void MapLoader::SetSubsectorLightmap(const LightmapSurface &surface)
|
|||
}
|
||||
}
|
||||
|
||||
void MapLoader::SetLineLightmap(const LightmapSurface &surface)
|
||||
void MapLoader::SetSideLightmap(const LightmapSurface &surface)
|
||||
{
|
||||
int index = 0;
|
||||
switch (surface.Type)
|
||||
|
@ -3305,16 +3305,16 @@ void MapLoader::SetLineLightmap(const LightmapSurface &surface)
|
|||
|
||||
if (!surface.ControlSector)
|
||||
{
|
||||
surface.Line->lightmap[index][0] = surface;
|
||||
surface.Side->lightmap[index][0] = surface;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& ffloors = surface.Line->frontsector->e->XFloor.ffloors;
|
||||
const auto &ffloors = surface.Side->sector->e->XFloor.ffloors;
|
||||
for (unsigned int i = 0; i < ffloors.Size(); i++)
|
||||
{
|
||||
if (ffloors[i]->model == surface.ControlSector)
|
||||
{
|
||||
surface.Line->lightmap[index][i + 1] = surface;
|
||||
surface.Side->lightmap[index][i + 1] = surface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3337,7 +3337,7 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
uint16_t numTextures = fr.ReadUInt16();
|
||||
uint32_t numSurfaces = fr.ReadUInt32();
|
||||
uint32_t numTexCoords = fr.ReadUInt32();
|
||||
uint32_t numTexBytes = numSurfaces * numTextures * textureSize * 2;
|
||||
uint32_t numTexBytes = numTextures * textureSize * textureSize * 3 * 2;
|
||||
|
||||
if (numSurfaces == 0 || numTexCoords == 0 || numTexBytes == 0)
|
||||
return;
|
||||
|
@ -3348,8 +3348,8 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
|
||||
unsigned int allSurfaces = 0;
|
||||
|
||||
for (unsigned int i = 0; i < Level->lines.Size(); i++)
|
||||
allSurfaces += 3 + Level->lines[i].frontsector->e->XFloor.ffloors.Size() * 3;
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
allSurfaces += 3 + Level->sides[i].sector->e->XFloor.ffloors.Size() * 3;
|
||||
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
allSurfaces += 2 + Level->subsectors[i].sector->e->XFloor.ffloors.Size() * 2;
|
||||
|
@ -3357,17 +3357,17 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
Level->LMSurfaces.Resize(allSurfaces);
|
||||
memset(&Level->LMSurfaces[0], 0, sizeof(LightmapSurface) * allSurfaces);
|
||||
|
||||
// Link the surfaces to sectors, lines and their 3D floors
|
||||
// Link the surfaces to sectors, sides and their 3D floors
|
||||
|
||||
unsigned int offset = 0;
|
||||
for (unsigned int i = 0; i < Level->lines.Size(); i++)
|
||||
for (unsigned int i = 0; i < Level->sides.Size(); i++)
|
||||
{
|
||||
auto& line = Level->lines[i];
|
||||
unsigned int count = 1 + line.frontsector->e->XFloor.ffloors.Size();
|
||||
line.lightmap[0] = &Level->LMSurfaces[offset];
|
||||
line.lightmap[1] = &Level->LMSurfaces[offset + count];
|
||||
line.lightmap[2] = line.lightmap[1];
|
||||
line.lightmap[3] = &Level->LMSurfaces[offset + count * 2];
|
||||
auto& side = Level->sides[i];
|
||||
unsigned int count = 1 + side.sector->e->XFloor.ffloors.Size();
|
||||
side.lightmap[0] = &Level->LMSurfaces[offset];
|
||||
side.lightmap[1] = &Level->LMSurfaces[offset + count];
|
||||
side.lightmap[2] = side.lightmap[1];
|
||||
side.lightmap[3] = &Level->LMSurfaces[offset + count * 2];
|
||||
offset += count * 3;
|
||||
}
|
||||
for (unsigned int i = 0; i < Level->subsectors.Size(); i++)
|
||||
|
@ -3397,7 +3397,7 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
|
||||
surface.Type = type;
|
||||
surface.LightmapNum = lightmapNum;
|
||||
surface.TexCoords = &Level->LMTexCoords[firstTexCoord];
|
||||
surface.TexCoords = &Level->LMTexCoords[firstTexCoord * 2];
|
||||
|
||||
if (type == ST_CEILING || type == ST_FLOOR)
|
||||
{
|
||||
|
@ -3407,8 +3407,8 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
}
|
||||
else if (type != ST_NULL)
|
||||
{
|
||||
surface.Line = &Level->lines[typeIndex];
|
||||
SetLineLightmap(surface);
|
||||
surface.Side = &Level->sides[typeIndex];
|
||||
SetSideLightmap(surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3423,6 +3423,9 @@ void MapLoader::LoadLightmap(MapData *map)
|
|||
Level->LMTextureData.Resize(numTexBytes);
|
||||
uint8_t* data = &Level->LMTextureData[0];
|
||||
fr.Read(data, numTexBytes);
|
||||
#if 0
|
||||
// Apply compression predictor
|
||||
for (uint32_t i = 1; i < numTexBytes; i++)
|
||||
data[i] += data[i - 1];
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ public:
|
|||
void CopySlopes();
|
||||
|
||||
void SetSubsectorLightmap(const LightmapSurface &surface);
|
||||
void SetLineLightmap(const LightmapSurface &surface);
|
||||
void SetSideLightmap(const LightmapSurface &surface);
|
||||
void LoadLightmap(MapData *map);
|
||||
|
||||
void LoadLevel(MapData *map, const char *lumpname, int position);
|
||||
|
|
|
@ -242,7 +242,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec,
|
|||
int lindex = lightmap->LightmapNum;
|
||||
for (unsigned int j = 0; j < sub->numlines; j++)
|
||||
{
|
||||
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline->v1, plane, luvs[j * 2], luvs[j * 2 + 1], lindex);
|
||||
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane, luvs[j * 2], luvs[j * 2 + 1], lindex);
|
||||
vbo_shadowdata[vi + pos].z += diff;
|
||||
pos++;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec,
|
|||
{
|
||||
for (unsigned int j = 0; j < sub->numlines; j++)
|
||||
{
|
||||
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline->v1, plane);
|
||||
SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane);
|
||||
vbo_shadowdata[vi + pos].z += diff;
|
||||
pos++;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ static int CreateIndexedSectorVerticesLM(FFlatVertexBuffer* fvb, sector_t* sec,
|
|||
}
|
||||
|
||||
// Create the indices for the subsectors
|
||||
for (int i = 0; i < sec->subsectorcount; i++)
|
||||
for (i = 0, pos = 0; i < sec->subsectorcount; i++)
|
||||
{
|
||||
subsector_t* sub = sec->subsectors[i];
|
||||
int firstndx = vi + pos;
|
||||
|
|
|
@ -255,10 +255,10 @@ public:
|
|||
void ProcessDecals(HWDrawInfo *di);
|
||||
|
||||
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
|
||||
void SplitLeftEdge (FFlatVertex *&ptr);
|
||||
void SplitRightEdge(FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(FFlatVertex *&ptr);
|
||||
void SplitLeftEdge (FFlatVertex *&ptr, float *lightuv, float lindex);
|
||||
void SplitRightEdge(FFlatVertex *&ptr, float *lightuv, float lindex);
|
||||
void SplitUpperEdge(FFlatVertex *&ptr, float *lightuv, float lindex);
|
||||
void SplitLowerEdge(FFlatVertex *&ptr, float *lightuv, float lindex);
|
||||
|
||||
void CountLeftEdge (unsigned &ptr);
|
||||
void CountRightEdge(unsigned &ptr);
|
||||
|
|
|
@ -34,7 +34,7 @@ EXTERN_CVAR(Bool, gl_seamless)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitUpperEdge(FFlatVertex *&ptr)
|
||||
void HWWall::SplitUpperEdge(FFlatVertex *&ptr, float *lightuv, float lindex)
|
||||
{
|
||||
side_t *sidedef = seg->sidedef;
|
||||
float polyw = glseg.fracright - glseg.fracleft;
|
||||
|
@ -43,6 +43,8 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr)
|
|||
float fact = (ztop[1] - ztop[0]) / polyw;
|
||||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
float faclu = (lightuv[UPRGT * 2] - lightuv[UPLFT * 2]) / polyw;
|
||||
float faclv = (lightuv[UPRGT * 2 + 1] - lightuv[UPLFT * 2 + 1]) / polyw;
|
||||
|
||||
for (int i = 0; i < sidedef->numsegs - 1; i++)
|
||||
{
|
||||
|
@ -58,6 +60,9 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr)
|
|||
ptr->z = ztop[0] + fact * fracfac;
|
||||
ptr->u = tcs[UPLFT].u + facu * fracfac;
|
||||
ptr->v = tcs[UPLFT].v + facv * fracfac;
|
||||
ptr->lu = lightuv[UPLFT * 2] + faclu * fracfac;
|
||||
ptr->lv = lightuv[UPLFT * 2 + 1] + faclv * fracfac;
|
||||
ptr->lindex = lindex;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +73,7 @@ void HWWall::SplitUpperEdge(FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitLowerEdge(FFlatVertex *&ptr)
|
||||
void HWWall::SplitLowerEdge(FFlatVertex *&ptr, float *lightuv, float lindex)
|
||||
{
|
||||
side_t *sidedef = seg->sidedef;
|
||||
float polyw = glseg.fracright - glseg.fracleft;
|
||||
|
@ -77,6 +82,8 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr)
|
|||
float facb = (zbottom[1] - zbottom[0]) / polyw;
|
||||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
float faclu = (lightuv[LORGT * 2] - lightuv[LOLFT * 2]) / polyw;
|
||||
float faclv = (lightuv[LORGT * 2 + 1] - lightuv[LOLFT * 2 + 1]) / polyw;
|
||||
|
||||
for (int i = sidedef->numsegs - 2; i >= 0; i--)
|
||||
{
|
||||
|
@ -92,6 +99,9 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr)
|
|||
ptr->z = zbottom[0] + facb * fracfac;
|
||||
ptr->u = tcs[LOLFT].u + facu * fracfac;
|
||||
ptr->v = tcs[LOLFT].v + facv * fracfac;
|
||||
ptr->lu = lightuv[LOLFT * 2] + faclu * fracfac;
|
||||
ptr->lv = lightuv[LOLFT * 2 + 1] + faclv * fracfac;
|
||||
ptr->lindex = lindex;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +112,7 @@ void HWWall::SplitLowerEdge(FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
|
||||
void HWWall::SplitLeftEdge(FFlatVertex *&ptr, float *lightuv, float lindex)
|
||||
{
|
||||
if (vertexes[0] == NULL) return;
|
||||
|
||||
|
@ -115,6 +125,8 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
|
|||
float polyh1 = ztop[0] - zbottom[0];
|
||||
float factv1 = polyh1 ? (tcs[UPLFT].v - tcs[LOLFT].v) / polyh1 : 0;
|
||||
float factu1 = polyh1 ? (tcs[UPLFT].u - tcs[LOLFT].u) / polyh1 : 0;
|
||||
float factlv1 = polyh1 ? (lightuv[UPLFT * 2 + 1] - lightuv[LOLFT * 2 + 1]) / polyh1 : 0;
|
||||
float factlu1 = polyh1 ? (lightuv[UPLFT * 2] - lightuv[LOLFT * 2]) / polyh1 : 0;
|
||||
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
|
@ -124,6 +136,9 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
|
|||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].u;
|
||||
ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].v;
|
||||
ptr->lu = factlu1 * (vi->heightlist[i] - ztop[0]) + lightuv[UPLFT * 2];
|
||||
ptr->lv = factlv1 * (vi->heightlist[i] - ztop[0]) + lightuv[UPLFT * 2 + 1];
|
||||
ptr->lindex = lindex;
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
|
@ -136,7 +151,7 @@ void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitRightEdge(FFlatVertex *&ptr)
|
||||
void HWWall::SplitRightEdge(FFlatVertex *&ptr, float *lightuv, float lindex)
|
||||
{
|
||||
if (vertexes[1] == NULL) return;
|
||||
|
||||
|
@ -149,6 +164,8 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr)
|
|||
float polyh2 = ztop[1] - zbottom[1];
|
||||
float factv2 = polyh2 ? (tcs[UPRGT].v - tcs[LORGT].v) / polyh2 : 0;
|
||||
float factu2 = polyh2 ? (tcs[UPRGT].u - tcs[LORGT].u) / polyh2 : 0;
|
||||
float factlv2 = polyh2 ? (lightuv[UPRGT * 2 + 1] - lightuv[LORGT * 2 + 1]) / polyh2 : 0;
|
||||
float factlu2 = polyh2 ? (lightuv[UPRGT * 2] - lightuv[LORGT * 2]) / polyh2 : 0;
|
||||
|
||||
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
|
||||
while (i>0 && vi->heightlist[i] > zbottom[1])
|
||||
|
@ -158,6 +175,9 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr)
|
|||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].u;
|
||||
ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].v;
|
||||
ptr->lu = factlu2 * (vi->heightlist[i] - ztop[1]) + lightuv[UPRGT * 2];
|
||||
ptr->lv = factlv2 * (vi->heightlist[i] - ztop[1]) + lightuv[UPRGT * 2 + 1];
|
||||
ptr->lindex = lindex;
|
||||
ptr++;
|
||||
i--;
|
||||
}
|
||||
|
@ -170,21 +190,35 @@ void HWWall::SplitRightEdge(FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static float ZeroLightmapUVs[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
int HWWall::CreateVertices(FFlatVertex *&ptr, bool split)
|
||||
{
|
||||
float *lightuv = ZeroLightmapUVs;
|
||||
float lindex = -1.0f;
|
||||
if (seg && seg->sidedef && type >= RENDERWALL_TOP && type <= RENDERWALL_BOTTOM)
|
||||
{
|
||||
LightmapSurface *lightmap = seg->sidedef->lightmap[type - RENDERWALL_TOP];
|
||||
if (lightmap != nullptr && lightmap->Type != ST_NULL)
|
||||
{
|
||||
lightuv = lightmap->TexCoords;
|
||||
lindex = (float)lightmap->LightmapNum;
|
||||
}
|
||||
}
|
||||
|
||||
auto oo = ptr;
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v, lightuv[LOLFT * 2], lightuv[LOLFT * 2 + 1], lindex);
|
||||
ptr++;
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr, lightuv, lindex);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v, lightuv[UPLFT * 2], lightuv[UPLFT * 2 + 1], lindex);
|
||||
ptr++;
|
||||
if (split && !(flags & HWF_NOSPLITUPPER && seg->sidedef->numsegs > 1)) SplitUpperEdge(ptr);
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
|
||||
if (split && !(flags & HWF_NOSPLITUPPER && seg->sidedef->numsegs > 1)) SplitUpperEdge(ptr, lightuv, lindex);
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v, lightuv[UPRGT * 2], lightuv[UPRGT * 2 + 1], lindex);
|
||||
ptr++;
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(ptr);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(ptr, lightuv, lindex);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v, lightuv[LORGT * 2], lightuv[LORGT * 2 + 1], lindex);
|
||||
ptr++;
|
||||
if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr);
|
||||
if (split && !(flags & HWF_NOSPLITLOWER) && seg->sidedef->numsegs > 1) SplitLowerEdge(ptr, lightuv, lindex);
|
||||
return int(ptr - oo);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue