Merge branch 'indexbuffer'

# Conflicts:
#	src/gl/data/gl_vertexbuffer.h
#	src/gl/scene/gl_flats.cpp
#	src/hwrenderer/data/flatvertices.h
This commit is contained in:
Christoph Oelckers 2018-05-22 22:10:21 +02:00
commit b612e182b4
19 changed files with 211 additions and 45 deletions

View file

@ -588,6 +588,7 @@ bool FDrawInfo::PutFlatCompat(GLFlat *flat, bool fog)
int list = list_indices[masked][foggy]; int list = list_indices[masked][foggy];
auto newflat = dldrawlists[list].NewFlat(); auto newflat = dldrawlists[list].NewFlat();
*newflat = *flat; *newflat = *flat;
newflat->vboindex = -1; // don't use the vertex buffer with legacy lights to ensure all passes use the same render logic.
return true; return true;
} }

View file

@ -125,6 +125,8 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
: FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height) : FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height)
{ {
ibo_id = 0;
if (gl.buffermethod != BM_LEGACY) glGenBuffers(1, &ibo_id);
switch (gl.buffermethod) switch (gl.buffermethod)
{ {
case BM_PERSISTENT: case BM_PERSISTENT:
@ -171,6 +173,11 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
if (ibo_id != 0)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ibo_id);
}
if (gl.legacyMode) if (gl.legacyMode)
{ {
delete[] map; delete[] map;
@ -189,6 +196,7 @@ void FFlatVertexBuffer::OutputResized(int width, int height)
void FFlatVertexBuffer::BindVBO() void FFlatVertexBuffer::BindVBO()
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
if (!gl.legacyMode) if (!gl.legacyMode)
{ {
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
@ -246,4 +254,9 @@ void FFlatVertexBuffer::CreateVBO()
Map(); Map();
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
Unmap(); Unmap();
if (ibo_id > 0)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo_data.Size() * sizeof(uint32_t), &ibo_data[0], GL_STATIC_DRAW);
}
} }

View file

@ -95,6 +95,7 @@ public:
class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator
{ {
unsigned int ibo_id;
FFlatVertex *map; FFlatVertex *map;
unsigned int mIndex; unsigned int mIndex;
std::atomic<unsigned int> mCurIndex; std::atomic<unsigned int> mCurIndex;
@ -177,6 +178,11 @@ public:
#endif #endif
uint32_t *GetIndexPointer() const
{
return ibo_id == 0 ? &ibo_data[0] : nullptr;
}
void Reset() void Reset()
{ {
mCurIndex = mIndex; mCurIndex = mIndex;

View file

@ -62,7 +62,7 @@ static void matrixToGL(const VSMatrix &mat, int loc)
void FRenderState::Reset() void FRenderState::Reset()
{ {
mTextureEnabled = true; mTextureEnabled = true;
mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; mClipLineShouldBeActive = mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true; mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true; currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
mFogColor.d = -1; mFogColor.d = -1;

View file

@ -81,6 +81,7 @@ class FRenderState
bool mGlowEnabled; bool mGlowEnabled;
bool mSplitEnabled; bool mSplitEnabled;
bool mClipLineEnabled; bool mClipLineEnabled;
bool mClipLineShouldBeActive;
bool mBrightmapEnabled; bool mBrightmapEnabled;
bool mColorMask[4]; bool mColorMask[4];
bool currentColorMask[4]; bool currentColorMask[4];
@ -201,6 +202,11 @@ public:
return mClipLineEnabled; return mClipLineEnabled;
} }
bool GetClipLineShouldBeActive()
{
return mClipLineShouldBeActive;
}
void SetClipHeight(float height, float direction); void SetClipHeight(float height, float direction);
void SetNormal(FVector3 norm) void SetNormal(FVector3 norm)
@ -326,6 +332,11 @@ public:
glDisable(GL_CLIP_DISTANCE0); glDisable(GL_CLIP_DISTANCE0);
} }
} }
else
{
// this needs to be flagged because in this case per-sector plane rendering needs to be disabled if a clip plane is active.
mClipLineShouldBeActive = on;
}
} }
void EnableBrightmap(bool on) void EnableBrightmap(bool on)

