mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
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:
commit
b612e182b4
19 changed files with 211 additions and 45 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue