mirror of
https://github.com/DrBeef/Raze.git
synced 2025-02-18 18:01:33 +00:00
- added wall edge splitting for gl_seamless.
This commit is contained in:
parent
f7e7476010
commit
b1d8f92ded
7 changed files with 226 additions and 48 deletions
|
@ -1062,6 +1062,7 @@ set (PCH_SOURCES
|
|||
core/rendering/hw_vertexmap.cpp
|
||||
core/rendering/scene/hw_clipper.cpp
|
||||
core/rendering/scene/hw_walls.cpp
|
||||
core/rendering/scene/hw_walls_vertex.cpp
|
||||
core/rendering/scene/hw_flats.cpp
|
||||
core/rendering/scene/hw_sprites.cpp
|
||||
core/rendering/scene/hw_drawlistadd.cpp
|
||||
|
|
|
@ -98,8 +98,8 @@ static void ReadSectorV7(FileReader& fr, sectortype& sect)
|
|||
{
|
||||
sect.wallptr = fr.ReadInt16();
|
||||
sect.wallnum = fr.ReadInt16();
|
||||
sect.setceilingz(fr.ReadInt32());
|
||||
sect.setfloorz(fr.ReadInt32());
|
||||
sect.setceilingz(fr.ReadInt32(), true);
|
||||
sect.setfloorz(fr.ReadInt32(), true);
|
||||
sect.ceilingstat = ESectorFlags::FromInt(fr.ReadUInt16());
|
||||
sect.floorstat = ESectorFlags::FromInt(fr.ReadUInt16());
|
||||
sect.ceilingpicnum = fr.ReadUInt16();
|
||||
|
@ -129,8 +129,8 @@ static void ReadSectorV6(FileReader& fr, sectortype& sect)
|
|||
sect.floorpicnum = fr.ReadUInt16();
|
||||
sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
sect.floorheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
sect.setceilingz(fr.ReadInt32());
|
||||
sect.setfloorz(fr.ReadInt32());
|
||||
sect.setceilingz(fr.ReadInt32(), true);
|
||||
sect.setfloorz(fr.ReadInt32(), true);
|
||||
sect.ceilingshade = fr.ReadInt8();
|
||||
sect.floorshade = fr.ReadInt8();
|
||||
sect.ceilingxpan_ = fr.ReadUInt8();
|
||||
|
@ -156,8 +156,8 @@ static void ReadSectorV5(FileReader& fr, sectortype& sect)
|
|||
sect.floorpicnum = fr.ReadUInt16();
|
||||
sect.ceilingheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
sect.floorheinum = clamp(fr.ReadInt16() << 5, -32768, 32767);
|
||||
sect.setceilingz(fr.ReadInt32());
|
||||
sect.setfloorz(fr.ReadInt32());
|
||||
sect.setceilingz(fr.ReadInt32(), true);
|
||||
sect.setfloorz(fr.ReadInt32(), true);
|
||||
sect.ceilingshade = fr.ReadInt8();
|
||||
sect.floorshade = fr.ReadInt8();
|
||||
sect.ceilingxpan_ = fr.ReadUInt8();
|
||||
|
|
|
@ -33,13 +33,12 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include "basics.h"
|
||||
#include "maptypes.h"
|
||||
#include "memarena.h"
|
||||
#include "gamefuncs.h"
|
||||
#include "hw_vertexmap.h"
|
||||
|
||||
extern FMemArena sectionArena; // allocate from the same arena as the section as the data here has the same lifetime.
|
||||
extern FMemArena sectionArena; // allocate from the same arena as the sections as the data here has the same lifetime.
|
||||
|
||||
TArray<int> vertexMap; // maps walls to the vertex data.
|
||||
TArray<vertex_t> vertices;
|
||||
|
@ -59,6 +58,7 @@ void CreateVertexMap()
|
|||
verticespersector.Resize(sector.Size());
|
||||
|
||||
for (auto& c : countpersector) c = 0;
|
||||
for (auto& c : vertexMap) c = -1;
|
||||
for (unsigned i = 0; i < wall.Size(); i++)
|
||||
{
|
||||
if (processed[i]) continue;
|
||||
|
@ -78,7 +78,7 @@ void CreateVertexMap()
|
|||
}
|
||||
});
|
||||
|
||||
vertices.Reserve(1);
|
||||
unsigned index = vertices.Reserve(1);
|
||||
auto newvert = &vertices.Last();
|
||||
|
||||
newvert->masterwall = walls[0];
|
||||
|
@ -87,6 +87,11 @@ void CreateVertexMap()
|
|||
newvert->dirty = true;
|
||||
newvert->numheights = 0;
|
||||
|
||||
for (auto w : walls)
|
||||
{
|
||||
vertexMap[w] = index;
|
||||
}
|
||||
|
||||
// allocate all data within this struct from the arena to simplify memory management.
|
||||
auto sect = (int*)sectionArena.Alloc(sectors.Size() * sizeof(int));
|
||||
newvert->sectors.Set(sect, sectors.Size());
|
||||
|
|
|
@ -223,7 +223,11 @@ public:
|
|||
|
||||
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
|
||||
|
||||
//int CountVertices();
|
||||
int CountVertices();
|
||||
void SplitLeftEdge(FFlatVertex*& ptr);
|
||||
void SplitRightEdge(FFlatVertex*& ptr);
|
||||
void CountLeftEdge(unsigned& ptr);
|
||||
void CountRightEdge(unsigned& ptr);
|
||||
|
||||
void RenderWall(HWDrawInfo *di, FRenderState &state, int textured);
|
||||
void RenderFogBoundary(HWDrawInfo *di, FRenderState &state);
|
||||
|
|
|
@ -133,42 +133,6 @@ static int IsOnWall(tspritetype* tspr, int height)
|
|||
return closest == nullptr? -1 : dist;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Create vertices for one wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int HWWall::CreateVertices(FFlatVertex*& ptr, bool split)
|
||||
{
|
||||
auto oo = ptr;
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
|
||||
ptr++;
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
|
||||
ptr++;
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
|
||||
ptr++;
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
|
||||
ptr++;
|
||||
return int(ptr - oo);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// build the vertices for this wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::MakeVertices(HWDrawInfo* di, bool nosplit)
|
||||
{
|
||||
if (vertcount == 0)
|
||||
{
|
||||
auto ret = screen->mVertexData->AllocVertices(4);
|
||||
vertindex = ret.second;
|
||||
vertcount = CreateVertices(ret.first, false);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// General purpose wall rendering function
|
||||
|
|
204
source/core/rendering/scene/hw_walls_vertex.cpp
Normal file
204
source/core/rendering/scene/hw_walls_vertex.cpp
Normal file
|
@ -0,0 +1,204 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2006-2022 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "basics.h"
|
||||
#include "maptypes.h"
|
||||
#include "memarena.h"
|
||||
#include "gamefuncs.h"
|
||||
#include "v_video.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_vertexmap.h"
|
||||
#include "hw_drawstructs.h"
|
||||
|
||||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split left edge of wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitLeftEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == nullptr) return;
|
||||
vertex_t* vi = &vertices[vertexMap[wallnum(seg)]];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
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;
|
||||
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
{
|
||||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
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++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split right edge of wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SplitRightEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == nullptr) return;
|
||||
vertex_t* vi = &vertices[vertexMap[seg->point2]];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i = vi->numheights - 1;
|
||||
|
||||
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;
|
||||
|
||||
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
|
||||
while (i>0 && vi->heightlist[i] > zbottom[1])
|
||||
{
|
||||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
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++;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Create vertices for one wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int HWWall::CreateVertices(FFlatVertex *&ptr, bool split)
|
||||
{
|
||||
auto oo = ptr;
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
|
||||
ptr++;
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(ptr);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
|
||||
ptr++;
|
||||
return int(ptr - oo);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split left edge of wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::CountLeftEdge(unsigned &ptr)
|
||||
{
|
||||
vertex_t* vi = &vertices[vertexMap[wallnum(seg)]];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
{
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Split right edge of wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::CountRightEdge(unsigned &ptr)
|
||||
{
|
||||
vertex_t* vi = &vertices[vertexMap[seg->point2]];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i = vi->numheights - 1;
|
||||
|
||||
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
|
||||
while (i>0 && vi->heightlist[i] > zbottom[1])
|
||||
{
|
||||
ptr++;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int HWWall::CountVertices()
|
||||
{
|
||||
unsigned ptr = 4;
|
||||
if (seg)
|
||||
{
|
||||
if (glseg.fracleft == 0) CountLeftEdge(ptr);
|
||||
if (glseg.fracright == 1) CountRightEdge(ptr);
|
||||
}
|
||||
return (int)ptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// build the vertices for this wall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::MakeVertices(HWDrawInfo *di, bool nosplit)
|
||||
{
|
||||
if (vertcount == 0)
|
||||
{
|
||||
bool split = (gl_seamless && !nosplit && seg != nullptr);
|
||||
auto ret = screen->mVertexData->AllocVertices(split ? CountVertices() : 4);
|
||||
vertindex = ret.second;
|
||||
vertcount = CreateVertices(ret.first, split);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,8 +253,8 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
|
|||
}
|
||||
pSector->wallptr = LittleShort(load.wallptr);
|
||||
pSector->wallnum = LittleShort(load.wallnum);
|
||||
pSector->setceilingz(LittleLong(load.ceilingz));
|
||||
pSector->setfloorz(LittleLong(load.floorz));
|
||||
pSector->setceilingz(LittleLong(load.ceilingz), true);
|
||||
pSector->setfloorz(LittleLong(load.floorz), true);
|
||||
pSector->ceilingstat = ESectorFlags::FromInt(LittleShort(load.ceilingstat));
|
||||
pSector->floorstat = ESectorFlags::FromInt(LittleShort(load.floorstat));
|
||||
pSector->ceilingpicnum = LittleShort(load.ceilingpicnum);
|
||||
|
|
Loading…
Reference in a new issue