View file

@ -121,6 +121,7 @@ struct FDrawInfo : public HWDrawInfo
void ProcessLights(GLFlat *flat, bool istrans); void ProcessLights(GLFlat *flat, bool istrans);
void DrawSubsector(GLFlat *flat, subsector_t * sub); void DrawSubsector(GLFlat *flat, subsector_t * sub);
void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli); void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli);
void SetupSectorLights(GLFlat *flat, int pass, int *dli);
// Sprite drawer // Sprite drawer
void DrawSprite(GLSprite *sprite, int pass); void DrawSprite(GLSprite *sprite, int pass);

View file

@ -48,6 +48,8 @@
#include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_scenedrawer.h"
#include "gl/renderer/gl_quaddrawer.h" #include "gl/renderer/gl_quaddrawer.h"
CVAR(Bool, gl_render_subsectors, false, 0)
//========================================================================== //==========================================================================
// //
// Flats // Flats
@ -62,7 +64,35 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub,
(*dli)++; (*dli)++;
return; return;
} }
if (flat->SetupSubsectorLights(pass, sub, lightdata)) if (flat->SetupSectorLights(pass, flat->sector, lightdata))
{
int d = GLRenderer->mLights->UploadLights(lightdata);
if (pass == GLPASS_LIGHTSONLY)
{
GLRenderer->mLights->StoreIndex(d);
}
else
{
gl_RenderState.ApplyLightIndex(d);
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void FDrawInfo::SetupSectorLights(GLFlat *flat, int pass, int *dli)
{
if (dli != NULL && *dli != -1)
{
gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli));
(*dli)++;
return;
}
if (flat->SetupSectorLights(pass, flat->sector, lightdata))
{ {
int d = GLRenderer->mLights->UploadLights(lightdata); int d = GLRenderer->mLights->UploadLights(lightdata);
if (pass == GLPASS_LIGHTSONLY) if (pass == GLPASS_LIGHTSONLY)
@ -137,15 +167,22 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans)
{ {
flat->dynlightindex = GLRenderer->mLights->GetIndexPtr(); flat->dynlightindex = GLRenderer->mLights->GetIndexPtr();
if (flat->sector->ibocount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive())
{
SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr);
}
else
{
// Draw the subsectors belonging to this sector // Draw the subsectors belonging to this sector
for (int i=0; i< flat->sector->subsectorcount; i++) for (int i = 0; i < flat->sector->subsectorcount; i++)
{ {
subsector_t * sub = flat->sector->subsectors[i]; subsector_t * sub = flat->sector->subsectors[i];
if (ss_renderflags[sub->Index()]& flat->renderflags || istrans) if (ss_renderflags[sub->Index()] & flat->renderflags || istrans)
{ {
SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr);
} }
} }
}
// Draw the subsectors assigned to it due to missing textures // Draw the subsectors assigned to it due to missing textures
if (!(flat->renderflags&SSRF_RENDER3DPLANES)) if (!(flat->renderflags&SSRF_RENDER3DPLANES))
@ -175,29 +212,40 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
gl_RenderState.Apply(); gl_RenderState.Apply();
if (gl.legacyMode) processlights = false; if (gl.legacyMode) processlights = false;
if (flat->vboindex >= 0)
auto vcount = flat->sector->ibocount;
if (vcount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive())
{
if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli);
drawcalls.Clock();
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->vboindex);
drawcalls.Unclock();
flatvertices += vcount;
flatprimitives++;
}
else if (flat->vboindex >= 0)
{ {
int index = flat->vboindex; int index = flat->vboindex;
for (int i=0; i<flat->sector->subsectorcount; i++) for (int i=0; i<flat->sector->subsectorcount; i++)
{ {
subsector_t * sub = flat->sector->subsectors[i]; subsector_t * sub = flat->sector->subsectors[i];
if (sub->numlines <= 2) continue;
if (ss_renderflags[sub->Index()]& flat->renderflags || istrans) if (ss_renderflags[sub->Index()]& flat->renderflags || istrans)
{ {
if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli); if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli);
drawcalls.Clock(); drawcalls.Clock();
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
drawcalls.Unclock(); drawcalls.Unclock();
flatvertices += sub->numlines; flatvertices += sub->numlines;
flatprimitives++; flatprimitives++;
} }
index += sub->numlines; index += (sub->numlines - 2) * 3;
} }
} }
else else
{ {
// Draw the subsectors belonging to this sector // Draw the subsectors belonging to this sector
// (can this case even happen?)
for (int i=0; i<flat->sector->subsectorcount; i++) for (int i=0; i<flat->sector->subsectorcount; i++)
{ {
subsector_t * sub = flat->sector->subsectors[i]; subsector_t * sub = flat->sector->subsectors[i];

View file

@ -118,13 +118,22 @@ static F3DFloor *Find3DFloor(sector_t *target, sector_t *model)
// //
//========================================================================== //==========================================================================
int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor) int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen)
{ {
int idx = vbo_shadowdata.Reserve(sub->numlines); if (sub->numlines < 3) return -1;
for(unsigned int k=0; k<sub->numlines; k++, idx++)
int idx = ibo_data.Reserve((sub->numlines - 2) * 3);
int idxc = idx;
int firstndx = gen.GetIndex(sub->firstline[0].v1);
int secondndx = gen.GetIndex(sub->firstline[1].v1);
for (unsigned int k = 2; k<sub->numlines; k++)
{ {
vbo_shadowdata[idx].SetFlatVertex(sub->firstline[k].v1, plane); auto ndx = gen.GetIndex(sub->firstline[k].v1);
if (sub->sector->transdoor && floor) vbo_shadowdata[idx].z -= 1.f;
ibo_data[idx++] = vi + firstndx;
ibo_data[idx++] = vi + secondndx;
ibo_data[idx++] = vi + ndx;
secondndx = ndx;
} }
return idx; return idx;
} }
@ -135,15 +144,28 @@ int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secpla
// //
//========================================================================== //==========================================================================
int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor) int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FFlatVertexGenerator::FIndexGenerationInfo &gen)
{ {
int rt = vbo_shadowdata.Size(); int rt = ibo_data.Size();
// First calculate the vertices for the sector itself int vi = vbo_shadowdata.Reserve(gen.vertices.Size());
for(int j=0; j<sec->subsectorcount; j++) float diff;
// Create the actual vertices.
if (sec->transdoor && floor) diff = -1.f;
else diff = 0.f;
for (unsigned i = 0; i < gen.vertices.Size(); i++)
{
vbo_shadowdata[vi + i].SetFlatVertex(gen.vertices[i], plane);
vbo_shadowdata[vi + i].z += diff;
}
// Create the indices for the subsectors
for (int j = 0; j<sec->subsectorcount; j++)
{ {
subsector_t *sub = sec->subsectors[j]; subsector_t *sub = sec->subsectors[j];
CreateSubsectorVertices(sub, plane, floor); CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen);
} }
sec->ibocount = ibo_data.Size() - rt;
return rt; return rt;
} }
@ -153,23 +175,23 @@ int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &
// //
//========================================================================== //==========================================================================
int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor) int FFlatVertexGenerator::CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FFlatVertexGenerator::FIndexGenerationInfo> &gen)
{ {
// First calculate the vertices for the sector itself // First calculate the vertices for the sector itself
sec->vboheight[h] = sec->GetPlaneTexZ(h); sec->vboheight[h] = sec->GetPlaneTexZ(h);
sec->vboindex[h] = CreateSectorVertices(sec, plane, floor); sec->vboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]);
// Next are all sectors using this one as heightsec // Next are all sectors using this one as heightsec
TArray<sector_t *> &fakes = sec->e->FakeFloor.Sectors; TArray<sector_t *> &fakes = sec->e->FakeFloor.Sectors;
for (unsigned g=0; g<fakes.Size(); g++) for (unsigned g = 0; g<fakes.Size(); g++)
{ {
sector_t *fsec = fakes[g]; sector_t *fsec = fakes[g];
fsec->vboindex[2+h] = CreateSectorVertices(fsec, plane, false); fsec->vboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
} }
// and finally all attached 3D floors // and finally all attached 3D floors
TArray<sector_t *> &xf = sec->e->XFloor.attached; TArray<sector_t *> &xf = sec->e->XFloor.attached;
for (unsigned g=0; g<xf.Size(); g++) for (unsigned g = 0; g<xf.Size(); g++)
{ {
sector_t *fsec = xf[g]; sector_t *fsec = xf[g];
F3DFloor *ffloor = Find3DFloor(fsec, sec); F3DFloor *ffloor = Find3DFloor(fsec, sec);
@ -181,10 +203,9 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t
if (dotop || dobottom) if (dotop || dobottom)
{ {
if (dotop) ffloor->top.vindex = vbo_shadowdata.Size(); auto ndx = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size(); if (dotop) ffloor->top.vindex = ndx;
if (dobottom) ffloor->bottom.vindex = ndx;
CreateSectorVertices(fsec, plane, false);
} }
} }
} }
@ -199,13 +220,28 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t
// //
//========================================================================== //==========================================================================
void FFlatVertexGenerator::CreateFlatVertices() void FFlatVertexGenerator::CreateIndexedFlatVertices()
{ {
TArray<FIndexGenerationInfo> gen;
gen.Resize(level.sectors.Size());
// This must be generated up front so that the following code knows how many vertices a sector contains.
for (unsigned i = 0; i < level.sectors.Size(); i++)
{
for (int j = 0; j < level.sectors[i].subsectorcount; j++)
{
auto sub = level.sectors[i].subsectors[j];
for (unsigned k = 0; k < sub->numlines; k++)
{
auto vert = sub->firstline[k].v1;
gen[i].AddVertex(vert);
}
}
}
for (int h = sector_t::floor; h <= sector_t::ceiling; h++) for (int h = sector_t::floor; h <= sector_t::ceiling; h++)
{ {
for(auto &sec : level.sectors) for (auto &sec : level.sectors)
{ {
CreateVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor); CreateIndexedVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor, gen);
} }
} }
@ -213,7 +249,7 @@ void FFlatVertexGenerator::CreateFlatVertices()
// No new vertices are needed here. The planes come from the actual sector // No new vertices are needed here. The planes come from the actual sector
for (auto &sec : level.sectors) for (auto &sec : level.sectors)
{ {
for(auto ff : sec.e->XFloor.ffloors) for (auto ff : sec.e->XFloor.ffloors)
{ {
if (ff->top.model == &sec) if (ff->top.model == &sec)
{ {
@ -257,7 +293,7 @@ void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane)
void FFlatVertexGenerator::CreateVertices() void FFlatVertexGenerator::CreateVertices()
{ {
vbo_shadowdata.Resize(NUM_RESERVED); vbo_shadowdata.Resize(NUM_RESERVED);
CreateFlatVertices(); CreateIndexedFlatVertices();
} }
//========================================================================== //==========================================================================

View file

@ -45,8 +45,32 @@ class FFlatVertexGenerator
{ {
protected: protected:
TArray<FFlatVertex> vbo_shadowdata; TArray<FFlatVertex> vbo_shadowdata;
TArray<uint32_t> ibo_data;
FFlatVertex *mMap; FFlatVertex *mMap;
// Temporary data for creating an indexed buffer
struct FIndexGenerationInfo
{
TArray<vertex_t *> vertices;
TMap<vertex_t*, uint32_t> vertexmap;
uint32_t AddVertex(vertex_t *vert)
{
auto check = vertexmap.CheckKey(vert);
if (check != nullptr) return *check;
auto index = vertices.Push(vert);
vertexmap[vert] = index;
return index;
}
uint32_t GetIndex(vertex_t *vert)
{
auto check = vertexmap.CheckKey(vert);
if (check != nullptr) return *check;
return ~0;
}
};
public: public:
enum enum
@ -65,10 +89,11 @@ public:
void OutputResized(int width, int height); void OutputResized(int width, int height);
private: private:
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); int CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FIndexGenerationInfo &gen);
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); int CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FIndexGenerationInfo &gen);
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); int CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FIndexGenerationInfo> &gen);
void CreateFlatVertices(); void CreateIndexedFlatVertices();
void UpdatePlaneVertices(sector_t *sec, int plane); void UpdatePlaneVertices(sector_t *sec, int plane);
protected: protected:
void CreateVertices(); void CreateVertices();

View file

@ -311,7 +311,9 @@ public:
int dynlightindex; int dynlightindex;
bool SetupLights(int pass, FLightNode *head, FDynLightData &lightdata, int portalgroup);
bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata); bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata);
bool SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata);
void PutFlat(HWDrawInfo *di, bool fog = false); void PutFlat(HWDrawInfo *di, bool fog = false);
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture); void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);

View file

@ -92,14 +92,13 @@ bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
// //
//========================================================================== //==========================================================================
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata) bool GLFlat::SetupLights(int pass, FLightNode * node, FDynLightData &lightdata, int portalgroup)
{ {
Plane p; Plane p;
if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return false; // no lights on additively blended surfaces. if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return false; // no lights on additively blended surfaces.
lightdata.Clear(); lightdata.Clear();
FLightNode * node = sub->lighthead;
while (node) while (node)
{ {
ADynamicLight * light = node->lightsource; ADynamicLight * light = node->lightsource;
@ -121,13 +120,23 @@ bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &li
} }
p.Set(plane.plane.Normal(), plane.plane.fD()); p.Set(plane.plane.Normal(), plane.plane.fD());
lightdata.GetLight(sub->sector->PortalGroup, p, light, false); lightdata.GetLight(portalgroup, p, light, false);
node = node->nextLight; node = node->nextLight;
} }
return true; return true;
} }
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
{
return SetupLights(pass, sub->lighthead, lightdata, sub->sector->PortalGroup);
}
bool GLFlat::SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata)
{
return SetupLights(pass, sec->lighthead, lightdata, sec->PortalGroup);
}
//========================================================================== //==========================================================================
// //
// GLFlat::PutFlat // GLFlat::PutFlat

View file

@ -1090,6 +1090,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
{ {
subsector_t *sub = HandledSubsectors[j]; subsector_t *sub = HandledSubsectors[j];
ss_renderflags[sub->Index()] &= ~SSRF_RENDERCEILING; ss_renderflags[sub->Index()] &= ~SSRF_RENDERCEILING;
sub->sector->ibocount = -1; // cannot render this sector in one go.
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
{ {
@ -1135,6 +1136,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
{ {
subsector_t *sub = HandledSubsectors[j]; subsector_t *sub = HandledSubsectors[j];
ss_renderflags[sub->Index()] &= ~SSRF_RENDERFLOOR; ss_renderflags[sub->Index()] &= ~SSRF_RENDERFLOOR;
sub->sector->ibocount = -1; // cannot render this sector in one go.
if (sub->portalcoverage[sector_t::floor].subsectors == NULL) if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
{ {

View file

@ -120,6 +120,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag
ffloor->top.copied = ffloor->bottom.copied = false; ffloor->top.copied = ffloor->bottom.copied = false;
ffloor->top.model = ffloor->bottom.model = ffloor->model = sec2; ffloor->top.model = ffloor->bottom.model = ffloor->model = sec2;
ffloor->target = sec; ffloor->target = sec;
ffloor->top.vindex = ffloor->bottom.vindex = -1;
if (!(flags&FF_THINFLOOR)) if (!(flags&FF_THINFLOOR))
{ {

View file

@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
ss->friction = ORIG_FRICTION; ss->friction = ORIG_FRICTION;
ss->movefactor = ORIG_FRICTION_FACTOR; ss->movefactor = ORIG_FRICTION_FACTOR;
ss->sectornum = i; ss->sectornum = i;
ss->ibocount = -1;
} }
delete[] msp; delete[] msp;
} }

View file

@ -1383,6 +1383,7 @@ public:
sec->sectornum = index; sec->sectornum = index;
sec->damageinterval = 32; sec->damageinterval = 32;
sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1; sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
sec->ibocount = -1;
memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors)); memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors));
if (floordrop) sec->Flags = SECF_FLOORDROP; if (floordrop) sec->Flags = SECF_FLOORDROP;
// killough 3/7/98: end changes // killough 3/7/98: end changes

View file

@ -1087,9 +1087,10 @@ public:
vbo_fakeceiling = ceiling+2, vbo_fakeceiling = ceiling+2,
}; };
int vboindex[4]; // VBO indices of the 4 planes this sector uses during rendering int vboindex[4]; // VBO/IBO indices of the 4 planes this sector uses during rendering
double vboheight[2]; // Last calculated height for the 2 planes of this actual sector double vboheight[2]; // Last calculated height for the 2 planes of this actual sector
int vbocount[2]; // Total count of vertices belonging to this sector's planes int vbocount[2]; // Total count of vertices belonging to this sector's planes. This is used when a sector height changes and also contains all attached planes.
int ibocount; // number of indices per plane (identical for all planes.) If this is -1 the index buffer is not in use.
float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; } float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; }
bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); }

View file

@ -1159,10 +1159,15 @@ bool SystemFrameBuffer::IsFullscreen()
// //
// //
//========================================================================== //==========================================================================
EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
vid_vsync.Callback();
}
void SystemFrameBuffer::SetVSync (bool vsync) void SystemFrameBuffer::SetVSync (bool vsync)
{ {
if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0); if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? (gl_control_tear? SwapInterval : 1) : 0);
} }
void SystemFrameBuffer::SwapBuffers() void SystemFrameBuffer::SwapBuffers()

View file

@ -9,6 +9,10 @@ vec3 lightContribution(int i, vec3 normal)
float lightdistance = distance(lightpos.xyz, pixelpos.xyz); float lightdistance = distance(lightpos.xyz, pixelpos.xyz);
if (lightpos.w < lightdistance) if (lightpos.w < lightdistance)
return vec3(0.0); // Early out lights touching surface but not this fragment return vec3(0.0); // Early out lights touching surface but not this fragment
vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz);
float dotprod = dot(normal, lightdir);
if (dotprod < 0.0) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases.
float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0); float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
@ -17,8 +21,7 @@ vec3 lightContribution(int i, vec3 normal)
if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag
{ {
vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz); attenuation *= clamp(dotprod, 0.0, 1.0);
attenuation *= clamp(dot(normal, lightdir), 0.0, 1.0);
} }
if (attenuation > 0.0) // Skip shadow map test if possible if (attenuation > 0.0) // Skip shadow map test if possible

View file

@ -12,7 +12,7 @@ struct SBarInfo native ui
} }
// The sole purpose of this wrapper is to elimintate the native dependencies of the status bar object // The sole purpose of this wrapper is to eliminate the native dependencies of the status bar object
// because those would seriously impede the script conversion of the base class. // because those would seriously impede the script conversion of the base class.
class SBarInfoWrapper : BaseStatusBar class SBarInfoWrapper : BaseStatusBar