From ebbe52082a97c41bacee6debaea98257968c7fb3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 May 2018 08:44:32 +0200 Subject: [PATCH 01/40] - fixed vr_enable_quadbuffered for real I did not consider that this is an init-only option. So changing the CVAR may not affect game behavior at all. Instead its value must be moved to some globally accessible variable on startup that never gets changed again. --- src/gl/stereo3d/gl_stereo_cvars.cpp | 2 -- src/win32/win32gliface.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gl/stereo3d/gl_stereo_cvars.cpp b/src/gl/stereo3d/gl_stereo_cvars.cpp index c726ef4bb..e826e9a12 100644 --- a/src/gl/stereo3d/gl_stereo_cvars.cpp +++ b/src/gl/stereo3d/gl_stereo_cvars.cpp @@ -33,8 +33,6 @@ #include "gl/stereo3d/gl_interleaved3d.h" #include "version.h" -EXTERN_CVAR(Bool, vr_enable_quadbuffered) - // Set up 3D-specific console variables: CVAR(Int, vr_mode, 0, CVAR_GLOBALCONFIG) diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 875a1a78b..bd4600bb0 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -81,7 +81,6 @@ CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { Printf("You must restart " GAMENAME " to switch quad stereo mode\n"); - screen->enable_quadbuffered = self; } EXTERN_CVAR(Int, vid_refreshrate) @@ -1082,6 +1081,7 @@ SystemFrameBuffer::SystemFrameBuffer(void *hMonitor, int width, int height, int m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma); ReleaseDC(Window, hDC); + enable_quadbuffered = vr_enable_quadbuffered; } //========================================================================== From ab3bacdaf587d0b3fa0911762051ecef648e13a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 May 2018 22:59:30 +0200 Subject: [PATCH 02/40] - added missing files to project. --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0acecbe6a..291961100 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -819,6 +819,8 @@ set( FASTMATH_SOURCES gl/scene/gl_portal.cpp gl/scene/gl_walls_draw.cpp gl_load/gl_load.c + hwrenderer/postprocessing/hw_postprocess_cvars.cpp + hwrenderer/postprocessing/hw_postprocessshader.cpp hwrenderer/dynlights/hw_dynlightdata.cpp hwrenderer/scene/hw_fakeflat.cpp hwrenderer/scene/hw_decal.cpp From 5ec47d8b4f025942c5f36dd570a6483c208e5061 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 08:25:26 +0200 Subject: [PATCH 03/40] - removed some leftover data in sector_t. --- src/r_defs.h | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 49a6d244d..a9e7e57c7 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -979,6 +979,12 @@ public: double CenterFloor() const { return floorplane.ZatPoint(centerspot); } double CenterCeiling() const { return ceilingplane.ZatPoint(centerspot); } + void CopyColors(sector_t *other) + { + memcpy(SpecialColors, other->SpecialColors, sizeof(SpecialColors)); + Colormap = other->Colormap; + } + // [RH] store floor and ceiling planes instead of heights secplane_t floorplane, ceilingplane; @@ -986,26 +992,6 @@ public: PalEntry SpecialColors[5]; FColormap Colormap; -private: - FDynamicColormap *_ColorMap; // [RH] Per-sector colormap - -public: - // just a helper for refactoring - FDynamicColormap *GetColorMap() - { - return _ColorMap; - } - - void CopyColors(sector_t *other) - { - memcpy(SpecialColors, other->SpecialColors, sizeof(SpecialColors)); - Colormap = other->Colormap; - - _ColorMap = other->_ColorMap; - } - - - TObjPtr SoundTarget; short special; From ace5ee3c41dd609dc9a67e496ebb03cc918d2888 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 19 May 2018 13:19:24 +0300 Subject: [PATCH 04/40] - fixed crash after saving a screenshot https://forum.zdoom.org/viewtopic.php?t=60616 --- src/gl/system/gl_framebuffer.cpp | 6 +++--- src/gl/system/gl_framebuffer.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index d83581249..81cbd7eeb 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -470,16 +470,16 @@ void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, int sx = u * viewport.width; int sy = v * viewport.height; int sindex = (sx + sy * viewport.width) * 3; - int dindex = (x + y * w) * 3; + int dindex = (x + (h - y - 1) * w) * 3; ScreenshotBuffer[dindex] = pixels[sindex]; ScreenshotBuffer[dindex + 1] = pixels[sindex + 1]; ScreenshotBuffer[dindex + 2] = pixels[sindex + 2]; } } - pitch = -w*3; + pitch = w * 3; color_type = SS_RGB; - buffer = ScreenshotBuffer + w * 3 * (h - 1); + buffer = ScreenshotBuffer; // Screenshot should not use gamma correction if it was already applied to rendered image EXTERN_CVAR(Bool, fullscreen); diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index a220b0a34..898820cc9 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -64,7 +64,6 @@ public: bool HWGammaActive = false; // Are we using hardware or software gamma? std::shared_ptr mDebug; // Debug API private: - uint8_t *ScreenshotBuffer; // What the name says. This must be maintained because the software renderer can return a locked canvas surface which the caller cannot release. int camtexcount = 0; class Wiper From 9257c9cc0c6bf85b80115dc0035a8d1c9c0c44c9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 19 May 2018 13:28:53 +0300 Subject: [PATCH 05/40] - fixed compilation warnings reported by GCC/Clang src/r_data/models/models.cpp:418:33: warning: comparison of integers of different signs: 'long' and 'unsigned long' [-Wsign-compare] src/r_data/models/models.cpp:427:38: warning: comparison of integers of different signs: 'long' and 'unsigned long' [-Wsign-compare] src/r_data/models/models_ue1.cpp:49:37: warning: comparison of integers of different signs: 'long' and 'unsigned long' [-Wsign-compare] --- src/r_data/models/models.cpp | 4 ++-- src/r_data/models/models_ue1.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index ad4e72576..ce41e064d 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -415,7 +415,7 @@ static unsigned FindModel(const char * path, const char * modelfile) FMemLump lumpd = Wads.ReadLump(lump); char * buffer = (char*)lumpd.GetMem(); - if ( fullname.IndexOf("_d.3d") == fullname.Len()-5 ) + if ( (size_t)fullname.IndexOf("_d.3d") == fullname.Len()-5 ) { FString anivfile = fullname.GetChars(); anivfile.Substitute("_d.3d","_a.3d"); @@ -424,7 +424,7 @@ static unsigned FindModel(const char * path, const char * modelfile) model = new FUE1Model; } } - else if ( fullname.IndexOf("_a.3d") == fullname.Len()-5 ) + else if ( (size_t)fullname.IndexOf("_a.3d") == fullname.Len()-5 ) { FString datafile = fullname.GetChars(); datafile.Substitute("_a.3d","_d.3d"); diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index e07f471b9..d7394bd79 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -46,7 +46,7 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int FMemLump lump2; const char *buffer2; FString realfilename = Wads.GetLumpFullName(lumpnum); - if ( realfilename.IndexOf("_d.3d") == realfilename.Len()-5 ) + if ( (size_t)realfilename.IndexOf("_d.3d") == realfilename.Len()-5 ) { realfilename.Substitute("_d.3d","_a.3d"); lumpnum2 = Wads.CheckNumForFullName(realfilename); From fd3681dae22e6fa41841d7e37b66c3f4aff7d481 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 13:33:28 +0200 Subject: [PATCH 06/40] - use an indexed vertex buffer to render the flats. Right now this has no advantage but it allows optimizing the data, e.g. rendering an entire sector in one go instead of per subsector. --- src/gl/compatibility/gl_20.cpp | 1 + src/gl/data/gl_vertexbuffer.cpp | 13 +++ src/gl/data/gl_vertexbuffer.h | 6 ++ src/gl/scene/gl_flats.cpp | 3 +- src/hwrenderer/data/flatvertices.cpp | 150 ++++++++++++++++++++++++++- src/hwrenderer/data/flatvertices.h | 30 +++++- src/p_3dfloors.cpp | 1 + src/p_setup.cpp | 1 + src/p_udmf.cpp | 1 + src/r_defs.h | 5 +- 10 files changed, 202 insertions(+), 9 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 5ff6c7710..84ecfc31d 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -588,6 +588,7 @@ bool FDrawInfo::PutFlatCompat(GLFlat *flat, bool fog) int list = list_indices[masked][foggy]; auto newflat = gl_drawinfo->dldrawlists[list].NewFlat(); *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; } diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index ce32b3ab4..301b6bc1c 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -125,6 +125,8 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) : FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height) { + ibo_id = 0; + if (gl.buffermethod != BM_LEGACY) glGenBuffers(1, &ibo_id); switch (gl.buffermethod) { case BM_PERSISTENT: @@ -170,6 +172,11 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); } + if (ibo_id != 0) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDeleteBuffers(1, &ibo_id); + } if (gl.legacyMode) { delete[] map; @@ -188,6 +195,7 @@ void FFlatVertexBuffer::OutputResized(int width, int height) void FFlatVertexBuffer::BindVBO() { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); if (!gl.legacyMode) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); @@ -245,4 +253,9 @@ void FFlatVertexBuffer::CreateVBO() Map(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); 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); + } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 28fe8f45c..b21fcd2d3 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -95,6 +95,7 @@ public: class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator { + unsigned int ibo_id; FFlatVertex *map; unsigned int mIndex; std::atomic mCurIndex; @@ -177,6 +178,11 @@ public: #endif + uint32_t *GetIndexPointer() const + { + return ibo_id == 0 ? &ibo_data[0] : nullptr; + } + void CheckPlanes(sector_t *sector) { FFlatVertexGenerator::CheckPlanes(sector, map); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index ff55d1161..41e4e0e69 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -186,7 +186,8 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool { if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli); drawcalls.Clock(); - glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); + //glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); + glDrawElements(GL_TRIANGLE_FAN, sub->numlines, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index); drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index 86bf78261..a5149a60e 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -181,10 +181,9 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t if (dotop || dobottom) { - if (dotop) ffloor->top.vindex = vbo_shadowdata.Size(); - if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size(); - - CreateSectorVertices(fsec, plane, false); + auto ndx = CreateSectorVertices(fsec, plane, false); + if (dotop) ffloor->top.vindex = ndx; + if (dobottom) ffloor->bottom.vindex = ndx; } } } @@ -227,6 +226,147 @@ void FFlatVertexGenerator::CreateFlatVertices() } } +//========================================================================== +// +// Creates the vertices for one plane in one subsector +// +//========================================================================== + +int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen) +{ + int idx = ibo_data.Reserve(sub->numlines); + for (unsigned int k = 0; knumlines; k++) + { + auto ndx = gen.GetIndex(sub->firstline[k].v1); + ibo_data[idx + k] = vi + ndx; + } + return idx; +} + +//========================================================================== +// +// Creates the vertices for one plane in one subsector +// +//========================================================================== + +int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FFlatVertexGenerator::FIndexGenerationInfo &gen) +{ + int rt = ibo_data.Size(); + int vi = vbo_shadowdata.Reserve(gen.vertices.Size()); + 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; jsubsectorcount; j++) + { + subsector_t *sub = sec->subsectors[j]; + CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen); + } + return rt; +} + +//========================================================================== +// +// +// +//========================================================================== + +int FFlatVertexGenerator::CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray &gen) +{ + // First calculate the vertices for the sector itself + sec->vboheight[h] = sec->GetPlaneTexZ(h); + sec->vboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]); + + // Next are all sectors using this one as heightsec + TArray &fakes = sec->e->FakeFloor.Sectors; + for (unsigned g = 0; gvboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]); + } + + // and finally all attached 3D floors + TArray &xf = sec->e->XFloor.attached; + for (unsigned g = 0; gflags & FF_RENDERPLANES) + { + bool dotop = (ffloor->top.model == sec) && (ffloor->top.isceiling == h); + bool dobottom = (ffloor->bottom.model == sec) && (ffloor->bottom.isceiling == h); + + if (dotop || dobottom) + { + auto ndx = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]); + if (dotop) ffloor->top.vindex = ndx; + if (dobottom) ffloor->bottom.vindex = ndx; + } + } + } + sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h]; + return sec->vboindex[h]; +} + + +//========================================================================== +// +// +// +//========================================================================== + +void FFlatVertexGenerator::CreateIndexedFlatVertices() +{ + TArray 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 (auto &sec : level.sectors) + { + CreateIndexedVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor, gen); + } + } + + // We need to do a final check for Vavoom water and FF_FIX sectors. + // No new vertices are needed here. The planes come from the actual sector + for (auto &sec : level.sectors) + { + for (auto ff : sec.e->XFloor.ffloors) + { + if (ff->top.model == &sec) + { + ff->top.vindex = sec.vboindex[ff->top.isceiling]; + } + if (ff->bottom.model == &sec) + { + ff->bottom.vindex = sec.vboindex[ff->top.isceiling]; + } + } + } +} + //========================================================================== // // @@ -257,7 +397,7 @@ void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVe void FFlatVertexGenerator::CreateVertices() { vbo_shadowdata.Resize(NUM_RESERVED); - CreateFlatVertices(); + CreateIndexedFlatVertices(); } //========================================================================== diff --git a/src/hwrenderer/data/flatvertices.h b/src/hwrenderer/data/flatvertices.h index 9a45558b5..2f0b1d5f4 100644 --- a/src/hwrenderer/data/flatvertices.h +++ b/src/hwrenderer/data/flatvertices.h @@ -45,9 +45,31 @@ class FFlatVertexGenerator { protected: TArray vbo_shadowdata; + TArray ibo_data; + // Temporary data for creating an indexed buffer + struct FIndexGenerationInfo + { + TArray vertices; + TMap 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; + } + }; - void CheckPlanes(sector_t *sector); public: enum @@ -70,6 +92,12 @@ private: int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); void CreateFlatVertices(); + + int CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FIndexGenerationInfo &gen); + int CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FIndexGenerationInfo &gen); + int CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray &gen); + void CreateIndexedFlatVertices(); + void UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map); protected: void CreateVertices(); diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 4254c92d4..5c6096f84 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -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.model = ffloor->bottom.model = ffloor->model = sec2; ffloor->target = sec; + ffloor->top.vindex = ffloor->bottom.vindex = -1; if (!(flags&FF_THINFLOOR)) { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 56850f6a0..dba5a109e 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->friction = ORIG_FRICTION; ss->movefactor = ORIG_FRICTION_FACTOR; ss->sectornum = i; + ss->ibocount = -1; } delete[] msp; } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 24a7fd5fd..ef2b08b8f 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1375,6 +1375,7 @@ public: sec->sectornum = index; sec->damageinterval = 32; sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1; + sec->ibocount = -1; memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors)); if (floordrop) sec->Flags = SECF_FLOORDROP; // killough 3/7/98: end changes diff --git a/src/r_defs.h b/src/r_defs.h index a9e7e57c7..b3ee3e96b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1087,9 +1087,10 @@ public: 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 - 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; } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } From 2125f8b9d1a12b14d9ff5159b14ffad34b68bab5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 14:42:25 +0200 Subject: [PATCH 07/40] - use triangles instead of triangle fans to render flats. --- src/gl/scene/gl_flats.cpp | 7 +++---- src/hwrenderer/data/flatvertices.cpp | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 41e4e0e69..ac6415b43 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -181,24 +181,23 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool for (int i=0; isector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; + if (sub->numlines <= 2) continue; if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans) { if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli); drawcalls.Clock(); - //glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); - glDrawElements(GL_TRIANGLE_FAN, sub->numlines, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index); + glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index); drawcalls.Unclock(); flatvertices += sub->numlines; flatprimitives++; } - index += sub->numlines; + index += (sub->numlines - 2) * 3; } } else { // Draw the subsectors belonging to this sector - // (can this case even happen?) for (int i=0; isector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index a5149a60e..cfa929d31 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -234,11 +234,20 @@ void FFlatVertexGenerator::CreateFlatVertices() int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen) { - int idx = ibo_data.Reserve(sub->numlines); - for (unsigned int k = 0; knumlines; k++) + if (sub->numlines < 3) return -1; + + 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; knumlines; k++) { auto ndx = gen.GetIndex(sub->firstline[k].v1); - ibo_data[idx + k] = vi + ndx; + + ibo_data[idx++] = vi + firstndx; + ibo_data[idx++] = vi + secondndx; + ibo_data[idx++] = vi + ndx; + secondndx = ndx; } return idx; } From 352279a52fa8fde81da9cf32ba90eb51f6f75b74 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 14:44:16 +0200 Subject: [PATCH 08/40] - removed the non-indexed flat setup. This won't be needed any longer. --- src/hwrenderer/data/flatvertices.cpp | 114 --------------------------- src/hwrenderer/data/flatvertices.h | 5 -- 2 files changed, 119 deletions(-) diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index cfa929d31..0fba9a50f 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -118,120 +118,6 @@ static F3DFloor *Find3DFloor(sector_t *target, sector_t *model) // //========================================================================== -int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor) -{ - int idx = vbo_shadowdata.Reserve(sub->numlines); - for(unsigned int k=0; knumlines; k++, idx++) - { - vbo_shadowdata[idx].SetFlatVertex(sub->firstline[k].v1, plane); - if (sub->sector->transdoor && floor) vbo_shadowdata[idx].z -= 1.f; - } - return idx; -} - -//========================================================================== -// -// Creates the vertices for one plane in one subsector -// -//========================================================================== - -int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor) -{ - int rt = vbo_shadowdata.Size(); - // First calculate the vertices for the sector itself - for(int j=0; jsubsectorcount; j++) - { - subsector_t *sub = sec->subsectors[j]; - CreateSubsectorVertices(sub, plane, floor); - } - return rt; -} - -//========================================================================== -// -// -// -//========================================================================== - -int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor) -{ - // First calculate the vertices for the sector itself - sec->vboheight[h] = sec->GetPlaneTexZ(h); - sec->vboindex[h] = CreateSectorVertices(sec, plane, floor); - - // Next are all sectors using this one as heightsec - TArray &fakes = sec->e->FakeFloor.Sectors; - for (unsigned g=0; gvboindex[2+h] = CreateSectorVertices(fsec, plane, false); - } - - // and finally all attached 3D floors - TArray &xf = sec->e->XFloor.attached; - for (unsigned g=0; gflags & FF_RENDERPLANES) - { - bool dotop = (ffloor->top.model == sec) && (ffloor->top.isceiling == h); - bool dobottom = (ffloor->bottom.model == sec) && (ffloor->bottom.isceiling == h); - - if (dotop || dobottom) - { - auto ndx = CreateSectorVertices(fsec, plane, false); - if (dotop) ffloor->top.vindex = ndx; - if (dobottom) ffloor->bottom.vindex = ndx; - } - } - } - sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h]; - return sec->vboindex[h]; -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FFlatVertexGenerator::CreateFlatVertices() -{ - for (int h = sector_t::floor; h <= sector_t::ceiling; h++) - { - for(auto &sec : level.sectors) - { - CreateVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor); - } - } - - // We need to do a final check for Vavoom water and FF_FIX sectors. - // No new vertices are needed here. The planes come from the actual sector - for (auto &sec : level.sectors) - { - for(auto ff : sec.e->XFloor.ffloors) - { - if (ff->top.model == &sec) - { - ff->top.vindex = sec.vboindex[ff->top.isceiling]; - } - if (ff->bottom.model == &sec) - { - ff->bottom.vindex = sec.vboindex[ff->top.isceiling]; - } - } - } -} - -//========================================================================== -// -// Creates the vertices for one plane in one subsector -// -//========================================================================== - int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen) { if (sub->numlines < 3) return -1; diff --git a/src/hwrenderer/data/flatvertices.h b/src/hwrenderer/data/flatvertices.h index 2f0b1d5f4..9f4661261 100644 --- a/src/hwrenderer/data/flatvertices.h +++ b/src/hwrenderer/data/flatvertices.h @@ -88,11 +88,6 @@ public: void OutputResized(int width, int height); private: - int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); - int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); - int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); - void CreateFlatVertices(); - int CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FIndexGenerationInfo &gen); int CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FIndexGenerationInfo &gen); int CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray &gen); From 3e204080ae3b2459e16d956b37d71a61adb64c2d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 15:20:46 +0200 Subject: [PATCH 09/40] - render sector planes in one draw call. On a fast and modern graphics card this is a lot faster than doing it per subsector but it may not be without drawbacks on older hardware so it will require some testing on older hardware. For me Frozen Time's view over the bridge went from 46 fps to 51 fps with this change, the time saved was roughly 2 ms. --- src/gl/scene/gl_drawinfo.h | 1 + src/gl/scene/gl_flats.cpp | 60 ++++++++++++++++++++++--- src/hwrenderer/data/flatvertices.cpp | 1 + src/hwrenderer/scene/hw_drawstructs.h | 2 + src/hwrenderer/scene/hw_flats.cpp | 16 +++++-- src/hwrenderer/scene/hw_renderhacks.cpp | 2 + 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 05ca3dd8d..1add3bf4d 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -121,6 +121,7 @@ struct FDrawInfo : public HWDrawInfo void ProcessLights(GLFlat *flat, bool istrans); void DrawSubsector(GLFlat *flat, subsector_t * sub); void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli); + void SetupSectorLights(GLFlat *flat, int pass, int *dli); // Sprite drawer void DrawSprite(GLSprite *sprite, int pass); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index ac6415b43..d4105c569 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -62,7 +62,35 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, (*dli)++; 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); if (pass == GLPASS_LIGHTSONLY) @@ -137,13 +165,20 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) { flat->dynlightindex = GLRenderer->mLights->GetIndexPtr(); - // Draw the subsectors belonging to this sector - for (int i=0; i< flat->sector->subsectorcount; i++) + if (flat->sector->ibocount > 0) { - subsector_t * sub = flat->sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans) + SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr); + } + else + { + // Draw the subsectors belonging to this sector + for (int i = 0; i < flat->sector->subsectorcount; i++) { - SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); + subsector_t * sub = flat->sector->subsectors[i]; + if (gl_drawinfo->ss_renderflags[sub->Index()] & flat->renderflags || istrans) + { + SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); + } } } @@ -175,7 +210,18 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool gl_RenderState.Apply(); if (gl.legacyMode) processlights = false; - if (flat->vboindex >= 0) + + auto vcount = flat->sector->ibocount; + if (vcount > 0) + { + 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; for (int i=0; isector->subsectorcount; i++) diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index 0fba9a50f..cba80b11a 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -165,6 +165,7 @@ int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secpl subsector_t *sub = sec->subsectors[j]; CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen); } + sec->ibocount = ibo_data.Size() - rt; return rt; } diff --git a/src/hwrenderer/scene/hw_drawstructs.h b/src/hwrenderer/scene/hw_drawstructs.h index 7aa7e0b7d..56c74a8f7 100644 --- a/src/hwrenderer/scene/hw_drawstructs.h +++ b/src/hwrenderer/scene/hw_drawstructs.h @@ -311,7 +311,9 @@ public: int dynlightindex; + bool SetupLights(int pass, FLightNode *head, FDynLightData &lightdata, int portalgroup); 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 Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture); diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index dabee535d..0aafadc26 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -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; if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return false; // no lights on additively blended surfaces. lightdata.Clear(); - FLightNode * node = sub->lighthead; while (node) { 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()); - lightdata.GetLight(sub->sector->PortalGroup, p, light, false); + lightdata.GetLight(portalgroup, p, light, false); node = node->nextLight; } 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 @@ -252,6 +261,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector) sector = &level.sectors[frontsector->sectornum]; extsector_t::xfloor &x = sector->e->XFloor; dynlightindex = -1; + vertexcount = sector->ibocount; uint8_t &srf = di->sectorrenderflags[sector->sectornum]; diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 5eacd9dfc..bfc7b38d3 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -1077,6 +1077,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area) { subsector_t *sub = HandledSubsectors[j]; 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) { @@ -1122,6 +1123,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area) { subsector_t *sub = HandledSubsectors[j]; 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) { From f54cf561abf1df8ca2cb1e21745ccab5e4fe8d90 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 15:40:33 +0200 Subject: [PATCH 10/40] - missed this. --- src/hwrenderer/scene/hw_flats.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index 0aafadc26..fa1ff287a 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -261,7 +261,6 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector) sector = &level.sectors[frontsector->sectornum]; extsector_t::xfloor &x = sector->e->XFloor; dynlightindex = -1; - vertexcount = sector->ibocount; uint8_t &srf = di->sectorrenderflags[sector->sectornum]; From 0c4a08460f36c4323f8bbc8a6f17cea8df3be684 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sat, 19 May 2018 16:40:45 +0200 Subject: [PATCH 11/40] Cleaned UE1 math by using FVector classes. Reversed winding order on vertex buffer creation as UE1 uses CCW. --- src/r_data/models/models_ue1.cpp | 52 ++++++++++---------------------- src/r_data/models/models_ue1.h | 12 ++------ 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index d7394bd79..7cf292d6b 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -98,9 +98,9 @@ void FUE1Model::LoadGeometry() { UE1Vertex Vert; // unpack position - Vert.Pos.X = unpackuvert(averts[j+i*numVerts],0); - Vert.Pos.Y = unpackuvert(averts[j+i*numVerts],1); - Vert.Pos.Z = unpackuvert(averts[j+i*numVerts],2); + Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],0), + unpackuvert(averts[j+i*numVerts],1), + unpackuvert(averts[j+i*numVerts],2)); // push vertex (without normals, will be calculated later) verts.Push(Vert); } @@ -114,10 +114,7 @@ void FUE1Model::LoadGeometry() Poly.V[j] = dpolys[i].vertices[j]; // unpack coords for ( int j=0; j<3; j++ ) - { - Poly.C[j].S = dpolys[i].uv[j][0]/255.f; - Poly.C[j].T = dpolys[i].uv[j][1]/255.f; - } + Poly.C[j] = FVector2(dpolys[i].uv[j][0]/255.f,dpolys[i].uv[j][1]/255.f); Poly.texNum = dpolys[i].texnum; // push polys.Push(Poly); @@ -129,39 +126,22 @@ void FUE1Model::LoadGeometry() { for ( int j=0; j=0; l-- ) { UE1Vertex V = verts[polys[groups[j].P[k]].V[l]+i*numVerts]; - UE1Coord C = polys[groups[j].P[k]].C[l]; + FVector2 C = polys[groups[j].P[k]].C[l]; FModelVertex *vert = &vptr[vidx++]; - vert->Set(V.Pos.X,V.Pos.Y,V.Pos.Z,C.S,C.T); + vert->Set(V.Pos.X,V.Pos.Y,V.Pos.Z,C.X,C.Y); vert->SetNormal(V.Normal.X,V.Normal.Y,V.Normal.Z); } } diff --git a/src/r_data/models/models_ue1.h b/src/r_data/models/models_ue1.h index 91d568047..dc6209fa2 100644 --- a/src/r_data/models/models_ue1.h +++ b/src/r_data/models/models_ue1.h @@ -56,22 +56,14 @@ private: uint32_t * averts; // converted data structures - struct UE1Coord - { - float S, T; - }; - struct UE1Vector - { - float X, Y, Z; - }; struct UE1Vertex { - UE1Vector Pos, Normal; + FVector3 Pos, Normal; }; struct UE1Poly { int V[3]; - UE1Coord C[3]; + FVector2 C[3]; int texNum; }; struct UE1Group From 90cb0b32158c37f7893009f54ef348b2d1acad13 Mon Sep 17 00:00:00 2001 From: RockstarRaccoon Date: Sat, 19 May 2018 09:31:22 +0300 Subject: [PATCH 12/40] - added 'revealed on automap' linedef flag, UDMF only https://forum.zdoom.org/viewtopic.php?t=59808 --- src/am_map.cpp | 2 +- src/doomdata.h | 1 + src/namedef.h | 1 + src/p_udmf.cpp | 4 ++++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 5b717e285..4cab453f7 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2658,7 +2658,7 @@ void AM_drawWalls (bool allmap) AM_drawMline(&l, AMColors.TSWallColor); } } - else if (allmap) + else if (allmap || (line.flags & ML_REVEALED)) { if ((line.flags & ML_DONTDRAW) && (am_cheat == 0 || am_cheat >= 4)) { diff --git a/src/doomdata.h b/src/doomdata.h index 58bfea68a..38a65ca50 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -170,6 +170,7 @@ enum ELineFlags : unsigned ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING + ML_REVEALED = 0x20000000, // set if revealed in automap ML_PORTALCONNECT = 0x80000000, // for internal use only: This line connects to a sector with a linked portal (used to speed up sight checks.) }; diff --git a/src/namedef.h b/src/namedef.h index 9e6d3811a..05f2c55cb 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -537,6 +537,7 @@ xx(Repeatspecial) xx(Conversation) xx(Locknumber) xx(Midtex3dimpassible) +xx(Revealed) xx(Playercross) xx(Playeruse) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 24a7fd5fd..f0d34c8ee 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1107,6 +1107,10 @@ public: Flag(ld->flags, ML_3DMIDTEX_IMPASS, key); continue; + case NAME_Revealed: + Flag(ld->flags, ML_REVEALED, key); + continue; + case NAME_MoreIds: // delay parsing of the tag string until parsing of the sector is complete // This ensures that the ID is always the first tag in the list. From c6f7d92c765d8d5c0b4232d8147436731887e978 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 19 May 2018 10:49:04 +0300 Subject: [PATCH 13/40] - added forced automap style to linedef, UDMF only https://forum.zdoom.org/viewtopic.php?t=59808 --- src/am_map.cpp | 31 +++++++++++++++++++++++++++++++ src/namedef.h | 1 + src/p_udmf.cpp | 4 ++++ src/r_defs.h | 21 +++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/src/am_map.cpp b/src/am_map.cpp index 4cab453f7..20f99de36 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -324,6 +324,30 @@ struct AMColorset } }; +//============================================================================= +// +// automap colors forced by linedef +// +//============================================================================= + +static const int AUTOMAP_LINE_COLORS[AMLS_COUNT] = +{ + -1, // AMLS_Default (unused) + AMColorset::WallColor, // AMLS_OneSided, + AMColorset::TSWallColor, // AMLS_TwoSided + AMColorset::FDWallColor, // AMLS_FloorDiff + AMColorset::CDWallColor, // AMLS_CeilingDiff + AMColorset::EFWallColor, // AMLS_ExtraFloor + AMColorset::SpecialWallColor, // AMLS_Special + AMColorset::SecretWallColor, // AMLS_Secret + AMColorset::NotSeenColor, // AMLS_NotSeen + AMColorset::LockedColor, // AMLS_Locked + AMColorset::IntraTeleportColor, // AMLS_IntraTeleport + AMColorset::InterTeleportColor, // AMLS_InterTeleport + AMColorset::UnexploredSecretColor, // AMLS_UnexploredSecret + AMColorset::PortalColor, // AMLS_Portal +}; + //============================================================================= // // predefined colorsets @@ -2583,6 +2607,13 @@ void AM_drawWalls (bool allmap) } } + if (line.automapstyle > AMLS_Default && line.automapstyle < AMLS_COUNT + && (am_cheat == 0 || am_cheat >= 4)) + { + AM_drawMline(&l, AUTOMAP_LINE_COLORS[line.automapstyle]); + continue; + } + if (portalmode) { AM_drawMline(&l, AMColors.PortalColor); diff --git a/src/namedef.h b/src/namedef.h index 05f2c55cb..b098a06c0 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -538,6 +538,7 @@ xx(Conversation) xx(Locknumber) xx(Midtex3dimpassible) xx(Revealed) +xx(AutomapStyle) xx(Playercross) xx(Playeruse) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index f0d34c8ee..283fac000 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1111,6 +1111,10 @@ public: Flag(ld->flags, ML_REVEALED, key); continue; + case NAME_AutomapStyle: + ld->automapstyle = AutomapLineStyle(CheckInt(key)); + continue; + case NAME_MoreIds: // delay parsing of the tag string until parsing of the sector is complete // This ensures that the ID is always the first tag in the list. diff --git a/src/r_defs.h b/src/r_defs.h index a9e7e57c7..d5b104624 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1281,6 +1281,26 @@ struct side_t }; +enum AutomapLineStyle : int +{ + AMLS_Default, + AMLS_OneSided, + AMLS_TwoSided, + AMLS_FloorDiff, + AMLS_CeilingDiff, + AMLS_ExtraFloor, + AMLS_Special, + AMLS_Secret, + AMLS_NotSeen, + AMLS_Locked, + AMLS_IntraTeleport, + AMLS_InterTeleport, + AMLS_UnexploredSecret, + AMLS_Portal, + + AMLS_COUNT +}; + struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 @@ -1297,6 +1317,7 @@ struct line_t int locknumber; // [Dusk] lock number for special unsigned portalindex; unsigned portaltransferred; + AutomapLineStyle automapstyle; DVector2 Delta() const { From cc65490062c902f9187094d5eeaef14cec26bf7d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 19:18:38 +0200 Subject: [PATCH 14/40] - added CVAR to disable WGL_EXT_swap_control_tear. At least on faster NVidia hardware, setting this to false and gl_finishbeforeswap to true gives a better experience because it reduces screen tearing - but the same setting will reduce frame rate quite dramatically on Intel and can cause bad stalls on some older GPUs when rendering camera textures. --- src/win32/win32gliface.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index bd4600bb0..cb6da5ff9 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -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) { - if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0); + if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? (gl_control_tear? SwapInterval : 1) : 0); } void SystemFrameBuffer::SwapBuffers() From 5cffa8873aec25ab2afa52b4b0910a68311b6e4e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 19:19:48 +0200 Subject: [PATCH 15/40] - added a CVAR to disable per-plane rendering. This will require some comparisons on older hardware. On my Geforce 1060 rendering the full plane with one draw call is clearly faster in all cases I tested. --- src/gl/scene/gl_flats.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index d4105c569..39ab921b4 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -48,6 +48,8 @@ #include "gl/scene/gl_scenedrawer.h" #include "gl/renderer/gl_quaddrawer.h" +CVAR(Bool, gl_render_subsectors, false, 0) + //========================================================================== // // Flats @@ -165,7 +167,7 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) { flat->dynlightindex = GLRenderer->mLights->GetIndexPtr(); - if (flat->sector->ibocount > 0) + if (flat->sector->ibocount > 0 && !gl_render_subsectors) { SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr); } @@ -212,7 +214,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool if (gl.legacyMode) processlights = false; auto vcount = flat->sector->ibocount; - if (vcount > 0) + if (vcount > 0 && !gl_render_subsectors) { if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli); drawcalls.Clock(); From 3dc6ddbcc3981dd298cc66bc1a0309d9935aec1f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 19:20:45 +0200 Subject: [PATCH 16/40] - check light direction in the shader. There are situations where lights on the wrong side of a linedef may be passed and those need to be skipped in the shader code. --- wadsrc/static/shaders/glsl/material_normal.fp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/shaders/glsl/material_normal.fp b/wadsrc/static/shaders/glsl/material_normal.fp index b048f4559..c251351d9 100644 --- a/wadsrc/static/shaders/glsl/material_normal.fp +++ b/wadsrc/static/shaders/glsl/material_normal.fp @@ -9,6 +9,9 @@ vec3 lightContribution(int i, vec3 normal) float lightdistance = distance(lightpos.xyz, pixelpos.xyz); if (lightpos.w < lightdistance) return vec3(0.0); // Early out lights touching surface but not this fragment + + 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); @@ -18,7 +21,7 @@ vec3 lightContribution(int i, vec3 normal) if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag { vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz); - attenuation *= clamp(dot(normal, lightdir), 0.0, 1.0); + attenuation *= clamp(dotprod, 0.0, 1.0); } if (attenuation > 0.0) // Skip shadow map test if possible From 1266339c0fd50df27bc987b2a4d00b2afe0d6269 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 May 2018 21:17:58 +0200 Subject: [PATCH 17/40] - fixed shader compilation. --- wadsrc/static/shaders/glsl/material_normal.fp | 2 +- wadsrc/static/zscript/statusbar/sbarinfowrapper.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/shaders/glsl/material_normal.fp b/wadsrc/static/shaders/glsl/material_normal.fp index c251351d9..6b65de6a3 100644 --- a/wadsrc/static/shaders/glsl/material_normal.fp +++ b/wadsrc/static/shaders/glsl/material_normal.fp @@ -10,6 +10,7 @@ vec3 lightContribution(int i, vec3 normal) if (lightpos.w < lightdistance) 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. @@ -20,7 +21,6 @@ vec3 lightContribution(int i, vec3 normal) 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); } diff --git a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt index efc6bedc8..96f006320 100644 --- a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt +++ b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt @@ -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. class SBarInfoWrapper : BaseStatusBar From 3069b5380459fadccd7aa2949017b191b4eb3ecf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 May 2018 00:15:31 +0200 Subject: [PATCH 18/40] - disable shader storage blocks if none get reported for vertex shaders. --- src/gl_load/gl_interface.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gl_load/gl_interface.cpp b/src/gl_load/gl_interface.cpp index ee47ce5a0..6e07259f5 100644 --- a/src/gl_load/gl_interface.cpp +++ b/src/gl_load/gl_interface.cpp @@ -238,7 +238,12 @@ void gl_LoadExtensions() // Intel's GLSL compiler is a bit broken with extensions, so unlock the feature only if not on Intel or having GL 4.3. if (strstr(gl.vendorstring, "Intel") == NULL || gl_version >= 4.3f) { - gl.flags |= RFL_SHADER_STORAGE_BUFFER; + // Mesa implements shader storage only for fragment shaders. + // Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects. + int v; + glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); + if (v > 0) + gl.flags |= RFL_SHADER_STORAGE_BUFFER; } } gl.flags |= RFL_BUFFER_STORAGE; From 2d4b8549c6302728c52cab824cea1c991fe5d2a9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 May 2018 08:56:29 +0200 Subject: [PATCH 19/40] - per-sector plane rendering needs to be disabled when processing a line portal with hardware that has no working clip plane support. In this case there are no means to discard the parts of the rendered sectors that lie behind the portal so it should only render the parts that are flagged as visible. --- src/gl/renderer/gl_renderstate.cpp | 2 +- src/gl/renderer/gl_renderstate.h | 11 +++++++++++ src/gl/scene/gl_flats.cpp | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 305a5177c..a0a1c5cc8 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -62,7 +62,7 @@ static void matrixToGL(const VSMatrix &mat, int loc) void FRenderState::Reset() { mTextureEnabled = true; - mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; + mClipLineShouldBeActive = mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true; currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true; mFogColor.d = -1; diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 1db6602a5..8aa4d0093 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -81,6 +81,7 @@ class FRenderState bool mGlowEnabled; bool mSplitEnabled; bool mClipLineEnabled; + bool mClipLineShouldBeActive; bool mBrightmapEnabled; bool mColorMask[4]; bool currentColorMask[4]; @@ -201,6 +202,11 @@ public: return mClipLineEnabled; } + bool GetClipLineShouldBeActive() + { + return mClipLineShouldBeActive; + } + void SetClipHeight(float height, float direction); void SetNormal(FVector3 norm) @@ -326,6 +332,11 @@ public: 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) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 39ab921b4..1810508bc 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -167,7 +167,7 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) { flat->dynlightindex = GLRenderer->mLights->GetIndexPtr(); - if (flat->sector->ibocount > 0 && !gl_render_subsectors) + if (flat->sector->ibocount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive()) { SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr); } @@ -214,7 +214,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool if (gl.legacyMode) processlights = false; auto vcount = flat->sector->ibocount; - if (vcount > 0 && !gl_render_subsectors) + if (vcount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive()) { if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli); drawcalls.Clock(); From 526711f5d8368cd99e2c8b92d08540459ca49b9c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 20 May 2018 13:08:29 +0300 Subject: [PATCH 20/40] - replaced tabs with spaces in UDMF spec --- specs/udmf_zdoom.txt | 105 ++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 185d2a6de..32806245c 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -120,7 +120,7 @@ Note: All fields default to false unless mentioned otherwise. blockhitscan = ; // Line blocks hitscan attacks locknumber = ; // Line special is locked arg0str = ; // Alternate string-based version of arg0 - moreids = ; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505") + moreids = ; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505") transparent = ; // true = line is a Strife transparent line (alpha 0.25) @@ -171,14 +171,14 @@ Note: All fields default to false unless mentioned otherwise. yscaleceiling = ; // Y texture scale of ceiling texture, Default = 1.0. rotationfloor = ; // Rotation of floor texture in degrees, Default = 0.0. rotationceiling = ; // Rotation of ceiling texture in degrees, Default = 0.0. - ceilingplane_a = ; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'. - ceilingplane_b = ; // 'heightceiling' will still be used to calculate texture alignment. - ceilingplane_c = ; // The plane equation will only be used if all 4 values are given. - ceilingplane_d = ; - floorplane_a = ; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'. - floorplane_b = ; // 'heightfloor' will still be used to calculate texture alignment. - floorplane_c = ; // The plane equation will only be used if all 4 values are given. - floorplane_d = ; + ceilingplane_a = ; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'. + ceilingplane_b = ; // 'heightceiling' will still be used to calculate texture alignment. + ceilingplane_c = ; // The plane equation will only be used if all 4 values are given. + ceilingplane_d = ; + floorplane_a = ; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'. + floorplane_b = ; // 'heightfloor' will still be used to calculate texture alignment. + floorplane_c = ; // The plane equation will only be used if all 4 values are given. + floorplane_d = ; lightfloor = ; // The floor's light level. Default is 0. lightceiling = ; // The ceiling's light level. Default is 0. lightfloorabsolute = ; // true = 'lightfloor' is an absolute value. Default is @@ -196,8 +196,8 @@ Note: All fields default to false unless mentioned otherwise. fadecolor = ; // Sector's fog color as RRGGBB value, default = 0x000000. desaturation = ; // Color desaturation factor. 0 = none, 1 = full, default = 0. silent = ; // Actors in this sector make no sound, - nofallingdamage = ; // Falling damage is disabled in this sector - noattack = ; // Blocks monster attacks in this sector. + nofallingdamage = ; // Falling damage is disabled in this sector + noattack = ; // Blocks monster attacks in this sector. dropactors = ; // Actors drop with instantly moving floors (*) norespawn = ; // Players can not respawn in this sector soundsequence = ; // The sound sequence to play when this sector moves. Placing a @@ -215,21 +215,21 @@ Note: All fields default to false unless mentioned otherwise. damagehazard = ; // Changes damage model to Strife's delayed damage for the given sector. Default = false. floorterrain = ; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.' ceilingterrain = ; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.' - floor_reflect = ; // reflectiveness of floor (OpenGL only, not functional on sloped sectors) - ceiling_reflect = ; // reflectiveness of ceiling (OpenGL only, not functional on sloped sectors) - fogdensity = ; // Sets an explicit fog density for the sector, overriding the default calculation from the light level. Value range is 0-510, - // 0 meaning that the default is to be used, 2 equalling the density of a light level of 250, and 255 equalling the density of - // a light level of 0. (OpenGL only) - floorglowcolor = ; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) - floorglowheight = ; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) - ceilingglowcolor = ; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) - ceilingglowheight = ; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) - color_floor = ; // Material color of sector's floor. Default is white (0xffffff) - color_ceiling = ; // Material color of sector's ceiling. Default is white (0xffffff) - color_walltop = ; // Material color of top of sector's sidedefs. In OpenGL 2.x and the software renderer this will define the entire wall's color) Default is white (0xffffff) - color_wallbottom = ; // Material color of bottom of sector's sidedefs (OpenGL 3.x and later only) Default is white (0xffffff) - color_sprites = ; // Material color of sprites in sector. Default is white (0xffffff) - + floor_reflect = ; // reflectiveness of floor (OpenGL only, not functional on sloped sectors) + ceiling_reflect = ; // reflectiveness of ceiling (OpenGL only, not functional on sloped sectors) + fogdensity = ; // Sets an explicit fog density for the sector, overriding the default calculation from the light level. Value range is 0-510, + // 0 meaning that the default is to be used, 2 equalling the density of a light level of 250, and 255 equalling the density of + // a light level of 0. (OpenGL only) + floorglowcolor = ; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) + floorglowheight = ; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) + ceilingglowcolor = ; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) + ceilingglowheight = ; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) + color_floor = ; // Material color of sector's floor. Default is white (0xffffff) + color_ceiling = ; // Material color of sector's ceiling. Default is white (0xffffff) + color_walltop = ; // Material color of top of sector's sidedefs. In OpenGL 2.x and the software renderer this will define the entire wall's color) Default is white (0xffffff) + color_wallbottom = ; // Material color of bottom of sector's sidedefs (OpenGL 3.x and later only) Default is white (0xffffff) + color_sprites = ; // Material color of sprites in sector. Default is white (0xffffff) + portal_ceil_blocksound = // ceiling portal blocks sound. portal_ceil_disabled = // ceiling portal disabled. @@ -241,8 +241,8 @@ Note: All fields default to false unless mentioned otherwise. portal_floor_nopass = // ceiling portal blocks movement if true. portal_floor_norender = // ceiling portal not rendered. portal_floor_overlaytype = // defines translucency style, can either be "translucent" or "additive". Default is "translucent". - - + + * Note about dropactors The spec requires this to be false by default. Currently, however, ZDoom assumes this to be true @@ -253,37 +253,37 @@ Note: All fields default to false unless mentioned otherwise. thing { - skill# = // Unlike the base spec, # can range from 1-16. - class# = // Unlike the base spec, # can range from 1-16. - conversation = // Assigns a conversation dialogue to this thing. + skill# = // Unlike the base spec, # can range from 1-16. + class# = // Unlike the base spec, # can range from 1-16. + conversation = // Assigns a conversation dialogue to this thing. // Parameter is the conversation ID, 0 meaning none. countsecret = ; // Picking up this actor counts as a secret. arg0str = ; // Alternate string-based version of arg0 - gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, - // negative values are used as their absolute. Default = 1.0. - - health = ; // Set per-actor health. Positive values are multiplied with the class's property, - // negative values are used as their absolute. Default = 1. - - renderstyle = ; // Set per-actor render style, overriding the class default. Possible values can be "normal", - // "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil", - // "addstencil", "shaded", "addshaded", "translucent", "fuzzy", "optfuzzy", "soultrans" and "shadow". - // Default is an empty string for no change. - fillcolor = ; // Fill color used by the "stencil", "addstencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000. - alpha = ; // Translucency of this actor (if applicable to renderstyle), default is 1.0. - score = ; // Score value of this actor, overriding the class default if not null. Default = 0. - pitch = ; // Pitch of thing in degrees. Default = 0 (horizontal). - roll = ; // Pitch of thing in degrees. Default = 0 (horizontal). - scalex = ; // Vertical scaling on thing. Default = 0 (ignored). - scaley = ; // Horizontal scaling on thing. Default = 0 (ignored). - scale = ; // Vertical and horizontal scaling on thing. Default = 0 (ignored). - floatbobphase = ; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default). + gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, + // negative values are used as their absolute. Default = 1.0. + + health = ; // Set per-actor health. Positive values are multiplied with the class's property, + // negative values are used as their absolute. Default = 1. + + renderstyle = ; // Set per-actor render style, overriding the class default. Possible values can be "normal", + // "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil", + // "addstencil", "shaded", "addshaded", "translucent", "fuzzy", "optfuzzy", "soultrans" and "shadow". + // Default is an empty string for no change. + fillcolor = ; // Fill color used by the "stencil", "addstencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000. + alpha = ; // Translucency of this actor (if applicable to renderstyle), default is 1.0. + score = ; // Score value of this actor, overriding the class default if not null. Default = 0. + pitch = ; // Pitch of thing in degrees. Default = 0 (horizontal). + roll = ; // Pitch of thing in degrees. Default = 0 (horizontal). + scalex = ; // Vertical scaling on thing. Default = 0 (ignored). + scaley = ; // Horizontal scaling on thing. Default = 0 (ignored). + scale = ; // Vertical and horizontal scaling on thing. Default = 0 (ignored). + floatbobphase = ; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default). * Note about arg0str For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it will be used as the name of the script to execute, and arg0 will be ignored. - On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color. + On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color. } @@ -430,6 +430,9 @@ sector material colors. 1.29 04.02.2018 arg0str in dynamic lights. +1.30 20.05.2018 +Replaced tabs with spaces. + =============================================================================== EOF =============================================================================== From ad31da20e5e1bbf8365a2f9243746bf7691e9818 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 20 May 2018 14:48:44 +0300 Subject: [PATCH 21/40] - added new linedef properties to UDMF spec https://forum.zdoom.org/viewtopic.php?t=59808 --- specs/udmf_zdoom.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 32806245c..84dcd4d29 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -122,7 +122,24 @@ Note: All fields default to false unless mentioned otherwise. arg0str = ; // Alternate string-based version of arg0 moreids = ; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505") - transparent = ; // true = line is a Strife transparent line (alpha 0.25) + transparent = ; // true = line is a Strife transparent line (alpha 0.25) + + automapstyle = ; // Explicit automap style. Possible values can be + // 0: Automap style is based on line properties (default). + // 1: One-sided wall. + // 2: Two-sided wall. + // 3: Floor levels of front and back sectors are different. + // 4: Ceiling levels of front and back sectors are different. + // 5: 3D floor border. + // 6: Wall with special non-door action. + // 7: Secret door. + // 8: Wall not seen yet. + // 9: Locked door. + // 10: Intra-level teleporter. + // 11: Inter-level or game-ending teleporter. + // 12: Unexplored secret wall. + // 13: Portal line. + revealed = ; // true = line is initially visible on automap. * Note about arg0str @@ -431,6 +448,7 @@ sector material colors. arg0str in dynamic lights. 1.30 20.05.2018 +Added automapstyle and revealed linedef properties. Replaced tabs with spaces. =============================================================================== From 2cdc9f9dda41f69a45de9de7b54a8ec4dc28a3cd Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 21 May 2018 10:49:29 +0300 Subject: [PATCH 22/40] - fixed applying of alpha to weapon sprites https://forum.zdoom.org/viewtopic.php?t=60638 https://forum.zdoom.org/viewtopic.php?t=60642 --- src/hwrenderer/scene/hw_weapon.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 781f3395a..ed71ceb11 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -252,14 +252,13 @@ bool HUDSprite::GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t * auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha); visstyle_t vis; - float trans = 0.f; vis.RenderStyle = STYLE_Count; vis.Alpha = rs.second; vis.Invert = false; playermo->AlterWeaponSprite(&vis); - if (!(psp->Flags & PSPF_FORCEALPHA)) trans = vis.Alpha; + alpha = (psp->Flags & PSPF_FORCEALPHA) ? 0.f : vis.Alpha; if (vis.RenderStyle != STYLE_Count && !(psp->Flags & PSPF_FORCESTYLE)) { @@ -303,14 +302,10 @@ bool HUDSprite::GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t * { alpha = 1.f; } - else if (trans == 0.f) + else if (alpha == 0.f) { alpha = vis.Alpha; } - else - { - alpha = trans; - } if (!RenderStyle.IsVisible(alpha)) return false; // if it isn't visible skip the rest. PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; From 31263eeac214590ad9ebfcd18f2e7cb890bed8f6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 10:49:24 +0200 Subject: [PATCH 23/40] - removed gl_drawinfo-> from FDrawInfo member functions and pass it to some other functions as a parameter. This really shouldn't be handled as a global variable. The mere fact that several member functions used it incorrectly is ample proof of that. --- src/gl/compatibility/gl_20.cpp | 58 +++++++++++++++++----------------- src/gl/scene/gl_drawinfo.cpp | 4 +-- src/gl/scene/gl_flats.cpp | 16 +++++----- src/gl/scene/gl_portal.cpp | 12 +++---- src/gl/scene/gl_portal.h | 2 +- src/gl/scene/gl_scene.cpp | 58 +++++++++++++++++----------------- src/gl/scene/gl_scenedrawer.h | 8 ++--- src/gl/scene/gl_sprite.cpp | 2 +- src/gl/scene/gl_walls_draw.cpp | 4 +-- 9 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 5ff6c7710..0f75ba467 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -586,7 +586,7 @@ bool FDrawInfo::PutFlatCompat(GLFlat *flat, bool fog) int list = list_indices[masked][foggy]; - auto newflat = gl_drawinfo->dldrawlists[list].NewFlat(); + auto newflat = dldrawlists[list].NewFlat(); *newflat = *flat; return true; } @@ -720,7 +720,7 @@ void FDrawInfo::DrawLightsCompat(GLFlat *flat, int pass) for (int i = 0; isector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub->Index()] & flat->renderflags) + if (ss_renderflags[sub->Index()] & flat->renderflags) { DrawSubsectorLights(flat, sub, pass); } @@ -730,8 +730,8 @@ void FDrawInfo::DrawLightsCompat(GLFlat *flat, int pass) if (!(flat->renderflags&SSRF_RENDER3DPLANES)) { gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR) ? - gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum); + GetOtherFloorPlanes(flat->sector->sectornum) : + GetOtherCeilingPlanes(flat->sector->sectornum); while (node) { @@ -854,7 +854,7 @@ void FDrawInfo::RenderLightsCompat(GLWall *wall, int pass) // //========================================================================== -void GLSceneDrawer::RenderMultipassStuff() +void GLSceneDrawer::RenderMultipassStuff(FDrawInfo *di) { // First pass: empty background with sector light only @@ -864,8 +864,8 @@ void GLSceneDrawer::RenderMultipassStuff() gl_RenderState.EnableTexture(false); gl_RenderState.EnableBrightmap(false); gl_RenderState.Apply(); - gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_ALL); - gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_ALL); + di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_ALL); + di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_ALL); // Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show // This creates a blank surface that only fills the nontransparent parts of the texture @@ -873,18 +873,18 @@ void GLSceneDrawer::RenderMultipassStuff() gl_RenderState.SetTextureMode(TM_MASK); gl_RenderState.EnableBrightmap(true); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_ALL); - gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_ALL); + di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_ALL); + di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_ALL); // Part 3: The base of fogged surfaces, including the texture gl_RenderState.EnableBrightmap(false); gl_RenderState.SetTextureMode(TM_MODULATE); gl_RenderState.AlphaFunc(GL_GEQUAL, 0); - gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(gl_drawinfo, GLPASS_ALL); - gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(gl_drawinfo, GLPASS_ALL); + di->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(di, GLPASS_ALL); + di->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(di, GLPASS_ALL); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(gl_drawinfo, GLPASS_ALL); - gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(gl_drawinfo, GLPASS_ALL); + di->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(di, GLPASS_ALL); + di->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(di, GLPASS_ALL); // second pass: draw lights glDepthMask(false); @@ -895,10 +895,10 @@ void GLSceneDrawer::RenderMultipassStuff() gl_RenderState.BlendFunc(GL_ONE, GL_ONE); glDepthFunc(GL_EQUAL); if (level.lightmode == 8) gl_RenderState.SetSoftLightLevel(255); - gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX); - gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX); - gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX); - gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX); + di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_LIGHTTEX); + di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_LIGHTTEX); + di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_LIGHTTEX); + di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_LIGHTTEX); gl_RenderState.BlendEquation(GL_FUNC_ADD); } else gl_lights = false; @@ -910,11 +910,11 @@ void GLSceneDrawer::RenderMultipassStuff() gl_RenderState.EnableFog(false); gl_RenderState.AlphaFunc(GL_GEQUAL, 0); glDepthFunc(GL_LEQUAL); - gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_TEXONLY); - gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_TEXONLY); + di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_TEXONLY); + di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_TEXONLY); gl_RenderState.AlphaFunc(GL_GREATER, gl_mask_threshold); - gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_TEXONLY); - gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_TEXONLY); + di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_TEXONLY); + di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_TEXONLY); // fourth pass: additive lights gl_RenderState.EnableFog(true); @@ -922,14 +922,14 @@ void GLSceneDrawer::RenderMultipassStuff() glDepthFunc(GL_EQUAL); if (gl_SetupLightTexture()) { - gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY); - gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY); - gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY); - gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY); + di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_LIGHTTEX_ADDITIVE); + di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_LIGHTTEX_ADDITIVE); + di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_LIGHTTEX_ADDITIVE); + di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_LIGHTTEX_ADDITIVE); + di->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(di, GLPASS_LIGHTTEX_FOGGY); + di->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(di, GLPASS_LIGHTTEX_FOGGY); + di->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(di, GLPASS_LIGHTTEX_FOGGY); + di->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(di, GLPASS_LIGHTTEX_FOGGY); } else gl_lights = false; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index b9ee2067d..ccd6567ce 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -81,13 +81,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head) DoDrawSorted(dl, head->left); gl_RenderState.SetClipSplit(clipsplit); } - dl->DoDraw(gl_drawinfo, GLPASS_TRANSLUCENT, head->itemindex, true); + dl->DoDraw(this, GLPASS_TRANSLUCENT, head->itemindex, true); if (head->equal) { SortNode * ehead=head->equal; while (ehead) { - dl->DoDraw(gl_drawinfo, GLPASS_TRANSLUCENT, ehead->itemindex, true); + dl->DoDraw(this, GLPASS_TRANSLUCENT, ehead->itemindex, true); ehead=ehead->equal; } } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index ff55d1161..380271989 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -141,7 +141,7 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) for (int i=0; i< flat->sector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans) + if (ss_renderflags[sub->Index()]& flat->renderflags || istrans) { SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); } @@ -151,8 +151,8 @@ void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) if (!(flat->renderflags&SSRF_RENDER3DPLANES)) { gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR)? - gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum); + GetOtherFloorPlanes(flat->sector->sectornum) : + GetOtherCeilingPlanes(flat->sector->sectornum); while (node) { @@ -182,7 +182,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool { subsector_t * sub = flat->sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans) + if (ss_renderflags[sub->Index()]& flat->renderflags || istrans) { if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli); drawcalls.Clock(); @@ -201,7 +201,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool for (int i=0; isector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; - if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans) + if (ss_renderflags[sub->Index()]& flat->renderflags || istrans) { if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli); DrawSubsector(flat, sub); @@ -213,8 +213,8 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool if (!(flat->renderflags&SSRF_RENDER3DPLANES)) { gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR)? - gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) : - gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum); + GetOtherFloorPlanes(flat->sector->sectornum) : + GetOtherCeilingPlanes(flat->sector->sectornum); while (node) { @@ -399,7 +399,7 @@ void FDrawInfo::AddFlat(GLFlat *flat, bool fog) bool masked = flat->gltexture->isMasked() && ((flat->renderflags&SSRF_RENDER3DPLANES) || flat->stack); list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS; } - auto newflat = gl_drawinfo->drawlists[list].NewFlat(); + auto newflat = drawlists[list].NewFlat(); *newflat = *flat; } diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e5c1064af..12683c2d2 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -688,7 +688,7 @@ GLSectorStackPortal::~GLSectorStackPortal() // //----------------------------------------------------------------------------- -static uint8_t SetCoverage(void *node) +static uint8_t SetCoverage(FDrawInfo *di, void *node) { if (level.nodes.Size() == 0) { @@ -697,18 +697,18 @@ static uint8_t SetCoverage(void *node) if (!((size_t)node & 1)) // Keep going until found a subsector { node_t *bsp = (node_t *)node; - uint8_t coverage = SetCoverage(bsp->children[0]) | SetCoverage(bsp->children[1]); + uint8_t coverage = SetCoverage(di, bsp->children[0]) | SetCoverage(di, bsp->children[1]); gl_drawinfo->no_renderflags[bsp->Index()] = coverage; return coverage; } else { subsector_t *sub = (subsector_t *)((uint8_t *)node - 1); - return gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN; + return di->ss_renderflags[sub->Index()] & SSRF_SEEN; } } -void GLSectorStackPortal::SetupCoverage() +void GLSectorStackPortal::SetupCoverage(FDrawInfo *di) { for(unsigned i=0; iss_renderflags[dsub->Index()] |= SSRF_SEEN; } } - SetCoverage(::level.HeadNode()); + SetCoverage(di, ::level.HeadNode()); } //----------------------------------------------------------------------------- @@ -742,7 +742,7 @@ void GLSectorStackPortal::DrawContents() drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SaveMapSection(); - SetupCoverage(); + SetupCoverage(gl_drawinfo); ClearClipper(); // If the viewpoint is not within the portal, we need to invalidate the entire clip area. diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 628ea4614..5e5d02387 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -302,7 +302,7 @@ public: { origin=pt; } - void SetupCoverage(); + void SetupCoverage(FDrawInfo *di); void AddSubsector(subsector_t *sub) { subsectors.Push(sub); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 70350b018..9b0719679 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -253,7 +253,7 @@ void GLSceneDrawer::CreateScene() SetView(); validcount++; // used for processing sidedefs only once by the renderer. - + gl_drawinfo->clipPortal = !!GLRenderer->mClipPortal; gl_drawinfo->mAngles = GLRenderer->mAngles; gl_drawinfo->mViewVector = GLRenderer->mViewVector; @@ -289,7 +289,7 @@ void GLSceneDrawer::CreateScene() // //----------------------------------------------------------------------------- -void GLSceneDrawer::RenderScene(int recursion) +void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion) { RenderAll.Clock(); @@ -303,11 +303,11 @@ void GLSceneDrawer::RenderScene(int recursion) if (gl_sort_textures) { - gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls(); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats(); - gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls(); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats(); - gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); + di->drawlists[GLDL_PLAINWALLS].SortWalls(); + di->drawlists[GLDL_PLAINFLATS].SortFlats(); + di->drawlists[GLDL_MASKEDWALLS].SortWalls(); + di->drawlists[GLDL_MASKEDFLATS].SortFlats(); + di->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); } // if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front, @@ -315,10 +315,10 @@ void GLSceneDrawer::RenderScene(int recursion) if (gl.lightmethod == LM_DEFERRED && level.HasDynamicLights && FixedColormap == CM_DEFAULT) { GLRenderer->mLights->Begin(); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(gl_drawinfo, GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(gl_drawinfo, GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(gl_drawinfo, GLPASS_LIGHTSONLY); - gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(gl_drawinfo, GLPASS_LIGHTSONLY, true); + di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, GLPASS_LIGHTSONLY); + di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, GLPASS_LIGHTSONLY); + di->drawlists[GLDL_TRANSLUCENTBORDER].Draw(di, GLPASS_LIGHTSONLY); + di->drawlists[GLDL_TRANSLUCENT].Draw(di, GLPASS_LIGHTSONLY, true); GLRenderer->mLights->Finish(); } @@ -336,7 +336,7 @@ void GLSceneDrawer::RenderScene(int recursion) else // GL 2.x legacy mode { // process everything that needs to handle textured dynamic lights. - if (level.HasDynamicLights) RenderMultipassStuff(); + if (level.HasDynamicLights) RenderMultipassStuff(di); // The remaining lists which are unaffected by dynamic lights are just processed as normal. pass = GLPASS_ALL; @@ -344,8 +344,8 @@ void GLSceneDrawer::RenderScene(int recursion) gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(gl_drawinfo, pass); - gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(gl_drawinfo, pass); + di->drawlists[GLDL_PLAINWALLS].DrawWalls(di, pass); + di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, pass); // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show @@ -355,20 +355,20 @@ void GLSceneDrawer::RenderScene(int recursion) gl_RenderState.SetTextureMode(TM_MASK); } gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(gl_drawinfo, pass); - gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(gl_drawinfo, pass); + di->drawlists[GLDL_MASKEDWALLS].DrawWalls(di, pass); + di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, pass); // Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use. - if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) + if (di->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) { glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); - gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(gl_drawinfo, pass); + di->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(di, pass); glDisable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0, 0); } - gl_drawinfo->drawlists[GLDL_MODELS].Draw(gl_drawinfo, pass); + di->drawlists[GLDL_MODELS].Draw(di, pass); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -377,7 +377,7 @@ void GLSceneDrawer::RenderScene(int recursion) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); glDepthMask(false); - gl_drawinfo->DrawDecals(); + di->DrawDecals(); gl_RenderState.SetTextureMode(TM_MODULATE); @@ -395,7 +395,7 @@ void GLSceneDrawer::RenderScene(int recursion) gl_RenderState.EnableFog(true); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.BlendFunc(GL_ONE,GL_ZERO); - gl_drawinfo->DrawUnhandledMissingTextures(); + di->DrawUnhandledMissingTextures(); glDepthMask(true); glPolygonOffset(0.0f, 0.0f); @@ -478,7 +478,7 @@ void GLSceneDrawer::DrawScene(int drawmode) } GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. - RenderScene(recursion); + RenderScene(gl_drawinfo, recursion); if (applySSAO && gl_RenderState.GetPassType() == GBUFFER_PASS) { @@ -505,7 +505,7 @@ void GLSceneDrawer::DrawScene(int drawmode) //----------------------------------------------------------------------------- -void GLSceneDrawer::EndDrawScene(sector_t * viewsector) +void GLSceneDrawer::EndDrawScene(FDrawInfo *di, sector_t * viewsector) { gl_RenderState.EnableFog(false); @@ -515,7 +515,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector) { // [BB] The HUD model should be drawn over everything else already drawn. glClear(GL_DEPTH_BUFFER_BIT); - gl_drawinfo->DrawPlayerSprites(true); + di->DrawPlayerSprites(true); } glDisable(GL_STENCIL_TEST); @@ -525,7 +525,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector) // Delay drawing psprites until after bloom has been applied, if enabled. if (!FGLRenderBuffers::IsEnabled() || !gl_bloom || FixedColormap != CM_DEFAULT) { - DrawEndScene2D(viewsector); + DrawEndScene2D(di, viewsector); } else { @@ -537,7 +537,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector) } } -void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector) +void GLSceneDrawer::DrawEndScene2D(FDrawInfo *di, sector_t * viewsector) { const bool renderHUDModel = gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); @@ -549,7 +549,7 @@ void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector) glDisable(GL_MULTISAMPLE); - gl_drawinfo->DrawPlayerSprites(false); + di->DrawPlayerSprites(false); if (gl.legacyMode) { @@ -696,11 +696,11 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl FDrawInfo::StartDrawInfo(this); ProcessScene(toscreen); - if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures. + if (mainview && toscreen) EndDrawScene(gl_drawinfo, lviewsector); // do not call this for camera textures. if (mainview && FGLRenderBuffers::IsEnabled()) { - GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(lviewsector); }); + GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(gl_drawinfo, lviewsector); }); // This should be done after postprocessing, not before. GLRenderer->mBuffers->BindCurrentFB(); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index cc712c4ac..9f7f27708 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -20,7 +20,7 @@ class GLSceneDrawer TMap weapondynlightindex; - void RenderMultipassStuff(); + void RenderMultipassStuff(FDrawInfo *di); void UnclipSubsector(subsector_t *sub); void AddLine (seg_t *seg, bool portalclip); @@ -33,7 +33,7 @@ class GLSceneDrawer void DoSubsector(subsector_t * sub); void RenderBSPNode(void *node); - void RenderScene(int recursion); + void RenderScene(FDrawInfo *di, int recursion); void RenderTranslucent(); void CreateScene(); @@ -60,8 +60,8 @@ public: void SetFixedColormap(player_t *player); void DrawScene(int drawmode); void ProcessScene(bool toscreen = false); - void EndDrawScene(sector_t * viewsector); - void DrawEndScene2D(sector_t * viewsector); + void EndDrawScene(FDrawInfo *di, sector_t * viewsector); + void DrawEndScene2D(FDrawInfo *di, sector_t * viewsector); sector_t *RenderViewpoint(AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen); sector_t *RenderView(player_t *player); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 2713cf759..2bafaf72a 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -327,7 +327,7 @@ void FDrawInfo::AddSprite(GLSprite *sprite, bool translucent) list = GLDL_MODELS; } - auto newsprt = gl_drawinfo->drawlists[list].NewSprite(); + auto newsprt = drawlists[list].NewSprite(); *newsprt = *sprite; } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index a49593550..b8a2155c0 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -142,7 +142,7 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); glDepthMask(false); - gl_drawinfo->DrawDecalsForMirror(wall); + DrawDecalsForMirror(wall); glDepthMask(true); glPolygonOffset(0.0f, 0.0f); glDisable(GL_POLYGON_OFFSET_FILL); @@ -293,7 +293,7 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass) case GLPASS_LIGHTTEX: case GLPASS_LIGHTTEX_ADDITIVE: case GLPASS_LIGHTTEX_FOGGY: - gl_drawinfo->RenderLightsCompat(wall, pass); + RenderLightsCompat(wall, pass); break; case GLPASS_TEXONLY: From cc4a09a3d2977685753c51b6df039d2c3883cb34 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 21 May 2018 14:23:30 +0200 Subject: [PATCH 24/40] - fix model interpolation bug --- src/r_data/models/models.cpp | 27 ++++++++------------------- src/r_data/models/models.h | 3 +-- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index ce41e064d..a0b76e581 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -94,8 +94,8 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s if (smf->flags & MDL_ROTATING) { - const double time = smf->rotationSpeed*GetTimeFloat() / 200.; - rotateOffset = double((time - xs_FloorToInt(time)) *360.); + double turns = (I_GetTime() % 200 + I_GetTimeFrac()) / 200.0; + rotateOffset = turns * 360.0; } // Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing. @@ -164,7 +164,7 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s objectToWorldMatrix.scale(1, stretch, 1); BeginDrawModel(actor, smf, objectToWorldMatrix); - RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), nullptr, translation); + RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), translation); EndDrawModel(actor, smf); } @@ -200,16 +200,11 @@ void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); BeginDrawHUDModel(playermo, objectToWorldMatrix); - RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0); + RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), 0); EndDrawHUDModel(playermo); } -void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, - const FState *curState, - const int curTics, - const PClass *ti, - Matrix3x4 *normaltransform, - int translation) +void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation) { // [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation // and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame. @@ -225,14 +220,13 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, // [BB] In case the tic counter is frozen we have to leave ticFraction at zero. if (ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN)) { - double time = GetTimeFloat(); - ticFraction = (time - static_cast(time)); + ticFraction = I_GetTimeFrac(); } - inter = static_cast(curState->Tics - curTics - ticFraction) / static_cast(curState->Tics); + inter = static_cast(curState->Tics - curTics + ticFraction) / static_cast(curState->Tics); // [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics. // In this case inter is negative and we need to set it to zero. - if (inter < 0.) + if (curState->Tics < curTics) inter = 0.; else { @@ -279,11 +273,6 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, } } -double FModelRenderer::GetTimeFloat() -{ - return (double)I_msTime() * (double)TICRATE / 1000.; -} - ///////////////////////////////////////////////////////////////////////////// void gl_LoadModels() diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index 91d3d14d6..802f85214 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -73,8 +73,7 @@ public: virtual void DrawElements(int numIndices, size_t offset) = 0; private: - void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, Matrix3x4 *normaltransform, int translation); - static double GetTimeFloat(); + void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation); }; struct FModelVertex From 31abe3df7e108f12a07441221ebddd34ce5198ed Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 21 May 2018 17:52:03 +0200 Subject: [PATCH 25/40] - avoid reusing the same mVBuf pointer for the different renderers as that causes too many problems when switching between them - remove gl_ prefix for model functions that are no longer GL specific --- src/gl/models/gl_models.h | 1 + src/gl/renderer/gl_renderer.cpp | 6 +-- src/gl/scene/gl_scene.cpp | 4 +- src/hwrenderer/scene/hw_sprites.cpp | 4 +- src/hwrenderer/scene/hw_weapon.cpp | 4 +- src/hwrenderer/textures/hw_precache.cpp | 2 +- src/polyrenderer/scene/poly_model.cpp | 8 ---- src/polyrenderer/scene/poly_model.h | 2 + src/polyrenderer/scene/poly_playersprite.cpp | 2 +- src/polyrenderer/scene/poly_sprite.cpp | 2 +- src/r_data/models/models.cpp | 45 +++++++++++--------- src/r_data/models/models.h | 35 +++++++++------ src/r_data/models/models_md2.cpp | 12 +++--- src/r_data/models/models_md3.cpp | 16 ++++--- src/r_data/models/models_ue1.cpp | 11 ++--- src/r_data/models/models_voxel.cpp | 16 ++++--- src/swrenderer/scene/r_opaque_pass.cpp | 2 +- src/swrenderer/things/r_model.cpp | 8 ---- src/swrenderer/things/r_model.h | 2 + src/swrenderer/things/r_playersprite.cpp | 2 +- 20 files changed, 94 insertions(+), 90 deletions(-) diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index f9458890a..821705c34 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -36,6 +36,7 @@ class FGLModelRenderer : public FModelRenderer public: FGLModelRenderer(int mli) : modellightindex(mli) {} + ModelRendererType GetType() const override { return GLModelRendererType; } void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index f8d2ead8f..993d6d1ee 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -121,9 +121,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mCustomPostProcessShaders = nullptr; } -void gl_LoadModels(); -void gl_FlushModels(); - void FGLRenderer::Initialize(int width, int height) { mBuffers = new FGLRenderBuffers(); @@ -175,7 +172,6 @@ void FGLRenderer::Initialize(int width, int height) SetupLevel(); mShaderManager = new FShaderManager; mSamplerManager = new FSamplerManager; - gl_LoadModels(); GLPortal::Initialize(); } @@ -184,7 +180,7 @@ FGLRenderer::~FGLRenderer() { GLPortal::Shutdown(); - gl_FlushModels(); + FlushModels(); AActor::DeleteAllAttachedLights(); FMaterial::FlushAll(); if (legacyShaders) delete legacyShaders; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 70350b018..eadd940b7 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -510,7 +510,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector) gl_RenderState.EnableFog(false); // [BB] HUD models need to be rendered here. - const bool renderHUDModel = gl_IsHUDModelForPlayerAvailable( players[consoleplayer].camera->player ); + const bool renderHUDModel = IsHUDModelForPlayerAvailable( players[consoleplayer].camera->player ); if ( renderHUDModel ) { // [BB] The HUD model should be drawn over everything else already drawn. @@ -539,7 +539,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector) void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector) { - const bool renderHUDModel = gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); + const bool renderHUDModel = IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); // This should be removed once all 2D stuff is really done through the 2D interface. gl_RenderState.mViewMatrix.loadIdentity(); diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 6814d1760..7db0fb335 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -448,7 +448,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // exclude vertically moving objects from this check. if (!thing->Vel.isZero()) { - if (!gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, false)) + if (!FindModelFrame(thing->GetClass(), spritenum, thing->frame, false)) { return; } @@ -509,7 +509,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t z += fz; } - modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); + modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); if (!modelframe) { bool mirror; diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index ed71ceb11..c22d2183a 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -425,7 +425,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area) bool brightflash = false; AActor * playermo = players[consoleplayer].camera; player_t * player = playermo->player; - const bool hudModelStep = gl_IsHUDModelForPlayerAvailable(player); + const bool hudModelStep = IsHUDModelForPlayerAvailable(player); AActor *camera = r_viewpoint.camera; @@ -448,7 +448,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area) for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { if (!psp->GetState()) continue; - FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr; + FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr; // This is an 'either-or' proposition. This maybe needs some work to allow overlays with weapon models but as originally implemented this just won't work. if (smf && !hudModelStep) continue; if (!smf && hudModelStep) continue; diff --git a/src/hwrenderer/textures/hw_precache.cpp b/src/hwrenderer/textures/hw_precache.cpp index a40a8a821..a6342d2fb 100644 --- a/src/hwrenderer/textures/hw_precache.cpp +++ b/src/hwrenderer/textures/hw_precache.cpp @@ -119,7 +119,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { auto &state = cls->GetStates()[i]; spritelist[state.sprite].Insert(gltrans, true); - FSpriteModelFrame * smf = gl_FindModelFrame(cls, state.sprite, state.Frame, false); + FSpriteModelFrame * smf = FindModelFrame(cls, state.sprite, state.Frame, false); if (smf != NULL) { for (int i = 0; i < MAX_MODELS_PER_FRAME; i++) diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index bb0c3fb52..ac29af9bb 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -33,9 +33,6 @@ #include "actorinlines.h" #include "i_time.h" -void gl_FlushModels(); -bool polymodelsInUse; - void PolyRenderModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) { PolyModelRenderer renderer(thread, worldToClip, stencilValue); @@ -52,11 +49,6 @@ void PolyRenderHUDModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint PolyModelRenderer::PolyModelRenderer(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue) : Thread(thread), WorldToClip(worldToClip), StencilValue(stencilValue) { - if (!polymodelsInUse) - { - gl_FlushModels(); - polymodelsInUse = true; - } } void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) diff --git a/src/polyrenderer/scene/poly_model.h b/src/polyrenderer/scene/poly_model.h index cc12f9e6e..cbfafce59 100644 --- a/src/polyrenderer/scene/poly_model.h +++ b/src/polyrenderer/scene/poly_model.h @@ -34,6 +34,8 @@ class PolyModelRenderer : public FModelRenderer public: PolyModelRenderer(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue); + ModelRendererType GetType() const override { return PolyModelRendererType; } + void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index c7d75ef33..e08857de9 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -60,7 +60,7 @@ void RenderPolyPlayerSprites::Render(PolyRenderThread *thread) (r_deathcamera && viewpoint.camera->health <= 0)) return; - renderHUDModel = r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); + renderHUDModel = r_models && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); PolyTransferHeights fakeflat(viewpoint.camera->subsector); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 12406b5c0..88ffb99b6 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -78,7 +78,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, AActor *thing, subsector { int spritenum = thing->sprite; bool isPicnumOverride = thing->picnum.isValid(); - FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); + FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); if (modelframe) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index a0b76e581..23b517352 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -171,7 +171,7 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) { AActor * playermo = players[consoleplayer].camera; - FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false); + FSpriteModelFrame *smf = FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false); // [BB] No model found for this sprite, so we can't render anything. if (smf == nullptr) @@ -247,7 +247,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FStat } } if (inter != 0.0) - smfNext = gl_FindModelFrame(ti, nextState->sprite, nextState->Frame, false); + smfNext = FindModelFrame(ti, nextState->sprite, nextState->Frame, false); } } } @@ -259,7 +259,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FStat FModel * mdl = Models[smf->modelIDs[i]]; FTexture *tex = smf->skinIDs[i].isValid() ? TexMan(smf->skinIDs[i]) : nullptr; mdl->BuildVertexBuffer(this); - SetVertexBuffer(mdl->mVBuf); + SetVertexBuffer(mdl->GetVertexBuffer(this)); mdl->PushSpriteMDLFrame(smf, i); @@ -275,17 +275,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FStat ///////////////////////////////////////////////////////////////////////////// -void gl_LoadModels() -{ - /* - for (int i = Models.Size() - 1; i >= 0; i--) - { - Models[i]->BuildVertexBuffer(); - } - */ -} - -void gl_FlushModels() +void FlushModels() { for (int i = Models.Size() - 1; i >= 0; i--) { @@ -295,9 +285,24 @@ void gl_FlushModels() ///////////////////////////////////////////////////////////////////////////// +FModel::FModel() +{ + for (int i = 0; i < NumModelRendererTypes; i++) + mVBuf[i] = nullptr; +} + FModel::~FModel() { - if (mVBuf != nullptr) delete mVBuf; + DestroyVertexBuffer(); +} + +void FModel::DestroyVertexBuffer() +{ + for (int i = 0; i < NumModelRendererTypes; i++) + { + delete mVBuf[i]; + mVBuf[i] = nullptr; + } } static TArray SpriteModelFrames; @@ -842,11 +847,11 @@ void gl_InitModels() //=========================================================================== // -// gl_FindModelFrame +// FindModelFrame // //=========================================================================== -FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped) +FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped) { if (GetDefaultByType(ti)->hasmodel) { @@ -887,11 +892,11 @@ FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, //=========================================================================== // -// gl_IsHUDModelForPlayerAvailable +// IsHUDModelForPlayerAvailable // //=========================================================================== -bool gl_IsHUDModelForPlayerAvailable (player_t * player) +bool IsHUDModelForPlayerAvailable (player_t * player) { if (player == nullptr || player->ReadyWeapon == nullptr) return false; @@ -902,7 +907,7 @@ bool gl_IsHUDModelForPlayerAvailable (player_t * player) return false; FState* state = psp->GetState(); - FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); + FSpriteModelFrame *smf = FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); return ( smf != nullptr ); } diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index 802f85214..b0d0f0230 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -46,6 +46,14 @@ FTextureID LoadSkin(const char * path, const char * fn); struct FSpriteModelFrame; class IModelVertexBuffer; +enum ModelRendererType +{ + GLModelRendererType, + SWModelRendererType, + PolyModelRendererType, + NumModelRendererTypes +}; + class FModelRenderer { public: @@ -54,6 +62,8 @@ public: void RenderModel(float x, float y, float z, FSpriteModelFrame *modelframe, AActor *actor); void RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); + virtual ModelRendererType GetType() const = 0; + virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) = 0; virtual void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) = 0; @@ -122,11 +132,7 @@ public: class FModel { public: - - FModel() - { - mVBuf = NULL; - } + FModel(); virtual ~FModel(); virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0; @@ -134,19 +140,20 @@ public: virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0; virtual void AddSkins(uint8_t *hitlist) = 0; - void DestroyVertexBuffer() - { - delete mVBuf; - mVBuf = NULL; - } virtual float getAspectFactor() { return 1.f; } + void SetVertexBuffer(FModelRenderer *renderer, IModelVertexBuffer *buffer) { mVBuf[renderer->GetType()] = buffer; } + IModelVertexBuffer *GetVertexBuffer(FModelRenderer *renderer) const { return mVBuf[renderer->GetType()]; } + void DestroyVertexBuffer(); + const FSpriteModelFrame *curSpriteMDLFrame; int curMDLIndex; void PushSpriteMDLFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; }; - IModelVertexBuffer *mVBuf; FString mFileName; + +private: + IModelVertexBuffer *mVBuf[NumModelRendererTypes]; }; class FDMDModel : public FModel @@ -472,9 +479,9 @@ struct FSpriteModelFrame float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float. }; -FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); - -bool gl_IsHUDModelForPlayerAvailable (player_t * player); +FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); +bool IsHUDModelForPlayerAvailable(player_t * player); +void FlushModels(); class DeletingModelArray : public TArray { diff --git a/src/r_data/models/models_md2.cpp b/src/r_data/models/models_md2.cpp index 999e0cd82..ce9566a8f 100644 --- a/src/r_data/models/models_md2.cpp +++ b/src/r_data/models/models_md2.cpp @@ -279,15 +279,17 @@ FDMDModel::~FDMDModel() void FDMDModel::BuildVertexBuffer(FModelRenderer *renderer) { - if (mVBuf == NULL) + if (!GetVertexBuffer(renderer)) { LoadGeometry(); int VertexBufferSize = info.numFrames * lodInfo[0].numTriangles * 3; unsigned int vindex = 0; - mVBuf = renderer->CreateVertexBuffer(false, info.numFrames == 1); - FModelVertex *vertptr = mVBuf->LockVertexBuffer(VertexBufferSize); + auto vbuf = renderer->CreateVertexBuffer(false, info.numFrames == 1); + SetVertexBuffer(renderer, vbuf); + + FModelVertex *vertptr = vbuf->LockVertexBuffer(VertexBufferSize); for (int i = 0; i < info.numFrames; i++) { @@ -313,7 +315,7 @@ void FDMDModel::BuildVertexBuffer(FModelRenderer *renderer) tri++; } } - mVBuf->UnlockVertexBuffer(); + vbuf->UnlockVertexBuffer(); UnloadGeometry(); } } @@ -368,7 +370,7 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame renderer->SetInterpolation(inter); renderer->SetMaterial(skin, false, translation); - mVBuf->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3); + GetVertexBuffer(renderer)->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3); renderer->DrawArrays(0, lodInfo[0].numTriangles * 3); renderer->SetInterpolation(0.f); } diff --git a/src/r_data/models/models_md3.cpp b/src/r_data/models/models_md3.cpp index 31f2c31cb..f47ee90cd 100644 --- a/src/r_data/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -237,7 +237,7 @@ void FMD3Model::LoadGeometry() void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) { - if (mVBuf == nullptr) + if (!GetVertexBuffer(renderer)) { LoadGeometry(); @@ -251,9 +251,11 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) ibufsize += 3 * surf->numTriangles; } - mVBuf = renderer->CreateVertexBuffer(true, numFrames == 1); - FModelVertex *vertptr = mVBuf->LockVertexBuffer(vbufsize); - unsigned int *indxptr = mVBuf->LockIndexBuffer(ibufsize); + auto vbuf = renderer->CreateVertexBuffer(true, numFrames == 1); + SetVertexBuffer(renderer, vbuf); + + FModelVertex *vertptr = vbuf->LockVertexBuffer(vbufsize); + unsigned int *indxptr = vbuf->LockIndexBuffer(ibufsize); assert(vertptr != nullptr && indxptr != nullptr); @@ -285,8 +287,8 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) } surf->UnloadGeometry(); } - mVBuf->UnlockVertexBuffer(); - mVBuf->UnlockIndexBuffer(); + vbuf->UnlockVertexBuffer(); + vbuf->UnlockIndexBuffer(); } } @@ -365,7 +367,7 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame } renderer->SetMaterial(surfaceSkin, false, translation); - mVBuf->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices); + GetVertexBuffer(renderer)->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices); renderer->DrawElements(surf->numTriangles * 3, surf->iindex * sizeof(unsigned int)); } renderer->SetInterpolation(0.f); diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index 7cf292d6b..98ea08a19 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -198,7 +198,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FTexture *skin, int frame } } renderer->SetMaterial(sskin,false,translation); - mVBuf->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize); + GetVertexBuffer(renderer)->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize); renderer->DrawArrays(0,vsize); vofs += vsize; } @@ -207,14 +207,15 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FTexture *skin, int frame void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer ) { - if ( mVBuf != NULL ) + if (GetVertexBuffer(renderer)) return; int vsize = 0; for ( int i=0; iCreateVertexBuffer(false,numFrames==1); - FModelVertex *vptr = mVBuf->LockVertexBuffer(vsize); + auto vbuf = renderer->CreateVertexBuffer(false,numFrames==1); + SetVertexBuffer(renderer, vbuf); + FModelVertex *vptr = vbuf->LockVertexBuffer(vsize); int vidx = 0; for ( int i=0; iUnlockVertexBuffer(); + vbuf->UnlockVertexBuffer(); } void FUE1Model::AddSkins( uint8_t *hitlist ) diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 3c9af2374..e25a72613 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -321,19 +321,21 @@ void FVoxelModel::Initialize() void FVoxelModel::BuildVertexBuffer(FModelRenderer *renderer) { - if (mVBuf == NULL) + if (!GetVertexBuffer(renderer)) { Initialize(); - mVBuf = renderer->CreateVertexBuffer(true, true); - FModelVertex *vertptr = mVBuf->LockVertexBuffer(mVertices.Size()); - unsigned int *indxptr = mVBuf->LockIndexBuffer(mIndices.Size()); + auto vbuf = renderer->CreateVertexBuffer(true, true); + SetVertexBuffer(renderer, vbuf); + + FModelVertex *vertptr = vbuf->LockVertexBuffer(mVertices.Size()); + unsigned int *indxptr = vbuf->LockIndexBuffer(mIndices.Size()); memcpy(vertptr, &mVertices[0], sizeof(FModelVertex)* mVertices.Size()); memcpy(indxptr, &mIndices[0], sizeof(unsigned int)* mIndices.Size()); - mVBuf->UnlockVertexBuffer(); - mVBuf->UnlockIndexBuffer(); + vbuf->UnlockVertexBuffer(); + vbuf->UnlockIndexBuffer(); mNumIndices = mIndices.Size(); // delete our temporary buffers @@ -398,7 +400,7 @@ float FVoxelModel::getAspectFactor() void FVoxelModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation) { renderer->SetMaterial(skin, true, translation); - mVBuf->SetupFrame(renderer, 0, 0, 0); + GetVertexBuffer(renderer)->SetupFrame(renderer, 0, 0, 0); renderer->DrawElements(mNumIndices, 0); } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 14e42379d..5a88c8086 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -962,7 +962,7 @@ namespace swrenderer { int spritenum = thing->sprite; bool isPicnumOverride = thing->picnum.isValid(); - FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); + FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); if (modelframe && (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared() < model_distance_cull) { DVector3 pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac); diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 8040797b5..fe5769262 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -34,9 +34,6 @@ #include "swrenderer/viewport/r_viewport.h" #include "swrenderer/scene/r_light.h" -void gl_FlushModels(); -extern bool polymodelsInUse; - namespace swrenderer { void RenderModel::Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) @@ -83,11 +80,6 @@ namespace swrenderer SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor) { - if (polymodelsInUse) - { - gl_FlushModels(); - polymodelsInUse = false; - } } void SWModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) diff --git a/src/swrenderer/things/r_model.h b/src/swrenderer/things/r_model.h index 0519d5588..004636e69 100644 --- a/src/swrenderer/things/r_model.h +++ b/src/swrenderer/things/r_model.h @@ -54,6 +54,8 @@ namespace swrenderer public: SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor); + ModelRendererType GetType() const override { return SWModelRendererType; } + void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index acb521500..e1156f4fd 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -94,7 +94,7 @@ namespace swrenderer (r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0)) return; - renderHUDModel = r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); + renderHUDModel = r_models && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); FDynamicColormap *basecolormap; CameraLight *cameraLight = CameraLight::Instance(); From e6a447eb6fe7f4f6d9f084d0262e871e4af25d17 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 20:28:12 +0200 Subject: [PATCH 26/40] - removed more occurences of gl_drawinfo. --- src/gl/scene/gl_drawinfo.cpp | 3 ++- src/gl/scene/gl_drawinfo.h | 2 +- src/gl/scene/gl_portal.cpp | 50 +++++++++++++++++------------------ src/gl/scene/gl_portal.h | 29 ++++++++++---------- src/gl/scene/gl_scene.cpp | 50 +++++++++++++++++------------------ src/gl/scene/gl_scenedrawer.h | 8 +++--- src/gl/scene/gl_skydome.cpp | 2 +- 7 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index ccd6567ce..dc39e3ecb 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -191,12 +191,13 @@ FDrawInfo::~FDrawInfo() // Sets up a new drawinfo struct // //========================================================================== -void FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) +FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) { FDrawInfo *di=di_list.GetNew(); di->mDrawer = drawer; di->FixedColormap = drawer->FixedColormap; di->StartScene(); + return di; } void FDrawInfo::StartScene() diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 05ca3dd8d..a2bf52d1f 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -135,7 +135,7 @@ struct FDrawInfo : public HWDrawInfo void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override; int ClipPoint(const DVector3 &pos) override; - static void StartDrawInfo(GLSceneDrawer *drawer); + static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer); static void EndDrawInfo(); gl_subsectorrendernode * GetOtherFloorPlanes(unsigned int sector) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 12683c2d2..e6fdc54b7 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -41,7 +41,6 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/data/gl_vertexbuffer.h" #include "hwrenderer/scene/hw_clipper.h" -#include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/stereo3d/scoped_color_mask.h" @@ -160,8 +159,9 @@ void GLPortal::DrawPortalStencil() // //----------------------------------------------------------------------------- -bool GLPortal::Start(bool usestencil, bool doquery) +bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) { + *pDi = nullptr; rendered_portals++; Clocker c(PortalAll); if (usestencil) @@ -228,7 +228,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) return false; } } - FDrawInfo::StartDrawInfo(drawer); + *pDi = FDrawInfo::StartDrawInfo(drawer); } else { @@ -256,7 +256,7 @@ bool GLPortal::Start(bool usestencil, bool doquery) { if (NeedDepthBuffer()) { - FDrawInfo::StartDrawInfo(drawer); + *pDi = FDrawInfo::StartDrawInfo(drawer); } else { @@ -596,7 +596,7 @@ void GLPortal::RestoreMapSection() // //----------------------------------------------------------------------------- -void GLSkyboxPortal::DrawContents() +void GLSkyboxPortal::DrawContents(FDrawInfo *di) { int old_pm = PlaneMirrorMode; int saved_extralight = r_viewpoint.extralight; @@ -637,7 +637,7 @@ void GLSkyboxPortal::DrawContents() SaveMapSection(); drawer->CurrentMapSections.Set(mapsection); - drawer->DrawScene(DM_SKYPORTAL); + drawer->DrawScene(di, DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; inskybox = false; gl_RenderState.SetDepthClamp(oldclamp); @@ -698,7 +698,7 @@ static uint8_t SetCoverage(FDrawInfo *di, void *node) { node_t *bsp = (node_t *)node; uint8_t coverage = SetCoverage(di, bsp->children[0]) | SetCoverage(di, bsp->children[1]); - gl_drawinfo->no_renderflags[bsp->Index()] = coverage; + di->no_renderflags[bsp->Index()] = coverage; return coverage; } else @@ -718,7 +718,7 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di) { subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]]; drawer->CurrentMapSections.Set(dsub->mapsection); - gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN; + di->ss_renderflags[dsub->Index()] |= SSRF_SEEN; } } SetCoverage(di, ::level.HeadNode()); @@ -729,7 +729,7 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di) // GLSectorStackPortal::DrawContents // //----------------------------------------------------------------------------- -void GLSectorStackPortal::DrawContents() +void GLSectorStackPortal::DrawContents(FDrawInfo *di) { FSectorPortalGroup *portal = origin; @@ -742,19 +742,19 @@ void GLSectorStackPortal::DrawContents() drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SaveMapSection(); - SetupCoverage(gl_drawinfo); + SetupCoverage(di); ClearClipper(); // If the viewpoint is not within the portal, we need to invalidate the entire clip area. // The portal will re-validate the necessary parts when its subsectors get traversed. subsector_t *sub = R_PointInSubsector(r_viewpoint.Pos); - if (!(gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN)) + if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN)) { drawer->clipper.SafeAddClipRange(0, ANGLE_MAX); drawer->clipper.SetBlocked(true); } - drawer->DrawScene(DM_PORTAL); + drawer->DrawScene(di, DM_PORTAL); RestoreMapSection(); if (origin->plane != -1) screen->instack[origin->plane]--; @@ -776,7 +776,7 @@ void GLSectorStackPortal::DrawContents() // //----------------------------------------------------------------------------- -void GLPlaneMirrorPortal::DrawContents() +void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di) { if (renderdepth > r_mirror_recursions) { @@ -801,7 +801,7 @@ void GLPlaneMirrorPortal::DrawContents() ClearClipper(); gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f); - drawer->DrawScene(DM_PORTAL); + drawer->DrawScene(di, DM_PORTAL); gl_RenderState.SetClipHeight(0.f, 0.f); PlaneMirrorFlag--; PlaneMirrorMode = old_pm; @@ -897,7 +897,7 @@ int GLLinePortal::ClipPoint(const DVector2 &pos) // R_EnterMirror // //----------------------------------------------------------------------------- -void GLMirrorPortal::DrawContents() +void GLMirrorPortal::DrawContents(FDrawInfo *di) { if (renderdepth>r_mirror_recursions) { @@ -976,7 +976,7 @@ void GLMirrorPortal::DrawContents() gl_RenderState.SetClipLine(linedef); gl_RenderState.EnableClipLine(true); - drawer->DrawScene(DM_PORTAL); + drawer->DrawScene(di, DM_PORTAL); gl_RenderState.EnableClipLine(false); MirrorFlag--; @@ -997,7 +997,7 @@ void GLMirrorPortal::DrawContents() // // //----------------------------------------------------------------------------- -void GLLineToLinePortal::DrawContents() +void GLLineToLinePortal::DrawContents(FDrawInfo *di) { // TODO: Handle recursion more intelligently if (renderdepth>r_mirror_recursions) @@ -1049,14 +1049,14 @@ void GLLineToLinePortal::DrawContents() ClearClipper(); gl_RenderState.SetClipLine(glport->lines[0]->mDestination); gl_RenderState.EnableClipLine(true); - drawer->DrawScene(DM_PORTAL); + drawer->DrawScene(di, DM_PORTAL); gl_RenderState.EnableClipLine(false); RestoreMapSection(); } -void GLLineToLinePortal::RenderAttached() +void GLLineToLinePortal::RenderAttached(FDrawInfo *di) { - gl_drawinfo->ProcessActorsInPortal(glport, gl_drawinfo->mDrawer->in_area); + di->ProcessActorsInPortal(glport, di->mDrawer->in_area); } //----------------------------------------------------------------------------- @@ -1145,7 +1145,7 @@ GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, bool local) // GLHorizonPortal::DrawContents // //----------------------------------------------------------------------------- -void GLHorizonPortal::DrawContents() +void GLHorizonPortal::DrawContents(FDrawInfo *di) { Clocker c(PortalAll); @@ -1216,7 +1216,7 @@ void GLHorizonPortal::DrawContents() // //----------------------------------------------------------------------------- -void GLEEHorizonPortal::DrawContents() +void GLEEHorizonPortal::DrawContents(FDrawInfo *di) { sector_t *sector = portal->mOrigin; if (sector->GetTexture(sector_t::floor) == skyflatnum || @@ -1225,7 +1225,7 @@ void GLEEHorizonPortal::DrawContents() GLSkyInfo skyinfo; skyinfo.init(sector->sky, 0); GLSkyPortal sky(&skyinfo, true); - sky.DrawContents(); + sky.DrawContents(di); } if (sector->GetTexture(sector_t::ceiling) != skyflatnum) { @@ -1239,7 +1239,7 @@ void GLEEHorizonPortal::DrawContents() horz.plane.Texheight = r_viewpoint.Pos.Z + fabs(horz.plane.Texheight); } GLHorizonPortal ceil(&horz, true); - ceil.DrawContents(); + ceil.DrawContents(di); } if (sector->GetTexture(sector_t::floor) != skyflatnum) { @@ -1253,7 +1253,7 @@ void GLEEHorizonPortal::DrawContents() horz.plane.Texheight = r_viewpoint.Pos.Z - fabs(horz.plane.Texheight); } GLHorizonPortal floor(&horz, true); - floor.DrawContents(); + floor.DrawContents(di); } } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 5e5d02387..707c3d2a4 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -89,9 +89,9 @@ protected: GLPortal(bool local = false) { if (!local) portals.Push(this); } virtual ~GLPortal() { } - bool Start(bool usestencil, bool doquery); + bool Start(bool usestencil, bool doquery, FDrawInfo **pDi); void End(bool usestencil); - virtual void DrawContents()=0; + virtual void DrawContents(FDrawInfo *di)=0; virtual void * GetSource() const =0; // GetSource MUST be implemented! void ClearClipper(); virtual bool IsSky() { return false; } @@ -111,9 +111,10 @@ public: // Start may perform an occlusion query. If that returns 0 there // is no need to draw the stencil's contents and there's also no // need to restore the affected area becasue there is none! - if (Start(usestencil, doquery)) + FDrawInfo *di; + if (Start(usestencil, doquery, &di)) { - DrawContents(); + DrawContents(di); End(usestencil); } } @@ -134,7 +135,7 @@ public: virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } virtual line_t *ClipLine() { return NULL; } - virtual void RenderAttached() {} + virtual void RenderAttached(FDrawInfo *di) {} static void BeginScene(); static void StartFrame(); @@ -205,7 +206,7 @@ struct GLMirrorPortal : public GLLinePortal line_t * linedef; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return linedef; } virtual const char *GetName(); @@ -223,11 +224,11 @@ struct GLLineToLinePortal : public GLLinePortal { FLinePortalSpan *glport; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return glport; } virtual const char *GetName(); virtual line_t *ClipLine() { return line(); } - virtual void RenderAttached(); + virtual void RenderAttached(FDrawInfo *di); public: @@ -244,7 +245,7 @@ struct GLSkyboxPortal : public GLPortal FSectorPortal * portal; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return portal; } virtual bool IsSky() { return true; } virtual const char *GetName(); @@ -266,7 +267,7 @@ struct GLSkyPortal : public GLPortal friend struct GLEEHorizonPortal; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return origin; } virtual bool IsSky() { return true; } virtual bool NeedDepthBuffer() { return false; } @@ -290,7 +291,7 @@ struct GLSectorStackPortal : public GLPortal TArray subsectors; protected: virtual ~GLSectorStackPortal(); - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return origin; } virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one. virtual const char *GetName(); @@ -313,7 +314,7 @@ public: struct GLPlaneMirrorPortal : public GLPortal { protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return origin; } virtual const char *GetName(); virtual void PushState(); @@ -338,7 +339,7 @@ struct GLHorizonPortal : public GLPortal friend struct GLEEHorizonPortal; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return origin; } virtual bool NeedDepthBuffer() { return false; } virtual bool NeedCap() { return false; } @@ -354,7 +355,7 @@ struct GLEEHorizonPortal : public GLPortal FSectorPortal * portal; protected: - virtual void DrawContents(); + virtual void DrawContents(FDrawInfo *di); virtual void * GetSource() const { return portal; } virtual bool NeedDepthBuffer() { return false; } virtual bool NeedCap() { return false; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 9b0719679..c3108a51b 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -234,7 +234,7 @@ void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirr // //----------------------------------------------------------------------------- -void GLSceneDrawer::CreateScene() +void GLSceneDrawer::CreateScene(FDrawInfo *di) { angle_t a1 = FrustumAngle(); InitClipper(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); @@ -254,26 +254,26 @@ void GLSceneDrawer::CreateScene() SetView(); validcount++; // used for processing sidedefs only once by the renderer. - gl_drawinfo->clipPortal = !!GLRenderer->mClipPortal; - gl_drawinfo->mAngles = GLRenderer->mAngles; - gl_drawinfo->mViewVector = GLRenderer->mViewVector; - gl_drawinfo->mViewActor = GLRenderer->mViewActor; - gl_drawinfo->mShadowMap = &GLRenderer->mShadowMap; + di->clipPortal = !!GLRenderer->mClipPortal; + di->mAngles = GLRenderer->mAngles; + di->mViewVector = GLRenderer->mViewVector; + di->mViewActor = GLRenderer->mViewActor; + di->mShadowMap = &GLRenderer->mShadowMap; RenderBSPNode (level.HeadNode()); - gl_drawinfo->PreparePlayerSprites(r_viewpoint.sector, in_area); + di->PreparePlayerSprites(r_viewpoint.sector, in_area); // Process all the sprites on the current portal's back side which touch the portal. - if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(); + if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di); Bsp.Unclock(); // And now the crappy hacks that have to be done to avoid rendering anomalies. // These cannot be multithreaded when the time comes because all these depend // on the global 'validcount' variable. - gl_drawinfo->HandleMissingTextures(in_area); // Missing upper/lower textures - gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water - gl_drawinfo->ProcessSectorStacks(in_area); // merge visplanes of sector stacks + di->HandleMissingTextures(in_area); // Missing upper/lower textures + di->HandleHackedSubsectors(); // open sector hacks for deep water + di->ProcessSectorStacks(in_area); // merge visplanes of sector stacks GLRenderer->mLights->Finish(); GLRenderer->mVBO->Unmap(); @@ -412,7 +412,7 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion) // //----------------------------------------------------------------------------- -void GLSceneDrawer::RenderTranslucent() +void GLSceneDrawer::RenderTranslucent(FDrawInfo *di) { RenderAll.Clock(); @@ -424,8 +424,8 @@ void GLSceneDrawer::RenderTranslucent() gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.EnableBrightmap(true); - gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(gl_drawinfo, GLPASS_TRANSLUCENT); - gl_drawinfo->DrawSorted(GLDL_TRANSLUCENT); + di->drawlists[GLDL_TRANSLUCENTBORDER].Draw(di, GLPASS_TRANSLUCENT); + di->DrawSorted(GLDL_TRANSLUCENT); gl_RenderState.EnableBrightmap(false); @@ -445,7 +445,7 @@ void GLSceneDrawer::RenderTranslucent() // //----------------------------------------------------------------------------- -void GLSceneDrawer::DrawScene(int drawmode) +void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode) { static int recursion=0; static int ssao_portals_available = 0; @@ -469,16 +469,16 @@ void GLSceneDrawer::DrawScene(int drawmode) if (r_viewpoint.camera != nullptr) { ActorRenderFlags savedflags = r_viewpoint.camera->renderflags; - CreateScene(); + CreateScene(di); r_viewpoint.camera->renderflags = savedflags; } else { - CreateScene(); + CreateScene(di); } GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. - RenderScene(gl_drawinfo, recursion); + RenderScene(di, recursion); if (applySSAO && gl_RenderState.GetPassType() == GBUFFER_PASS) { @@ -495,7 +495,7 @@ void GLSceneDrawer::DrawScene(int drawmode) recursion++; GLPortal::EndFrame(); recursion--; - RenderTranslucent(); + RenderTranslucent(di); } //----------------------------------------------------------------------------- @@ -572,7 +572,7 @@ void GLSceneDrawer::DrawEndScene2D(FDrawInfo *di, sector_t * viewsector) // //----------------------------------------------------------------------------- -void GLSceneDrawer::ProcessScene(bool toscreen) +void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen) { iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; GLPortal::BeginScene(); @@ -581,7 +581,7 @@ void GLSceneDrawer::ProcessScene(bool toscreen) CurrentMapSections.Resize(level.NumMapSections); CurrentMapSections.Zero(); CurrentMapSections.Set(mapsection); - DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); + DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN); } @@ -694,13 +694,13 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false); gl_RenderState.ApplyMatrices(); - FDrawInfo::StartDrawInfo(this); - ProcessScene(toscreen); - if (mainview && toscreen) EndDrawScene(gl_drawinfo, lviewsector); // do not call this for camera textures. + FDrawInfo *di = FDrawInfo::StartDrawInfo(this); + ProcessScene(di, toscreen); + if (mainview && toscreen) EndDrawScene(di, lviewsector); // do not call this for camera textures. if (mainview && FGLRenderBuffers::IsEnabled()) { - GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(gl_drawinfo, lviewsector); }); + GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(di, lviewsector); }); // This should be done after postprocessing, not before. GLRenderer->mBuffers->BindCurrentFB(); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 9f7f27708..dfca8f4fa 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -34,9 +34,9 @@ class GLSceneDrawer void RenderBSPNode(void *node); void RenderScene(FDrawInfo *di, int recursion); - void RenderTranslucent(); + void RenderTranslucent(FDrawInfo *di); - void CreateScene(); + void CreateScene(FDrawInfo *di); public: GLSceneDrawer() @@ -58,8 +58,8 @@ public: void Set3DViewport(bool mainview); void Reset3DViewport(); void SetFixedColormap(player_t *player); - void DrawScene(int drawmode); - void ProcessScene(bool toscreen = false); + void DrawScene(FDrawInfo *di, int drawmode); + void ProcessScene(FDrawInfo *di, bool toscreen = false); void EndDrawScene(FDrawInfo *di, sector_t * viewsector); void DrawEndScene2D(FDrawInfo *di, sector_t * viewsector); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index a476d2ab3..38a70ea33 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -271,7 +271,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool // // //----------------------------------------------------------------------------- -void GLSkyPortal::DrawContents() +void GLSkyPortal::DrawContents(FDrawInfo *di) { bool drawBoth = false; From 5f87e81b6aad426fc5de65741411c186de56e73c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 22:04:29 +0200 Subject: [PATCH 27/40] - moved CurrentMapSections and in_area from GLSceneDrawer to HWDrawInfo. Not only are they better placed in the common code, but they are also both per-viewpoint and not per-scene, so this is a far more suitable place and avoids saving and restoring them in the portal code. --- src/gl/scene/gl_bsp.cpp | 18 +++++------ src/gl/scene/gl_drawinfo.cpp | 16 +++------- src/gl/scene/gl_portal.cpp | 42 ++++--------------------- src/gl/scene/gl_portal.h | 4 --- src/gl/scene/gl_scene.cpp | 39 +++++------------------ src/gl/scene/gl_scenedrawer.h | 2 -- src/gl/scene/gl_walls_draw.cpp | 2 +- src/hwrenderer/scene/hw_drawinfo.h | 4 +++ src/hwrenderer/scene/hw_fakeflat.cpp | 24 ++++++++++++++ src/hwrenderer/scene/hw_renderhacks.cpp | 11 +++++++ 10 files changed, 67 insertions(+), 95 deletions(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 2449fce9e..d0a21dfb1 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -140,9 +140,9 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) else { // clipping checks are only needed when the backsector is not the same as the front sector - if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); + if (gl_drawinfo->in_area == area_default) gl_drawinfo->in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); - backsector = hw_FakeFlat(seg->backsector, &bs, in_area, true); + backsector = hw_FakeFlat(seg->backsector, &bs, gl_drawinfo->in_area, true); if (hw_CheckClip(seg->sidedef, currentsector, backsector)) { @@ -364,10 +364,10 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } } // If this thing is in a map section that's not in view it can't possibly be visible - if (CurrentMapSections[thing->subsector->mapsection]) + if (gl_drawinfo->CurrentMapSections[thing->subsector->mapsection]) { GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, in_area, false); + sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, false); } } @@ -386,7 +386,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->mDrawer->in_area, true); + sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, true); } SetupSprite.Unclock(); } @@ -419,7 +419,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) if (!sector) return; // If the mapsections differ this subsector can't possibly be visible from the current view point - if (!CurrentMapSections[sub->mapsection]) return; + if (!gl_drawinfo->CurrentMapSections[sub->mapsection]) return; if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect. if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN) @@ -431,7 +431,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) } if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. - fakesector=hw_FakeFlat(sector, &fake, in_area, false); + fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); if (GLRenderer->mClipPortal) { @@ -497,14 +497,14 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // but undetermined heightsec state. This can only happen if the // subsector is obstructed but not excluded due to a large bounding box. // Due to the way a BSP works such a subsector can never be visible - if (!sector->GetHeightSec() || in_area!=area_default) + if (!sector->GetHeightSec() || gl_drawinfo->in_area!=area_default) { if (sector != sub->render_sector) { sector = sub->render_sector; // the planes of this subsector are faked to belong to another sector // This means we need the heightsec parts and light info of the render sector, not the actual one. - fakesector = hw_FakeFlat(sector, &fake, in_area, false); + fakesector = hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); } uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum]; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index dc39e3ecb..cc697114c 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -204,14 +204,6 @@ void FDrawInfo::StartScene() { ClearBuffers(); - sectorrenderflags.Resize(level.sectors.Size()); - ss_renderflags.Resize(level.subsectors.Size()); - no_renderflags.Resize(level.subsectors.Size()); - - memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); - memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0])); - memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0])); - next = gl_drawinfo; gl_drawinfo = this; for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset(); @@ -393,8 +385,8 @@ void FDrawInfo::FloodUpperGap(seg_t * seg) { wallseg ws; sector_t ffake, bfake; - sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true); - sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false); + sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true); + sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false); vertex_t * v1, * v2; @@ -445,8 +437,8 @@ void FDrawInfo::FloodLowerGap(seg_t * seg) { wallseg ws; sector_t ffake, bfake; - sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true); - sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false); + sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true); + sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false); vertex_t * v1, * v2; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e6fdc54b7..25209848d 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -271,7 +271,6 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) savedshowviewer = r_viewpoint.showviewer; savedAngles = r_viewpoint.Angles; savedviewactor=GLRenderer->mViewActor; - savedviewarea=drawer->in_area; savedviewpath[0] = r_viewpoint.Path[0]; savedviewpath[1] = r_viewpoint.Path[1]; savedvisibility = r_viewpoint.camera ? r_viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0); @@ -340,7 +339,6 @@ void GLPortal::End(bool usestencil) r_viewpoint.ActorPos = savedViewActorPos; r_viewpoint.Angles = savedAngles; GLRenderer->mViewActor=savedviewactor; - drawer->in_area=savedviewarea; if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags = (r_viewpoint.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); @@ -399,7 +397,6 @@ void GLPortal::End(bool usestencil) r_viewpoint.Pos = savedViewPos; r_viewpoint.Angles = savedAngles; GLRenderer->mViewActor=savedviewactor; - drawer->in_area=savedviewarea; if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags |= savedvisibility; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); @@ -560,26 +557,6 @@ GLPortal * GLPortal::FindPortal(const void * src) } -//----------------------------------------------------------------------------- -// -// Save/RestoreMapSection -// -// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene -// -//----------------------------------------------------------------------------- - -void GLPortal::SaveMapSection() -{ - SavedMapSection = std::move(drawer->CurrentMapSections); - drawer->CurrentMapSections.Resize(SavedMapSection.Size()); - drawer->CurrentMapSections.Zero(); -} - -void GLPortal::RestoreMapSection() -{ - drawer->CurrentMapSections = std::move(SavedMapSection); -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // @@ -629,13 +606,13 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) inskybox = true; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); - drawer->SetViewArea(); + di->SetViewArea(); ClearClipper(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - SaveMapSection(); - drawer->CurrentMapSections.Set(mapsection); + di->CurrentMapSections.Zero(); + di->CurrentMapSections.Set(mapsection); drawer->DrawScene(di, DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; @@ -645,8 +622,6 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) PlaneMirrorMode = old_pm; r_viewpoint.extralight = saved_extralight; - - RestoreMapSection(); } //----------------------------------------------------------------------------- @@ -717,7 +692,7 @@ void GLSectorStackPortal::SetupCoverage(FDrawInfo *di) for(int j=0;jportalcoverage[plane].sscount; j++) { subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]]; - drawer->CurrentMapSections.Set(dsub->mapsection); + di->CurrentMapSections.Set(dsub->mapsection); di->ss_renderflags[dsub->Index()] |= SSRF_SEEN; } } @@ -741,7 +716,6 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) if (origin->plane != -1) screen->instack[origin->plane]++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - SaveMapSection(); SetupCoverage(di); ClearClipper(); @@ -755,7 +729,6 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) } drawer->DrawScene(di, DM_PORTAL); - RestoreMapSection(); if (origin->plane != -1) screen->instack[origin->plane]--; } @@ -1031,8 +1004,6 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) } - SaveMapSection(); - for (unsigned i = 0; i < lines.Size(); i++) { line_t *line = lines[i].seg->linedef->getPortalDestination(); @@ -1040,7 +1011,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) if (line->sidedef[0]->Flags & WALLF_POLYOBJ) sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY()); else sub = line->frontsector->subsectors[0]; - drawer->CurrentMapSections.Set(sub->mapsection); + di->CurrentMapSections.Set(sub->mapsection); } GLRenderer->mViewActor = nullptr; @@ -1051,12 +1022,11 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) gl_RenderState.EnableClipLine(true); drawer->DrawScene(di, DM_PORTAL); gl_RenderState.EnableClipLine(false); - RestoreMapSection(); } void GLLineToLinePortal::RenderAttached(FDrawInfo *di) { - di->ProcessActorsInPortal(glport, di->mDrawer->in_area); + di->ProcessActorsInPortal(glport, di->in_area); } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 707c3d2a4..ecab4db22 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -75,11 +75,9 @@ private: DRotator savedAngles; bool savedshowviewer; AActor * savedviewactor; - area_t savedviewarea; ActorRenderFlags savedvisibility; GLPortal *PrevPortal; GLPortal *PrevClipPortal; - BitArray SavedMapSection; TArray mPrimIndices; protected: @@ -99,8 +97,6 @@ protected: virtual bool NeedDepthBuffer() { return true; } void ClearScreen(); virtual const char *GetName() = 0; - void SaveMapSection(); - void RestoreMapSection(); virtual void PushState() {} virtual void PopState() {} diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c3108a51b..c10ba669a 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -92,29 +92,6 @@ angle_t GLSceneDrawer::FrustumAngle() return a1; } -//----------------------------------------------------------------------------- -// -// Sets the area the camera is in -// -//----------------------------------------------------------------------------- -void GLSceneDrawer::SetViewArea() -{ - // The render_sector is better suited to represent the current position in GL - r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector; - - // Get the heightsec state from the render sector, not the current one! - if (r_viewpoint.sector->GetHeightSec()) - { - in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below : - (r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) && - !(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal; - } - else - { - in_area = level.HasHeightSecs? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs. - } -} - //----------------------------------------------------------------------------- // // resets the 3D viewport @@ -261,7 +238,7 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) di->mShadowMap = &GLRenderer->mShadowMap; RenderBSPNode (level.HeadNode()); - di->PreparePlayerSprites(r_viewpoint.sector, in_area); + di->PreparePlayerSprites(r_viewpoint.sector, di->in_area); // Process all the sprites on the current portal's back side which touch the portal. if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di); @@ -271,9 +248,9 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) // These cannot be multithreaded when the time comes because all these depend // on the global 'validcount' variable. - di->HandleMissingTextures(in_area); // Missing upper/lower textures + di->HandleMissingTextures(di->in_area); // Missing upper/lower textures di->HandleHackedSubsectors(); // open sector hacks for deep water - di->ProcessSectorStacks(in_area); // merge visplanes of sector stacks + di->ProcessSectorStacks(di->in_area); // merge visplanes of sector stacks GLRenderer->mLights->Finish(); GLRenderer->mVBO->Unmap(); @@ -578,9 +555,7 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen) GLPortal::BeginScene(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - CurrentMapSections.Resize(level.NumMapSections); - CurrentMapSections.Zero(); - CurrentMapSections.Set(mapsection); + di->CurrentMapSections.Set(mapsection); DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN); } @@ -644,7 +619,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl GLRenderer->mSceneClearColor[1] = 0.0f; GLRenderer->mSceneClearColor[2] = 0.0f; R_SetupFrame (r_viewpoint, r_viewwindow, camera); - SetViewArea(); GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility); @@ -684,6 +658,10 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl Set3DViewport(mainview); GLRenderer->mDrawingScene2D = true; GLRenderer->mCurrentFoV = fov; + + FDrawInfo *di = FDrawInfo::StartDrawInfo(this); + di->SetViewArea(); + // Stereo mode specific perspective projection SetProjection( eye->GetProjection(fov, ratio, fovratio) ); // SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper @@ -694,7 +672,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false); gl_RenderState.ApplyMatrices(); - FDrawInfo *di = FDrawInfo::StartDrawInfo(this); ProcessScene(di, toscreen); if (mainview && toscreen) EndDrawScene(di, lviewsector); // do not call this for camera textures. diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index dfca8f4fa..169cfbc7f 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -46,8 +46,6 @@ public: Clipper clipper; int FixedColormap; - area_t in_area; - BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. angle_t FrustumAngle(); void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index b8a2155c0..2dbe156dd 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -426,7 +426,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype) line_t *otherside = wall->lineportal->lines[0]->mDestination; if (otherside != NULL && otherside->portalindex < level.linePortals.Size()) { - ProcessActorsInPortal(otherside->getPortal()->mGroup, mDrawer->in_area); + ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area); } portal = new GLLineToLinePortal(wall->lineportal); } diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 429981c89..3e57fa21d 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -104,6 +104,9 @@ struct HWDrawInfo TArray ss_renderflags; TArray no_renderflags; + BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. + area_t in_area; + private: // For ProcessLowerMiniseg bool inview; @@ -114,6 +117,7 @@ private: public: void ClearBuffers(); + void SetViewArea(); bool DoOneSectorUpper(subsector_t * subsec, float planez, area_t in_area); bool DoOneSectorLower(subsector_t * subsec, float planez, area_t in_area); diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index 0e22e276f..761379851 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -31,6 +31,8 @@ #include "a_sharedglobal.h" #include "r_sky.h" #include "hw_fakeflat.h" +#include "hw_drawinfo.h" +#include "r_utility.h" //========================================================================== @@ -383,4 +385,26 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac return dest; } +//----------------------------------------------------------------------------- +// +// Sets the area the camera is in +// +//----------------------------------------------------------------------------- +void HWDrawInfo::SetViewArea() +{ + // The render_sector is better suited to represent the current position in GL + r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector; + + // Get the heightsec state from the render sector, not the current one! + if (r_viewpoint.sector->GetHeightSec()) + { + in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below : + (r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) && + !(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal; + } + else + { + in_area = level.HasHeightSecs ? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs. + } +} diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 5eacd9dfc..89352007c 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -72,7 +72,18 @@ void HWDrawInfo::ClearBuffers() HandledSubsectors.Clear(); spriteindex = 0; + CurrentMapSections.Resize(level.NumMapSections); + CurrentMapSections.Zero(); + + sectorrenderflags.Resize(level.sectors.Size()); + ss_renderflags.Resize(level.subsectors.Size()); + no_renderflags.Resize(level.subsectors.Size()); + + memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); + memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0])); + memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0])); } + //========================================================================== // // Adds a subsector plane to a sector's render list From df0b1e8dae87648050562e506473c19549db7bef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 May 2018 22:54:04 +0200 Subject: [PATCH 28/40] - moved the clipper out of GLSceneDrawer and let it be handled by HWDrawInfo. The precise way the clipper needs to be maintained may differ between APIs, so it is no longer owned by any render structure but instead HWDrawInfo only contains a reference. For OpenGL there is still only one static clipper because without multithreaded BSP traversal there is no need for more. --- src/gl/scene/gl_bsp.cpp | 8 +++++--- src/gl/scene/gl_drawinfo.cpp | 6 ++++++ src/gl/scene/gl_portal.cpp | 30 +++++++++++++++--------------- src/gl/scene/gl_portal.h | 2 +- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_scenedrawer.h | 7 ------- src/hwrenderer/scene/hw_drawinfo.h | 2 ++ 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index d0a21dfb1..5e87acc62 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -46,6 +46,7 @@ void GLSceneDrawer::UnclipSubsector(subsector_t *sub) { int count = sub->numlines; seg_t * seg = sub->firstline; + auto &clipper = *gl_drawinfo->mClipper; while (count--) { @@ -88,6 +89,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) if (clipres == PClip_InFront) return; } + auto &clipper = *gl_drawinfo->mClipper; angle_t startAngle = clipper.GetClipAngle(seg->v2); angle_t endAngle = clipper.GetClipAngle(seg->v1); @@ -225,7 +227,7 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!clipper.CheckBox(bsp->bbox[side])) + if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) { return; } @@ -429,7 +431,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // range this subsector spans before going on. UnclipSubsector(sub); } - if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. + if (gl_drawinfo->mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); @@ -575,7 +577,7 @@ void GLSceneDrawer::RenderBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!clipper.CheckBox(bsp->bbox[side])) + if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) { if (!(gl_drawinfo->no_renderflags[bsp->Index()] & SSRF_SEEN)) return; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index cc697114c..93ce4f624 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -191,10 +191,16 @@ FDrawInfo::~FDrawInfo() // Sets up a new drawinfo struct // //========================================================================== + +// OpenGL has no use for multiple clippers so use the same one for all DrawInfos. +static Clipper staticClipper; + FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) { FDrawInfo *di=di_list.GetNew(); di->mDrawer = drawer; + di->mClipper = &staticClipper; + staticClipper.Clear(); di->FixedColormap = drawer->FixedColormap; di->StartScene(); return di; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 25209848d..b90cd3dcd 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -286,14 +286,14 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) } -inline void GLPortal::ClearClipper() +inline void GLPortal::ClearClipper(FDrawInfo *di) { DAngle angleOffset = deltaangle(savedAngles.Yaw, r_viewpoint.Angles.Yaw); - drawer->clipper.Clear(); + di->mClipper->Clear(); // Set the clipper to the minimal visible area - drawer->clipper.SafeAddClipRange(0,0xffffffff); + di->mClipper->SafeAddClipRange(0,0xffffffff); for (unsigned int i = 0; i < lines.Size(); i++) { DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - savedViewPos).Angle() + angleOffset; @@ -301,16 +301,16 @@ inline void GLPortal::ClearClipper() if (deltaangle(endAngle, startAngle) < 0) { - drawer->clipper.SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs()); + di->mClipper->SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs()); } } // and finally clip it to the visible area angle_t a1 = drawer->FrustumAngle(); - if (a1 < ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); + if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); // lock the parts that have just been clipped out. - drawer->clipper.SetSilhouette(); + di->mClipper->SetSilhouette(); } //----------------------------------------------------------------------------- @@ -607,7 +607,7 @@ void GLSkyboxPortal::DrawContents(FDrawInfo *di) inskybox = true; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); di->SetViewArea(); - ClearClipper(); + ClearClipper(di); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; @@ -717,15 +717,15 @@ void GLSectorStackPortal::DrawContents(FDrawInfo *di) drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); SetupCoverage(di); - ClearClipper(); + ClearClipper(di); // If the viewpoint is not within the portal, we need to invalidate the entire clip area. // The portal will re-validate the necessary parts when its subsectors get traversed. subsector_t *sub = R_PointInSubsector(r_viewpoint.Pos); if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN)) { - drawer->clipper.SafeAddClipRange(0, ANGLE_MAX); - drawer->clipper.SetBlocked(true); + di->mClipper->SafeAddClipRange(0, ANGLE_MAX); + di->mClipper->SetBlocked(true); } drawer->DrawScene(di, DM_PORTAL); @@ -771,7 +771,7 @@ void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di) PlaneMirrorFlag++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); - ClearClipper(); + ClearClipper(di); gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f); drawer->DrawScene(di, DM_PORTAL); @@ -938,14 +938,14 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di) MirrorFlag++; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - drawer->clipper.Clear(); + di->mClipper->Clear(); angle_t af = drawer->FrustumAngle(); - if (afclipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af); + if (afmClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af); angle_t a2 = linedef->v1->GetClipAngle(); angle_t a1 = linedef->v2->GetClipAngle(); - drawer->clipper.SafeAddClipRange(a1,a2); + di->mClipper->SafeAddClipRange(a1,a2); gl_RenderState.SetClipLine(linedef); gl_RenderState.EnableClipLine(true); @@ -1017,7 +1017,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) GLRenderer->mViewActor = nullptr; drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); - ClearClipper(); + ClearClipper(di); gl_RenderState.SetClipLine(glport->lines[0]->mDestination); gl_RenderState.EnableClipLine(true); drawer->DrawScene(di, DM_PORTAL); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index ecab4db22..8b4a87f15 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -91,7 +91,7 @@ protected: void End(bool usestencil); virtual void DrawContents(FDrawInfo *di)=0; virtual void * GetSource() const =0; // GetSource MUST be implemented! - void ClearClipper(); + void ClearClipper(FDrawInfo *di); virtual bool IsSky() { return false; } virtual bool NeedCap() { return true; } virtual bool NeedDepthBuffer() { return true; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c10ba669a..78da1e5aa 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -214,7 +214,7 @@ void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirr void GLSceneDrawer::CreateScene(FDrawInfo *di) { angle_t a1 = FrustumAngle(); - InitClipper(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); + di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1); // reset the portal manager GLPortal::StartFrame(); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 169cfbc7f..e6c30239b 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -44,7 +44,6 @@ public: GLPortal::drawer = this; } - Clipper clipper; int FixedColormap; angle_t FrustumAngle(); @@ -65,12 +64,6 @@ public: sector_t *RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void InitClipper(angle_t a1, angle_t a2) - { - clipper.Clear(); - clipper.SafeAddClipRangeRealAngles(a1, a2); - } - void SetView() { viewx = FLOAT2FIXED(r_viewpoint.Pos.X); diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 3e57fa21d..369bfe399 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -14,6 +14,7 @@ class IShadowMap; struct particle_t; struct FDynLightData; struct HUDSprite; +class Clipper; //========================================================================== // @@ -83,6 +84,7 @@ struct HWDrawInfo FVector2 mViewVector; AActor *mViewActor; IShadowMap *mShadowMap; + Clipper *mClipper; TArray MissingUpperTextures; TArray MissingLowerTextures; From 226e8f84da6e4c2bafa02384a10171f5faeb6449 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 May 2018 00:27:39 +0200 Subject: [PATCH 29/40] - most of gl_bsp.cpp moved to HWDrawInfo. Only the vertex buffer update check needs to be done yet. --- src/gl/renderer/gl_renderer.cpp | 1 - src/gl/renderer/gl_renderer.h | 2 +- src/gl/scene/gl_bsp.cpp | 119 ++++++++++++------------ src/gl/scene/gl_drawinfo.cpp | 8 +- src/gl/scene/gl_drawinfo.h | 3 - src/gl/scene/gl_portal.cpp | 14 +-- src/gl/scene/gl_portal.h | 7 +- src/gl/scene/gl_scene.cpp | 9 +- src/gl/scene/gl_scenedrawer.h | 22 ----- src/hwrenderer/scene/hw_drawinfo.h | 24 ++++- src/hwrenderer/scene/hw_portal.h | 10 ++ src/hwrenderer/scene/hw_renderhacks.cpp | 2 + src/hwrenderer/scene/hw_sprites.cpp | 5 +- src/portal.h | 3 + 14 files changed, 113 insertions(+), 116 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index f8d2ead8f..883e5ffe5 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -85,7 +85,6 @@ extern bool NoInterpolateView; FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) { framebuffer = fb; - mClipPortal = nullptr; mCurrentPortal = nullptr; mMirrorCount = 0; mPlaneMirrorCount = 0; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index d3ac02671..7cdf3b01d 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -87,7 +87,7 @@ class FGLRenderer public: OpenGLFrameBuffer *framebuffer; - GLPortal *mClipPortal; + //GLPortal *mClipPortal; GLPortal *mCurrentPortal; int mMirrorCount; int mPlaneMirrorCount; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 5e87acc62..b5bc58e46 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -31,10 +31,13 @@ #include "g_levellocals.h" #include "p_effect.h" #include "po_man.h" +#include "hwrenderer/scene/hw_fakeflat.h" +#include "hwrenderer/scene/hw_clipper.h" +#include "hwrenderer/scene/hw_drawstructs.h" +#include "hwrenderer/scene/hw_drawinfo.h" +#include "hwrenderer/scene/hw_portal.h" +#include "hwrenderer/utility/hw_clock.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_vertexbuffer.h" -#include "gl/scene/gl_scenedrawer.h" EXTERN_CVAR(Bool, gl_render_segs) @@ -42,11 +45,11 @@ CVAR(Bool, gl_render_things, true, 0) CVAR(Bool, gl_render_walls, true, 0) CVAR(Bool, gl_render_flats, true, 0) -void GLSceneDrawer::UnclipSubsector(subsector_t *sub) +void HWDrawInfo::UnclipSubsector(subsector_t *sub) { int count = sub->numlines; seg_t * seg = sub->firstline; - auto &clipper = *gl_drawinfo->mClipper; + auto &clipper = *mClipper; while (count--) { @@ -71,7 +74,7 @@ void GLSceneDrawer::UnclipSubsector(subsector_t *sub) // //========================================================================== -void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) +void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) { #ifdef _DEBUG if (seg->linedef->Index() == 38) @@ -80,16 +83,16 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) } #endif - sector_t * backsector = NULL; + sector_t * backsector = nullptr; sector_t bs; if (portalclip) { - int clipres = GLRenderer->mClipPortal->ClipSeg(seg); + int clipres = mClipPortal->ClipSeg(seg); if (clipres == PClip_InFront) return; } - auto &clipper = *gl_drawinfo->mClipper; + auto &clipper = *mClipper; angle_t startAngle = clipper.GetClipAngle(seg->v2); angle_t endAngle = clipper.GetClipAngle(seg->v1); @@ -99,7 +102,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) return; } - if (seg->sidedef == NULL) + if (seg->sidedef == nullptr) { if (!(currentsubsector->flags & SSECMF_DRAWN)) { @@ -142,9 +145,9 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) else { // clipping checks are only needed when the backsector is not the same as the front sector - if (gl_drawinfo->in_area == area_default) gl_drawinfo->in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); + if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector); - backsector = hw_FakeFlat(seg->backsector, &bs, gl_drawinfo->in_area, true); + backsector = hw_FakeFlat(seg->backsector, &bs, in_area, true); if (hw_CheckClip(seg->sidedef, currentsector, backsector)) { @@ -170,7 +173,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) GLWall wall; wall.sub = currentsubsector; - wall.Process(gl_drawinfo, seg, currentsector, backsector); + wall.Process(this, seg, currentsector, backsector); rendered_lines++; SetupWall.Unclock(); @@ -187,7 +190,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip) // //========================================================================== -void GLSceneDrawer::PolySubsector(subsector_t * sub) +void HWDrawInfo::PolySubsector(subsector_t * sub) { int count = sub->numlines; seg_t * line = sub->firstline; @@ -196,7 +199,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub) { if (line->linedef) { - AddLine (line, GLRenderer->mClipPortal != NULL); + AddLine (line, mClipPortal != nullptr); } line++; } @@ -211,7 +214,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub) // //========================================================================== -void GLSceneDrawer::RenderPolyBSPNode (void *node) +void HWDrawInfo::RenderPolyBSPNode (void *node) { while (!((size_t)node & 1)) // Keep going until found a subsector { @@ -227,7 +230,7 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) + if (!mClipper->CheckBox(bsp->bbox[side])) { return; } @@ -244,15 +247,15 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node) // //========================================================================== -void GLSceneDrawer::AddPolyobjs(subsector_t *sub) +void HWDrawInfo::AddPolyobjs(subsector_t *sub) { - if (sub->BSP == NULL || sub->BSP->bDirty) + if (sub->BSP == nullptr || sub->BSP->bDirty) { sub->BuildPolyBSP(); for (unsigned i = 0; i < sub->BSP->Segs.Size(); i++) { sub->BSP->Segs[i].Subsector = sub; - sub->BSP->Segs[i].PartnerSeg = NULL; + sub->BSP->Segs[i].PartnerSeg = nullptr; } } if (sub->BSP->Nodes.Size() == 0) @@ -272,13 +275,13 @@ void GLSceneDrawer::AddPolyobjs(subsector_t *sub) // //========================================================================== -void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector) +void HWDrawInfo::AddLines(subsector_t * sub, sector_t * sector) { currentsector = sector; currentsubsector = sub; ClipWall.Clock(); - if (sub->polys != NULL) + if (sub->polys != nullptr) { AddPolyobjs(sub); } @@ -289,13 +292,13 @@ void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector) while (count--) { - if (seg->linedef == NULL) + if (seg->linedef == nullptr) { - if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, GLRenderer->mClipPortal != NULL); + if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, mClipPortal != nullptr); } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { - AddLine (seg, GLRenderer->mClipPortal != NULL); + AddLine (seg, mClipPortal != nullptr); } seg++; } @@ -316,7 +319,7 @@ inline bool PointOnLine(const DVector2 &pos, const line_t *line) return fabs(v) <= EQUAL_EPSILON; } -void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line) +void HWDrawInfo::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line) { currentsector = sector; currentsubsector = sub; @@ -327,7 +330,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, while (count--) { - if (seg->linedef != NULL && seg->PartnerSeg != NULL) + if (seg->linedef != nullptr && seg->PartnerSeg != nullptr) { if (PointOnLine(seg->v1->fPos(), line) && PointOnLine(seg->v2->fPos(), line)) AddLine(seg, false); @@ -344,7 +347,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, // //========================================================================== -void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) +void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector) { SetupSprite.Clock(); sector_t * sec=sub->sector; @@ -356,7 +359,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) thing->validcount = validcount; FIntCVar *cvar = thing->GetInfo()->distancecheck; - if (cvar != NULL && *cvar >= 0) + if (cvar != nullptr && *cvar >= 0) { double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared(); double check = (double)**cvar; @@ -366,10 +369,10 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } } // If this thing is in a map section that's not in view it can't possibly be visible - if (gl_drawinfo->CurrentMapSections[thing->subsector->mapsection]) + if (CurrentMapSections[thing->subsector->mapsection]) { GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, false); + sprite.Process(this, thing, sector, in_area, false); } } @@ -377,7 +380,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) { AActor *thing = node->m_thing; FIntCVar *cvar = thing->GetInfo()->distancecheck; - if (cvar != NULL && *cvar >= 0) + if (cvar != nullptr && *cvar >= 0) { double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared(); double check = (double)**cvar; @@ -388,7 +391,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) } GLSprite sprite; - sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->in_area, true); + sprite.Process(this, thing, sector, in_area, true); } SetupSprite.Unclock(); } @@ -403,7 +406,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector) // //========================================================================== -void GLSceneDrawer::DoSubsector(subsector_t * sub) +void HWDrawInfo::DoSubsector(subsector_t * sub) { unsigned int i; sector_t * sector; @@ -421,26 +424,26 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) if (!sector) return; // If the mapsections differ this subsector can't possibly be visible from the current view point - if (!gl_drawinfo->CurrentMapSections[sub->mapsection]) return; + if (!CurrentMapSections[sub->mapsection]) return; if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect. - if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN) + if (ss_renderflags[sub->Index()] & SSRF_SEEN) { // This means that we have reached a subsector in a portal that has been marked 'seen' // from the other side of the portal. This means we must clear the clipper for the // range this subsector spans before going on. UnclipSubsector(sub); } - if (gl_drawinfo->mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. + if (mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet. - fakesector=hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); + fakesector=hw_FakeFlat(sector, &fake, in_area, false); - if (GLRenderer->mClipPortal) + if (mClipPortal) { - int clipres = GLRenderer->mClipPortal->ClipSubsector(sub); + int clipres = mClipPortal->ClipSubsector(sub); if (clipres == PClip_InFront) { - line_t *line = GLRenderer->mClipPortal->ClipLine(); + line_t *line = mClipPortal->ClipLine(); // The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts. if (line) AddSpecialPortalLines(sub, fakesector, line); return; @@ -460,14 +463,14 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) for (i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) { - if (GLRenderer->mClipPortal) + if (mClipPortal) { - int clipres = GLRenderer->mClipPortal->ClipPoint(Particles[i].Pos); + int clipres = mClipPortal->ClipPoint(Particles[i].Pos); if (clipres == PClip_InFront) continue; } GLSprite sprite; - sprite.ProcessParticle(gl_drawinfo, &Particles[i], fakesector); + sprite.ProcessParticle(this, &Particles[i], fakesector); } SetupSprite.Unclock(); } @@ -499,45 +502,43 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // but undetermined heightsec state. This can only happen if the // subsector is obstructed but not excluded due to a large bounding box. // Due to the way a BSP works such a subsector can never be visible - if (!sector->GetHeightSec() || gl_drawinfo->in_area!=area_default) + if (!sector->GetHeightSec() || in_area!=area_default) { if (sector != sub->render_sector) { sector = sub->render_sector; // the planes of this subsector are faked to belong to another sector // This means we need the heightsec parts and light info of the render sector, not the actual one. - fakesector = hw_FakeFlat(sector, &fake, gl_drawinfo->in_area, false); + fakesector = hw_FakeFlat(sector, &fake, in_area, false); } - uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum]; + uint8_t &srf = sectorrenderflags[sub->render_sector->sectornum]; if (!(srf & SSRF_PROCESSED)) { srf |= SSRF_PROCESSED; SetupFlat.Clock(); GLFlat flat; - flat.ProcessSector(gl_drawinfo, fakesector); + flat.ProcessSector(this, fakesector); SetupFlat.Unclock(); } // mark subsector as processed - but mark for rendering only if it has an actual area. - gl_drawinfo->ss_renderflags[sub->Index()] = + ss_renderflags[sub->Index()] = (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; - if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); + if (sub->hacked & 1) AddHackedSubsector(sub); FSectorPortalGroup *portal; portal = fakesector->GetPortalGroup(sector_t::ceiling); - if (portal != NULL) + if (portal != nullptr) { - GLSectorStackPortal *glportal = portal->GetRenderState(); - glportal->AddSubsector(sub); + portal->AddSubsector(sub); } portal = fakesector->GetPortalGroup(sector_t::floor); - if (portal != NULL) + if (portal != nullptr) { - GLSectorStackPortal *glportal = portal->GetRenderState(); - glportal->AddSubsector(sub); + portal->AddSubsector(sub); } } } @@ -556,7 +557,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // //========================================================================== -void GLSceneDrawer::RenderBSPNode (void *node) +void HWDrawInfo::RenderBSPNode (void *node) { if (level.nodes.Size() == 0) { @@ -577,9 +578,9 @@ void GLSceneDrawer::RenderBSPNode (void *node) side ^= 1; // It is not necessary to use the slower precise version here - if (!gl_drawinfo->mClipper->CheckBox(bsp->bbox[side])) + if (!mClipper->CheckBox(bsp->bbox[side])) { - if (!(gl_drawinfo->no_renderflags[bsp->Index()] & SSRF_SEEN)) + if (!(no_renderflags[bsp->Index()] & SSRF_SEEN)) return; } diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 93ce4f624..b67f23fb4 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -44,7 +44,7 @@ #include "gl/renderer/gl_quaddrawer.h" #include "gl/dynlights/gl_lightbuffer.h" -FDrawInfo * gl_drawinfo; +static FDrawInfo * gl_drawinfo; FDrawInfoList di_list; //========================================================================== @@ -504,12 +504,6 @@ void FDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *su portal->GetRenderState()->AddSubsector(sub); } -int FDrawInfo::ClipPoint(const DVector3 &pos) -{ - return GLRenderer->mClipPortal->ClipPoint(pos); -} - - std::pair FDrawInfo::AllocVertices(unsigned int count) { unsigned int index = -1; diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index a2bf52d1f..4ab217bab 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -133,7 +133,6 @@ struct FDrawInfo : public HWDrawInfo // These two may be moved to the API independent part of the renderer later. void ProcessLowerMinisegs(TArray &lowersegs) override; void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override; - int ClipPoint(const DVector3 &pos) override; static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer); static void EndDrawInfo(); @@ -162,8 +161,6 @@ public: }; -extern FDrawInfo * gl_drawinfo; - void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending); #endif diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b90cd3dcd..6a0d86132 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -277,8 +277,6 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) PrevPortal = GLRenderer->mCurrentPortal; - PrevClipPortal = GLRenderer->mClipPortal; - GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves GLRenderer->mCurrentPortal = this; if (PrevPortal != NULL) PrevPortal->PushState(); @@ -324,8 +322,6 @@ void GLPortal::End(bool usestencil) Clocker c(PortalAll); if (PrevPortal != NULL) PrevPortal->PopState(); - GLRenderer->mCurrentPortal = PrevPortal; - GLRenderer->mClipPortal = PrevClipPortal; if (usestencil) { @@ -878,7 +874,7 @@ void GLMirrorPortal::DrawContents(FDrawInfo *di) return; } - GLRenderer->mClipPortal = this; + di->mClipPortal = this; DAngle StartAngle = r_viewpoint.Angles.Yaw; DVector3 StartPos = r_viewpoint.Pos; @@ -979,7 +975,7 @@ void GLLineToLinePortal::DrawContents(FDrawInfo *di) return; } - GLRenderer->mClipPortal = this; + di->mClipPortal = this; line_t *origin = glport->lines[0]->mOrigin; P_TranslatePortalXY(origin, r_viewpoint.Pos.X, r_viewpoint.Pos.Y); @@ -1251,3 +1247,9 @@ const char *GLLineToLinePortal::GetName() { return "LineToLine"; } const char *GLHorizonPortal::GetName() { return "Horizon"; } const char *GLEEHorizonPortal::GetName() { return "EEHorizon"; } +// This needs to remain on the renderer side until the portal interface can be abstracted. +void FSectorPortalGroup::AddSubsector(subsector_t *sub) +{ + GLSectorStackPortal *glportal = GetRenderState(); + glportal->AddSubsector(sub); +} diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 8b4a87f15..5f646f41c 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -49,7 +49,7 @@ extern UniqueList UniquePlaneMirrors; struct GLEEHorizonPortal; class GLSceneDrawer; -class GLPortal +class GLPortal : public IPortal { static TArray portals; static int recursion; @@ -77,7 +77,6 @@ private: AActor * savedviewactor; ActorRenderFlags savedvisibility; GLPortal *PrevPortal; - GLPortal *PrevClipPortal; TArray mPrimIndices; protected: @@ -127,10 +126,6 @@ public: static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); } - virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } - virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } - virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } - virtual line_t *ClipLine() { return NULL; } virtual void RenderAttached(FDrawInfo *di) {} static void BeginScene(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 78da1e5aa..422bb58a6 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -228,16 +228,18 @@ void GLSceneDrawer::CreateScene(FDrawInfo *di) GLRenderer->mVBO->Map(); GLRenderer->mLights->Begin(); - SetView(); + // Give the DrawInfo the viewpoint in fixed point because that's what the nodes are. + di->viewx = FLOAT2FIXED(r_viewpoint.Pos.X); + di->viewy = FLOAT2FIXED(r_viewpoint.Pos.Y); + validcount++; // used for processing sidedefs only once by the renderer. - di->clipPortal = !!GLRenderer->mClipPortal; di->mAngles = GLRenderer->mAngles; di->mViewVector = GLRenderer->mViewVector; di->mViewActor = GLRenderer->mViewActor; di->mShadowMap = &GLRenderer->mShadowMap; - RenderBSPNode (level.HeadNode()); + di->RenderBSPNode (level.HeadNode()); di->PreparePlayerSprites(r_viewpoint.sector, di->in_area); // Process all the sprites on the current portal's back side which touch the portal. @@ -453,7 +455,6 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode) { CreateScene(di); } - GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. RenderScene(di, recursion); diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index e6c30239b..d075e1418 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -13,26 +13,10 @@ struct HUDSprite; class GLSceneDrawer { - fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. - - subsector_t *currentsubsector; // used by the line processing code. - sector_t *currentsector; - TMap weapondynlightindex; void RenderMultipassStuff(FDrawInfo *di); - void UnclipSubsector(subsector_t *sub); - void AddLine (seg_t *seg, bool portalclip); - void PolySubsector(subsector_t * sub); - void RenderPolyBSPNode (void *node); - void AddPolyobjs(subsector_t *sub); - void AddLines(subsector_t * sub, sector_t * sector); - void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line); - void RenderThings(subsector_t * sub, sector_t * sector); - void DoSubsector(subsector_t * sub); - void RenderBSPNode(void *node); - void RenderScene(FDrawInfo *di, int recursion); void RenderTranslucent(FDrawInfo *di); @@ -64,12 +48,6 @@ public: sector_t *RenderView(player_t *player); void WriteSavePic(player_t *player, FileWriter *file, int width, int height); - void SetView() - { - viewx = FLOAT2FIXED(r_viewpoint.Pos.X); - viewy = FLOAT2FIXED(r_viewpoint.Pos.Y); - } - void SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon = false) { gl_SetColor(light, rellight, FixedColormap != CM_DEFAULT, cm, alpha, weapon); diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index 369bfe399..ad34a4c52 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -15,6 +15,7 @@ struct particle_t; struct FDynLightData; struct HUDSprite; class Clipper; +class IPortal; //========================================================================== // @@ -79,7 +80,7 @@ struct HWDrawInfo int FixedColormap; std::atomic spriteindex; - bool clipPortal; + IPortal *mClipPortal; FRotator mAngles; FVector2 mViewVector; AActor *mViewActor; @@ -108,15 +109,31 @@ struct HWDrawInfo BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. area_t in_area; + fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. + private: // For ProcessLowerMiniseg bool inview; subsector_t * viewsubsector; TArray lowersegs; - + + subsector_t *currentsubsector; // used by the line processing code. + sector_t *currentsector; + sector_t fakesec; // this is a struct member because it gets used in recursively called functions so it cannot be put on the stack. + + void UnclipSubsector(subsector_t *sub); + void AddLine(seg_t *seg, bool portalclip); + void PolySubsector(subsector_t * sub); + void RenderPolyBSPNode(void *node); + void AddPolyobjs(subsector_t *sub); + void AddLines(subsector_t * sub, sector_t * sector); + void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line); + void RenderThings(subsector_t * sub, sector_t * sector); + void DoSubsector(subsector_t * sub); public: + void RenderBSPNode(void *node); void ClearBuffers(); void SetViewArea(); @@ -175,8 +192,5 @@ public: virtual GLDecal *AddDecal(bool onmirror) = 0; virtual std::pair AllocVertices(unsigned int count) = 0; - virtual int ClipPoint(const DVector3 &pos) = 0; - - }; diff --git a/src/hwrenderer/scene/hw_portal.h b/src/hwrenderer/scene/hw_portal.h index 3037ed8c1..2347be86d 100644 --- a/src/hwrenderer/scene/hw_portal.h +++ b/src/hwrenderer/scene/hw_portal.h @@ -1,5 +1,6 @@ #pragma once +#include "hw_drawinfo.h" #include "hwrenderer/textures/hw_material.h" struct GLSkyInfo @@ -32,3 +33,12 @@ struct GLHorizonInfo PalEntry specialcolor; }; +class IPortal +{ +public: + virtual ~IPortal(); + virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } + virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } + virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } + virtual line_t *ClipLine() { return nullptr; } +}; diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 89352007c..d92951aa9 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -82,6 +82,8 @@ void HWDrawInfo::ClearBuffers() memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0])); memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0])); memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0])); + + mClipPortal = nullptr; } //========================================================================== diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 6814d1760..d5c0ea99e 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -45,6 +45,7 @@ #include "hwrenderer/scene/hw_drawstructs.h" #include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_fakeflat.h" +#include "hwrenderer/scene/hw_portal.h" #include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_lighting.h" @@ -471,9 +472,9 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again. } - if (thruportal != 2 && di->clipPortal) + if (thruportal != 2 && di->mClipPortal != nullptr) { - int clipres = di->ClipPoint(thingpos); + int clipres = di->mClipPortal->ClipPoint(thingpos); if (clipres == PClip_InFront) return; } // disabled because almost none of the actual game code is even remotely prepared for this. If desired, use the INTERPOLATE flag. diff --git a/src/portal.h b/src/portal.h index f194c3886..343e09b29 100644 --- a/src/portal.h +++ b/src/portal.h @@ -7,6 +7,7 @@ struct FPortalGroupArray; struct portnode_t; +struct subsector_t; //============================================================================ // // This table holds the offsets for the different parts of a map @@ -256,6 +257,8 @@ struct FSectorPortalGroup GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! GLSectorStackPortal *GetRenderState(); + + void AddSubsector(subsector_t *sub); }; From 91aec1689e9a1ec47dc3c39946d2ed91e50baffb Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 22 May 2018 01:28:57 +0200 Subject: [PATCH 30/40] - move modeldef parsing to its own function (ParseModelDefLump) - rename gl_InitModels to InitModels - add commented out support for #include in modeldefs (blocked by gene tech having broken #include statements in its modeldef files) --- src/r_data/models/models.cpp | 627 ++++++++++++++++++----------------- src/r_data/sprites.cpp | 4 +- 2 files changed, 322 insertions(+), 309 deletions(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index 23b517352..cb260bf88 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -469,22 +469,15 @@ static unsigned FindModel(const char * path, const char * modelfile) //=========================================================================== // -// gl_InitModels +// InitModels // //=========================================================================== -void gl_InitModels() +void ParseModelDefLump(int Lump); + +void InitModels() { - int Lump, lastLump; - FString path; - int index, surface; - int i; - - FSpriteModelFrame smf; - - lastLump = 0; - - for(unsigned i=0;iVoxel->VoxelIndex]; + FSpriteModelFrame smf; memset(&smf, 0, sizeof(smf)); smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex; @@ -533,302 +527,11 @@ void gl_InitModels() } } - memset(&smf, 0, sizeof(smf)); - smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + int Lump; + int lastLump = 0; while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1) { - FScanner sc(Lump); - while (sc.GetString()) - { - if (sc.Compare("model")) - { - path = ""; - sc.MustGetString(); - memset(&smf, 0, sizeof(smf)); - smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; - smf.xscale=smf.yscale=smf.zscale=1.f; - - smf.type = PClass::FindClass(sc.String); - if (!smf.type || smf.type->Defaults == nullptr) - { - sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String); - } - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("path")) - { - sc.MustGetString(); - FixPathSeperator(sc.String); - path = sc.String; - if (path[(int)path.Len()-1]!='/') path+='/'; - } - else if (sc.Compare("model")) - { - sc.MustGetNumber(); - index = sc.Number; - if (index < 0 || index >= MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - sc.MustGetString(); - FixPathSeperator(sc.String); - smf.modelIDs[index] = FindModel(path.GetChars(), sc.String); - if (smf.modelIDs[index] == -1) - { - Printf("%s: model not found in %s\n", sc.String, path.GetChars()); - } - } - else if (sc.Compare("scale")) - { - sc.MustGetFloat(); - smf.xscale = sc.Float; - sc.MustGetFloat(); - smf.yscale = sc.Float; - sc.MustGetFloat(); - smf.zscale = sc.Float; - } - // [BB] Added zoffset reading. - // Now it must be considered deprecated. - else if (sc.Compare("zoffset")) - { - sc.MustGetFloat(); - smf.zoffset=sc.Float; - } - // Offset reading. - else if (sc.Compare("offset")) - { - sc.MustGetFloat(); - smf.xoffset = sc.Float; - sc.MustGetFloat(); - smf.yoffset = sc.Float; - sc.MustGetFloat(); - smf.zoffset = sc.Float; - } - // angleoffset, pitchoffset and rolloffset reading. - else if (sc.Compare("angleoffset")) - { - sc.MustGetFloat(); - smf.angleoffset = sc.Float; - } - else if (sc.Compare("pitchoffset")) - { - sc.MustGetFloat(); - smf.pitchoffset = sc.Float; - } - else if (sc.Compare("rolloffset")) - { - sc.MustGetFloat(); - smf.rolloffset = sc.Float; - } - // [BB] Added model flags reading. - else if (sc.Compare("ignoretranslation")) - { - smf.flags |= MDL_IGNORETRANSLATION; - } - else if (sc.Compare("pitchfrommomentum")) - { - smf.flags |= MDL_PITCHFROMMOMENTUM; - } - else if (sc.Compare("inheritactorpitch")) - { - smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION; - } - else if (sc.Compare("inheritactorroll")) - { - smf.flags |= MDL_USEACTORROLL; - } - else if (sc.Compare("useactorpitch")) - { - smf.flags |= MDL_USEACTORPITCH; - } - else if (sc.Compare("useactorroll")) - { - smf.flags |= MDL_USEACTORROLL; - } - else if (sc.Compare("rotating")) - { - smf.flags |= MDL_ROTATING; - smf.xrotate = 0.; - smf.yrotate = 1.; - smf.zrotate = 0.; - smf.rotationCenterX = 0.; - smf.rotationCenterY = 0.; - smf.rotationCenterZ = 0.; - smf.rotationSpeed = 1.; - } - else if (sc.Compare("rotation-speed")) - { - sc.MustGetFloat(); - smf.rotationSpeed = sc.Float; - } - else if (sc.Compare("rotation-vector")) - { - sc.MustGetFloat(); - smf.xrotate = sc.Float; - sc.MustGetFloat(); - smf.yrotate = sc.Float; - sc.MustGetFloat(); - smf.zrotate = sc.Float; - } - else if (sc.Compare("rotation-center")) - { - sc.MustGetFloat(); - smf.rotationCenterX = sc.Float; - sc.MustGetFloat(); - smf.rotationCenterY = sc.Float; - sc.MustGetFloat(); - smf.rotationCenterZ = sc.Float; - } - else if (sc.Compare("interpolatedoubledframes")) - { - smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES; - } - else if (sc.Compare("nointerpolation")) - { - smf.flags |= MDL_NOINTERPOLATION; - } - else if (sc.Compare("skin")) - { - sc.MustGetNumber(); - index=sc.Number; - if (index<0 || index>=MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - sc.MustGetString(); - FixPathSeperator(sc.String); - if (sc.Compare("")) - { - smf.skinIDs[index]=FNullTextureID(); - } - else - { - smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String); - if (!smf.skinIDs[index].isValid()) - { - Printf("Skin '%s' not found in '%s'\n", - sc.String, smf.type->TypeName.GetChars()); - } - } - } - else if (sc.Compare("surfaceskin")) - { - sc.MustGetNumber(); - index = sc.Number; - sc.MustGetNumber(); - surface = sc.Number; - - if (index<0 || index >= MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - - if (surface<0 || surface >= MD3_MAX_SURFACES) - { - sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars()); - } - - sc.MustGetString(); - FixPathSeperator(sc.String); - if (sc.Compare("")) - { - smf.surfaceskinIDs[index][surface] = FNullTextureID(); - } - else - { - smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String); - if (!smf.surfaceskinIDs[index][surface].isValid()) - { - Printf("Surface Skin '%s' not found in '%s'\n", - sc.String, smf.type->TypeName.GetChars()); - } - } - } - else if (sc.Compare("frameindex") || sc.Compare("frame")) - { - bool isframe=!!sc.Compare("frame"); - - sc.MustGetString(); - smf.sprite = -1; - for (i = 0; i < (int)sprites.Size (); ++i) - { - if (strnicmp (sprites[i].name, sc.String, 4) == 0) - { - if (sprites[i].numframes==0) - { - //sc.ScriptError("Sprite %s has no frames", sc.String); - } - smf.sprite = i; - break; - } - } - if (smf.sprite==-1) - { - sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars()); - } - - sc.MustGetString(); - FString framechars = sc.String; - - sc.MustGetNumber(); - index=sc.Number; - if (index<0 || index>=MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - if (isframe) - { - sc.MustGetString(); - if (smf.modelIDs[index] != -1) - { - FModel *model = Models[smf.modelIDs[index]]; - smf.modelframes[index] = model->FindFrame(sc.String); - if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars()); - } - else smf.modelframes[index] = -1; - } - else - { - sc.MustGetNumber(); - smf.modelframes[index] = sc.Number; - } - - for(i=0; framechars[i]>0; i++) - { - char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int c = toupper(framechars[i])-'A'; - - if (c<0 || c>=29) - { - sc.ScriptError("Invalid frame character %c found", c+'A'); - } - if (map[c]) continue; - smf.frame=c; - SpriteModelFrames.Push(smf); - GetDefaultByType(smf.type)->hasmodel = true; - map[c]=1; - } - } - else if (sc.Compare("dontcullbackfaces")) - { - smf.flags |= MDL_DONTCULLBACKFACES; - } - else if (sc.Compare("userotationcenter")) - { - smf.flags |= MDL_USEROTATIONCENTER; - smf.rotationCenterX = 0.; - smf.rotationCenterY = 0.; - smf.rotationCenterZ = 0.; - } - else - { - sc.ScriptMessage("Unrecognized string \"%s\"", sc.String); - } - } - } - } + ParseModelDefLump(Lump); } // create a hash table for quick access @@ -836,7 +539,7 @@ void gl_InitModels() atterm(DeleteModelHash); memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int)); - for (i = 0; i < (int)SpriteModelFrames.Size (); i++) + for (unsigned int i = 0; i < SpriteModelFrames.Size (); i++) { int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size (); @@ -845,6 +548,316 @@ void gl_InitModels() } } +static void ParseModelDefLump(int Lump) +{ + FScanner sc(Lump); + while (sc.GetString()) + { + if (sc.Compare("model")) + { + int index, surface; + FString path = ""; + sc.MustGetString(); + + FSpriteModelFrame smf; + memset(&smf, 0, sizeof(smf)); + smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + smf.xscale=smf.yscale=smf.zscale=1.f; + + smf.type = PClass::FindClass(sc.String); + if (!smf.type || smf.type->Defaults == nullptr) + { + sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String); + } + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("path")) + { + sc.MustGetString(); + FixPathSeperator(sc.String); + path = sc.String; + if (path[(int)path.Len()-1]!='/') path+='/'; + } + else if (sc.Compare("model")) + { + sc.MustGetNumber(); + index = sc.Number; + if (index < 0 || index >= MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + sc.MustGetString(); + FixPathSeperator(sc.String); + smf.modelIDs[index] = FindModel(path.GetChars(), sc.String); + if (smf.modelIDs[index] == -1) + { + Printf("%s: model not found in %s\n", sc.String, path.GetChars()); + } + } + else if (sc.Compare("scale")) + { + sc.MustGetFloat(); + smf.xscale = sc.Float; + sc.MustGetFloat(); + smf.yscale = sc.Float; + sc.MustGetFloat(); + smf.zscale = sc.Float; + } + // [BB] Added zoffset reading. + // Now it must be considered deprecated. + else if (sc.Compare("zoffset")) + { + sc.MustGetFloat(); + smf.zoffset=sc.Float; + } + // Offset reading. + else if (sc.Compare("offset")) + { + sc.MustGetFloat(); + smf.xoffset = sc.Float; + sc.MustGetFloat(); + smf.yoffset = sc.Float; + sc.MustGetFloat(); + smf.zoffset = sc.Float; + } + // angleoffset, pitchoffset and rolloffset reading. + else if (sc.Compare("angleoffset")) + { + sc.MustGetFloat(); + smf.angleoffset = sc.Float; + } + else if (sc.Compare("pitchoffset")) + { + sc.MustGetFloat(); + smf.pitchoffset = sc.Float; + } + else if (sc.Compare("rolloffset")) + { + sc.MustGetFloat(); + smf.rolloffset = sc.Float; + } + // [BB] Added model flags reading. + else if (sc.Compare("ignoretranslation")) + { + smf.flags |= MDL_IGNORETRANSLATION; + } + else if (sc.Compare("pitchfrommomentum")) + { + smf.flags |= MDL_PITCHFROMMOMENTUM; + } + else if (sc.Compare("inheritactorpitch")) + { + smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION; + } + else if (sc.Compare("inheritactorroll")) + { + smf.flags |= MDL_USEACTORROLL; + } + else if (sc.Compare("useactorpitch")) + { + smf.flags |= MDL_USEACTORPITCH; + } + else if (sc.Compare("useactorroll")) + { + smf.flags |= MDL_USEACTORROLL; + } + else if (sc.Compare("rotating")) + { + smf.flags |= MDL_ROTATING; + smf.xrotate = 0.; + smf.yrotate = 1.; + smf.zrotate = 0.; + smf.rotationCenterX = 0.; + smf.rotationCenterY = 0.; + smf.rotationCenterZ = 0.; + smf.rotationSpeed = 1.; + } + else if (sc.Compare("rotation-speed")) + { + sc.MustGetFloat(); + smf.rotationSpeed = sc.Float; + } + else if (sc.Compare("rotation-vector")) + { + sc.MustGetFloat(); + smf.xrotate = sc.Float; + sc.MustGetFloat(); + smf.yrotate = sc.Float; + sc.MustGetFloat(); + smf.zrotate = sc.Float; + } + else if (sc.Compare("rotation-center")) + { + sc.MustGetFloat(); + smf.rotationCenterX = sc.Float; + sc.MustGetFloat(); + smf.rotationCenterY = sc.Float; + sc.MustGetFloat(); + smf.rotationCenterZ = sc.Float; + } + else if (sc.Compare("interpolatedoubledframes")) + { + smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES; + } + else if (sc.Compare("nointerpolation")) + { + smf.flags |= MDL_NOINTERPOLATION; + } + else if (sc.Compare("skin")) + { + sc.MustGetNumber(); + index=sc.Number; + if (index<0 || index>=MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + sc.MustGetString(); + FixPathSeperator(sc.String); + if (sc.Compare("")) + { + smf.skinIDs[index]=FNullTextureID(); + } + else + { + smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String); + if (!smf.skinIDs[index].isValid()) + { + Printf("Skin '%s' not found in '%s'\n", + sc.String, smf.type->TypeName.GetChars()); + } + } + } + else if (sc.Compare("surfaceskin")) + { + sc.MustGetNumber(); + index = sc.Number; + sc.MustGetNumber(); + surface = sc.Number; + + if (index<0 || index >= MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + + if (surface<0 || surface >= MD3_MAX_SURFACES) + { + sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars()); + } + + sc.MustGetString(); + FixPathSeperator(sc.String); + if (sc.Compare("")) + { + smf.surfaceskinIDs[index][surface] = FNullTextureID(); + } + else + { + smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String); + if (!smf.surfaceskinIDs[index][surface].isValid()) + { + Printf("Surface Skin '%s' not found in '%s'\n", + sc.String, smf.type->TypeName.GetChars()); + } + } + } + else if (sc.Compare("frameindex") || sc.Compare("frame")) + { + bool isframe=!!sc.Compare("frame"); + + sc.MustGetString(); + smf.sprite = -1; + for (int i = 0; i < (int)sprites.Size (); ++i) + { + if (strnicmp (sprites[i].name, sc.String, 4) == 0) + { + if (sprites[i].numframes==0) + { + //sc.ScriptError("Sprite %s has no frames", sc.String); + } + smf.sprite = i; + break; + } + } + if (smf.sprite==-1) + { + sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars()); + } + + sc.MustGetString(); + FString framechars = sc.String; + + sc.MustGetNumber(); + index=sc.Number; + if (index<0 || index>=MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + if (isframe) + { + sc.MustGetString(); + if (smf.modelIDs[index] != -1) + { + FModel *model = Models[smf.modelIDs[index]]; + smf.modelframes[index] = model->FindFrame(sc.String); + if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars()); + } + else smf.modelframes[index] = -1; + } + else + { + sc.MustGetNumber(); + smf.modelframes[index] = sc.Number; + } + + for(int i=0; framechars[i]>0; i++) + { + char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + int c = toupper(framechars[i])-'A'; + + if (c<0 || c>=29) + { + sc.ScriptError("Invalid frame character %c found", c+'A'); + } + if (map[c]) continue; + smf.frame=c; + SpriteModelFrames.Push(smf); + GetDefaultByType(smf.type)->hasmodel = true; + map[c]=1; + } + } + else if (sc.Compare("dontcullbackfaces")) + { + smf.flags |= MDL_DONTCULLBACKFACES; + } + else if (sc.Compare("userotationcenter")) + { + smf.flags |= MDL_USEROTATIONCENTER; + smf.rotationCenterX = 0.; + smf.rotationCenterY = 0.; + smf.rotationCenterZ = 0.; + } + else + { + sc.ScriptMessage("Unrecognized string \"%s\"", sc.String); + } + } + } + // This code is commented out because Gene Tech has broken include statements that blocks this feature.. + /*else if (sc.Compare("#include")) + { + sc.MustGetString(); + // This is not using sc.Open because it can print a more useful error message when done here + int includelump = Wads.CheckNumForFullName(sc.String, true); + if (includelump == -1) + sc.ScriptError("Lump '%s' not found", sc.String); + else + ParseModelDefLump(includelump); + }*/ + } +} + //=========================================================================== // // FindModelFrame diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index ce6123c18..c1f1f3e02 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -34,7 +34,7 @@ #include "r_data/voxels.h" #include "vm.h" -void gl_InitModels(); +void InitModels(); // variables used to look up // and range check thing_t sprites patches @@ -1048,7 +1048,7 @@ void R_InitSprites () // [RH] Sort the skins, but leave base as skin 0 //qsort (&skins[PlayerClasses.Size ()], numskins-PlayerClasses.Size (), sizeof(FPlayerSkin), skinsorter); - gl_InitModels(); + InitModels(); } From 2514753afb3826705744277c4ecc15749e2d5ba8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 May 2018 18:48:10 +0200 Subject: [PATCH 31/40] - make the vertex buffer accessible from the hwrenderer code. --- src/gl/data/gl_vertexbuffer.cpp | 5 +++-- src/gl/data/gl_vertexbuffer.h | 10 ---------- src/gl/scene/gl_bsp.cpp | 3 ++- src/gl/scene/gl_drawinfo.cpp | 1 + src/gl/scene/gl_portal.cpp | 6 +++--- src/gl/scene/gl_scene.cpp | 1 + src/hwrenderer/data/flatvertices.cpp | 18 +++++++++--------- src/hwrenderer/data/flatvertices.h | 11 +++++------ src/hwrenderer/scene/hw_drawinfo.h | 4 ++++ src/hwrenderer/scene/hw_portal.h | 2 +- 10 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index ce32b3ab4..335c7740c 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -157,6 +157,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) mIndex = mCurIndex = 0; mNumReserved = NUM_RESERVED; + mMap = map; Map(); memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex)); Unmap(); @@ -215,7 +216,7 @@ void FFlatVertexBuffer::Map() unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); gl_RenderState.ResetVertexBuffer(); - map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT); + mMap = map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT); } } @@ -227,7 +228,7 @@ void FFlatVertexBuffer::Unmap() glBindBuffer(GL_ARRAY_BUFFER, vbo_id); gl_RenderState.ResetVertexBuffer(); glUnmapBuffer(GL_ARRAY_BUFFER); - map = nullptr; + mMap = map = nullptr; } } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 28fe8f45c..de741b251 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -177,16 +177,6 @@ public: #endif - void CheckPlanes(sector_t *sector) - { - FFlatVertexGenerator::CheckPlanes(sector, map); - } - - void CheckUpdate(sector_t *sector) - { - FFlatVertexGenerator::CheckUpdate(sector, map); - } - void Reset() { mCurIndex = mIndex; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index b5bc58e46..d01706b6d 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -37,6 +37,7 @@ #include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_portal.h" #include "hwrenderer/utility/hw_clock.h" +#include "hwrenderer/data/flatvertices.h" EXTERN_CVAR(Bool, gl_render_segs) @@ -452,7 +453,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) if (sector->validcount != validcount) { - GLRenderer->mVBO->CheckUpdate(sector); + mVBO->CheckUpdate(sector); } // [RH] Add particles diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index b67f23fb4..abcdbe70b 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -199,6 +199,7 @@ FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer) { FDrawInfo *di=di_list.GetNew(); di->mDrawer = drawer; + di->mVBO = GLRenderer->mVBO; di->mClipper = &staticClipper; staticClipper.Clear(); di->FixedColormap = drawer->FixedColormap; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 6a0d86132..ce96aa658 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -425,11 +425,11 @@ void GLPortal::End(bool usestencil) //----------------------------------------------------------------------------- void GLPortal::StartFrame() { - GLPortal * p=NULL; + GLPortal * p = nullptr; portals.Push(p); - if (renderdepth==0) + if (renderdepth == 0) { - inskybox=false; + inskybox = false; screen->instack[sector_t::floor] = screen->instack[sector_t::ceiling] = 0; } renderdepth++; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 422bb58a6..d3a1a2e22 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -557,6 +557,7 @@ void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen) int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; di->CurrentMapSections.Set(mapsection); + GLRenderer->mCurrentPortal = nullptr; DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN); } diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index 86bf78261..f069a7989 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -233,13 +233,13 @@ void FFlatVertexGenerator::CreateFlatVertices() // //========================================================================== -void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map) +void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane) { int startvt = sec->vboindex[plane]; int countvt = sec->vbocount[plane]; secplane_t &splane = sec->GetSecPlane(plane); FFlatVertex *vt = &vbo_shadowdata[startvt]; - FFlatVertex *mapvt = &map[startvt]; + FFlatVertex *mapvt = &mMap[startvt]; for(int i=0; iz = (float)splane.ZatPoint(vt->x, vt->y); @@ -266,16 +266,16 @@ void FFlatVertexGenerator::CreateVertices() // //========================================================================== -void FFlatVertexGenerator::CheckPlanes(sector_t *sector, FFlatVertex *map) +void FFlatVertexGenerator::CheckPlanes(sector_t *sector) { if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling]) { - UpdatePlaneVertices(sector, sector_t::ceiling, map); + UpdatePlaneVertices(sector, sector_t::ceiling); sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling); } if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor]) { - UpdatePlaneVertices(sector, sector_t::floor, map); + UpdatePlaneVertices(sector, sector_t::floor); sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor); } } @@ -287,11 +287,11 @@ void FFlatVertexGenerator::CheckPlanes(sector_t *sector, FFlatVertex *map) // //========================================================================== -void FFlatVertexGenerator::CheckUpdate(sector_t *sector, FFlatVertex *map) +void FFlatVertexGenerator::CheckUpdate(sector_t *sector) { - CheckPlanes(sector, map); + CheckPlanes(sector); sector_t *hs = sector->GetHeightSec(); - if (hs != NULL) CheckPlanes(hs, map); + if (hs != NULL) CheckPlanes(hs); for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++) - CheckPlanes(sector->e->XFloor.ffloors[i]->model, map); + CheckPlanes(sector->e->XFloor.ffloors[i]->model); } diff --git a/src/hwrenderer/data/flatvertices.h b/src/hwrenderer/data/flatvertices.h index 9a45558b5..ee390218f 100644 --- a/src/hwrenderer/data/flatvertices.h +++ b/src/hwrenderer/data/flatvertices.h @@ -45,10 +45,9 @@ class FFlatVertexGenerator { protected: TArray vbo_shadowdata; + FFlatVertex *mMap; - void CheckPlanes(sector_t *sector); - public: enum { @@ -70,12 +69,12 @@ private: int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor); void CreateFlatVertices(); - void UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map); + void UpdatePlaneVertices(sector_t *sec, int plane); protected: void CreateVertices(); - void CheckPlanes(sector_t *sector, FFlatVertex *map); - void CheckUpdate(sector_t *sector, FFlatVertex *map); - + void CheckPlanes(sector_t *sector); +public: + void CheckUpdate(sector_t *sector); }; #endif \ No newline at end of file diff --git a/src/hwrenderer/scene/hw_drawinfo.h b/src/hwrenderer/scene/hw_drawinfo.h index ad34a4c52..e9db60a09 100644 --- a/src/hwrenderer/scene/hw_drawinfo.h +++ b/src/hwrenderer/scene/hw_drawinfo.h @@ -3,6 +3,7 @@ #include #include "r_defs.h" + struct FSectorPortalGroup; struct FLinePortalSpan; struct FFlatVertex; @@ -16,6 +17,7 @@ struct FDynLightData; struct HUDSprite; class Clipper; class IPortal; +class FFlatVertexGenerator; //========================================================================== // @@ -107,9 +109,11 @@ struct HWDrawInfo TArray ss_renderflags; TArray no_renderflags; + // This is needed by the BSP traverser. BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. area_t in_area; fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. + FFlatVertexGenerator *mVBO; // this class needs access because the sector vertex updating is part of BSP traversal. private: diff --git a/src/hwrenderer/scene/hw_portal.h b/src/hwrenderer/scene/hw_portal.h index 2347be86d..695daaa98 100644 --- a/src/hwrenderer/scene/hw_portal.h +++ b/src/hwrenderer/scene/hw_portal.h @@ -36,7 +36,7 @@ struct GLHorizonInfo class IPortal { public: - virtual ~IPortal(); + virtual ~IPortal() {} virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } From 26ebb938c1aea5e861d0363ae4d532c189ba76a8 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 22 May 2018 21:48:31 +0300 Subject: [PATCH 32/40] - fixed compilation with GCC/Clang https://forum.zdoom.org/viewtopic.php?f=2&t=60657 --- src/r_data/models/models.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index cb260bf88..4b43a4766 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -473,7 +473,7 @@ static unsigned FindModel(const char * path, const char * modelfile) // //=========================================================================== -void ParseModelDefLump(int Lump); +static void ParseModelDefLump(int Lump); void InitModels() { From 8987aba4a4ff6a0f88310a43bbb23492aa22c998 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 May 2018 21:08:00 +0200 Subject: [PATCH 33/40] - restored accidentally deleted line of code. --- src/gl/scene/gl_portal.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index ce96aa658..25b2ff236 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -322,6 +322,7 @@ void GLPortal::End(bool usestencil) Clocker c(PortalAll); if (PrevPortal != NULL) PrevPortal->PopState(); + GLRenderer->mCurrentPortal = PrevPortal; if (usestencil) { From 3f6789ecac16bb57c2fcfbbd8ba5087aaf57c13b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 May 2018 21:36:42 +0200 Subject: [PATCH 34/40] - moved gl_bsp.cpp to its proper place. --- src/CMakeLists.txt | 2 +- src/{gl/scene/gl_bsp.cpp => hwrenderer/scene/hw_bsp.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{gl/scene/gl_bsp.cpp => hwrenderer/scene/hw_bsp.cpp} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 291961100..16c23743a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -809,7 +809,6 @@ set( FASTMATH_SOURCES textures/hires/hqnx/hq4x.cpp textures/hires/xbr/xbrz.cpp textures/hires/xbr/xbrz_old.cpp - gl/scene/gl_bsp.cpp gl/scene/gl_drawinfo.cpp gl/scene/gl_flats.cpp gl/scene/gl_sprite.cpp @@ -822,6 +821,7 @@ set( FASTMATH_SOURCES hwrenderer/postprocessing/hw_postprocess_cvars.cpp hwrenderer/postprocessing/hw_postprocessshader.cpp hwrenderer/dynlights/hw_dynlightdata.cpp + hwrenderer/scene/hw_bsp.cpp hwrenderer/scene/hw_fakeflat.cpp hwrenderer/scene/hw_decal.cpp hwrenderer/scene/hw_drawlist.cpp diff --git a/src/gl/scene/gl_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp similarity index 100% rename from src/gl/scene/gl_bsp.cpp rename to src/hwrenderer/scene/hw_bsp.cpp From 044c8a2034539d7fe68076f98ac7f3a430b5b295 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 23 May 2018 08:43:52 +0200 Subject: [PATCH 35/40] - removed gl_render_subsectors test CVAR and disabled vertex buffer generation for legacy mode To reduce the performance impact, legacy mode will now always create flat vertex data on the fly instead of relying on the vertex buffer. This makes the CVAR mostly redundant as on anything more modern rendering per subsector will always be slower. --- src/gl/data/gl_vertexbuffer.cpp | 5 ++++- src/gl/scene/gl_flats.cpp | 22 ++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index cd7549aa8..bf867f13e 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -249,7 +249,10 @@ void FFlatVertexBuffer::Unmap() void FFlatVertexBuffer::CreateVBO() { vbo_shadowdata.Resize(mNumReserved); - FFlatVertexGenerator::CreateVertices(); + if (!gl.legacyMode) + { + FFlatVertexGenerator::CreateVertices(); + } mCurIndex = mIndex = vbo_shadowdata.Size(); Map(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 0aa9c88fc..1faa44901 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -48,8 +48,6 @@ #include "gl/scene/gl_scenedrawer.h" #include "gl/renderer/gl_quaddrawer.h" -CVAR(Bool, gl_render_subsectors, false, 0) - //========================================================================== // // Flats @@ -166,24 +164,24 @@ void FDrawInfo::DrawSubsector(GLFlat *flat, subsector_t * sub) void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans) { flat->dynlightindex = GLRenderer->mLights->GetIndexPtr(); - - if (flat->sector->ibocount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive()) + + if (flat->sector->ibocount > 0 && !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++) - { - subsector_t * sub = flat->sector->subsectors[i]; - if (ss_renderflags[sub->Index()] & flat->renderflags || istrans) { - SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); + subsector_t * sub = flat->sector->subsectors[i]; + if (ss_renderflags[sub->Index()] & flat->renderflags || istrans) + { + SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr); + } } } - } - + // Draw the subsectors assigned to it due to missing textures if (!(flat->renderflags&SSRF_RENDER3DPLANES)) { @@ -214,7 +212,7 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool if (gl.legacyMode) processlights = false; auto vcount = flat->sector->ibocount; - if (vcount > 0 && !gl_render_subsectors && !gl_RenderState.GetClipLineShouldBeActive()) + if (vcount > 0 && !gl_RenderState.GetClipLineShouldBeActive()) { if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli); drawcalls.Clock(); From 23909d109ff3ac60b3109c4f097e60a4bb972063 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 23 May 2018 08:46:26 +0200 Subject: [PATCH 36/40] fixed: Generating light data for single subsectors should not use the light list of the entire sector but only the one for the current subsector --- src/gl/scene/gl_flats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 1faa44901..4f974598d 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -62,7 +62,7 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, (*dli)++; return; } - if (flat->SetupSectorLights(pass, flat->sector, lightdata)) + if (flat->SetupSubsectorLights(pass, sub, lightdata)) { int d = GLRenderer->mLights->UploadLights(lightdata); if (pass == GLPASS_LIGHTSONLY) From 496e6e2e8ffd4c756b62917756efb42b6805e36a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 24 May 2018 00:01:56 +0200 Subject: [PATCH 37/40] - fixed: The vertex height updater was using the index buffer offsets to access the vertex buffer. I missed this part when repurposing the vboindex members to store the index buffer offsets. However, since both indices are needed, they need another set of variables. --- src/gl/compatibility/gl_20.cpp | 2 +- src/gl/scene/gl_flats.cpp | 6 +++--- src/hwrenderer/data/flatvertices.cpp | 15 ++++++++------- src/hwrenderer/scene/hw_bsp.cpp | 4 ++++ src/hwrenderer/scene/hw_drawstructs.h | 2 +- src/hwrenderer/scene/hw_fakeflat.cpp | 16 ++++++++-------- src/hwrenderer/scene/hw_flats.cpp | 12 ++++++------ src/r_defs.h | 3 ++- 8 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 18d96c9b2..0dd2930ff 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -588,7 +588,7 @@ bool FDrawInfo::PutFlatCompat(GLFlat *flat, bool fog) int list = list_indices[masked][foggy]; auto newflat = dldrawlists[list].NewFlat(); *newflat = *flat; - newflat->vboindex = -1; // don't use the vertex buffer with legacy lights to ensure all passes use the same render logic. + newflat->iboindex = -1; // don't use the vertex buffer with legacy lights to ensure all passes use the same render logic. return true; } diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 4f974598d..70ca080f2 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -216,14 +216,14 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool { if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli); drawcalls.Clock(); - glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->vboindex); + glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->iboindex); drawcalls.Unclock(); flatvertices += vcount; flatprimitives++; } - else if (flat->vboindex >= 0) + else if (flat->iboindex >= 0) { - int index = flat->vboindex; + int index = flat->iboindex; for (int i=0; isector->subsectorcount; i++) { subsector_t * sub = flat->sector->subsectors[i]; diff --git a/src/hwrenderer/data/flatvertices.cpp b/src/hwrenderer/data/flatvertices.cpp index 5771012bc..1decb2c04 100644 --- a/src/hwrenderer/data/flatvertices.cpp +++ b/src/hwrenderer/data/flatvertices.cpp @@ -177,21 +177,22 @@ int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secpl int FFlatVertexGenerator::CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray &gen) { + sec->vboindex[h] = vbo_shadowdata.Size(); // First calculate the vertices for the sector itself sec->vboheight[h] = sec->GetPlaneTexZ(h); - sec->vboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]); + sec->iboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]); // Next are all sectors using this one as heightsec TArray &fakes = sec->e->FakeFloor.Sectors; - for (unsigned g = 0; gvboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]); + fsec->iboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]); } // and finally all attached 3D floors TArray &xf = sec->e->XFloor.attached; - for (unsigned g = 0; gvbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h]; - return sec->vboindex[h]; + return sec->iboindex[h]; } @@ -253,11 +254,11 @@ void FFlatVertexGenerator::CreateIndexedFlatVertices() { if (ff->top.model == &sec) { - ff->top.vindex = sec.vboindex[ff->top.isceiling]; + ff->top.vindex = sec.iboindex[ff->top.isceiling]; } if (ff->bottom.model == &sec) { - ff->bottom.vindex = sec.vboindex[ff->top.isceiling]; + ff->bottom.vindex = sec.iboindex[ff->top.isceiling]; } } } diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index d01706b6d..4393424c1 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -453,6 +453,10 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) if (sector->validcount != validcount) { + if (sector->Index() == 62) + { + int a = 0; + } mVBO->CheckUpdate(sector); } diff --git a/src/hwrenderer/scene/hw_drawstructs.h b/src/hwrenderer/scene/hw_drawstructs.h index 56c74a8f7..5758cf0b8 100644 --- a/src/hwrenderer/scene/hw_drawstructs.h +++ b/src/hwrenderer/scene/hw_drawstructs.h @@ -306,7 +306,7 @@ public: bool stack; bool ceiling; uint8_t renderflags; - int vboindex; + int iboindex; //int vboheight; int dynlightindex; diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index 761379851..e4e986ca8 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -234,7 +234,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac { dest->SetTexture(sector_t::floor, s->GetTexture(sector_t::floor), false); dest->SetPlaneTexZQuick(sector_t::floor, s->GetPlaneTexZ(sector_t::floor)); - dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakefloor]; + dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakefloor]; dest->vboheight[sector_t::floor] = s->vboheight[sector_t::floor]; } else if (s->MoreFlags & SECMF_FAKEFLOORONLY) @@ -260,7 +260,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac dest->SetPlaneTexZQuick(sector_t::floor, s->GetPlaneTexZ(sector_t::floor)); dest->floorplane = s->floorplane; - dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakefloor]; + dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakefloor]; dest->vboheight[sector_t::floor] = s->vboheight[sector_t::floor]; } @@ -272,7 +272,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac { dest->SetTexture(sector_t::ceiling, s->GetTexture(sector_t::ceiling), false); dest->SetPlaneTexZQuick(sector_t::ceiling, s->GetPlaneTexZ(sector_t::ceiling)); - dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakeceiling]; + dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakeceiling]; dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::ceiling]; } } @@ -280,7 +280,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac { dest->ceilingplane = s->ceilingplane; dest->SetPlaneTexZQuick(sector_t::ceiling, s->GetPlaneTexZ(sector_t::ceiling)); - dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakeceiling]; + dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakeceiling]; dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::ceiling]; } } @@ -294,10 +294,10 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac dest->ceilingplane=s->floorplane; dest->ceilingplane.FlipVert(); - dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::floor]; + dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::floor]; dest->vboheight[sector_t::floor] = sec->vboheight[sector_t::floor]; - dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakefloor]; + dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakefloor]; dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::floor]; dest->ClearPortal(sector_t::ceiling); @@ -347,10 +347,10 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac dest->floorplane = s->ceilingplane; dest->floorplane.FlipVert(); - dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakeceiling]; + dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakeceiling]; dest->vboheight[sector_t::floor] = s->vboheight[sector_t::ceiling]; - dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::ceiling]; + dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::ceiling]; dest->vboheight[sector_t::ceiling] = sec->vboheight[sector_t::ceiling]; dest->ClearPortal(sector_t::floor); diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index fa1ff287a..27e31843f 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -229,11 +229,11 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside) renderstyle = rover->flags&FF_ADDITIVETRANS? STYLE_Add : STYLE_Translucent; if (plane.model->VBOHeightcheck(plane.isceiling)) { - vboindex = plane.vindex; + iboindex = plane.vindex; } else { - vboindex = -1; + iboindex = -1; } } @@ -298,11 +298,11 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector) { if (frontsector->VBOHeightcheck(sector_t::floor)) { - vboindex = frontsector->vboindex[sector_t::floor]; + iboindex = frontsector->iboindex[sector_t::floor]; } else { - vboindex = -1; + iboindex = -1; } ceiling = false; @@ -358,11 +358,11 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector) { if (frontsector->VBOHeightcheck(sector_t::ceiling)) { - vboindex = frontsector->vboindex[sector_t::ceiling]; + iboindex = frontsector->iboindex[sector_t::ceiling]; } else { - vboindex = -1; + iboindex = -1; } ceiling = true; diff --git a/src/r_defs.h b/src/r_defs.h index 17fcc5cad..4ba0d45d3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1087,7 +1087,8 @@ public: vbo_fakeceiling = ceiling+2, }; - int vboindex[4]; // VBO/IBO indices of the 4 planes this sector uses during rendering + int vboindex[4]; // VBO indices of the 4 planes this sector uses during rendering. This is only needed for updating plane heights. + int iboindex[4]; // 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 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. From fb9cf33af6a28bf5f40fc7daa1887f7f4956e00e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 24 May 2018 00:59:45 +0200 Subject: [PATCH 38/40] - enable #include support in modeldef files --- src/r_data/models/models.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index 4b43a4766..84751baba 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -845,16 +845,21 @@ static void ParseModelDefLump(int Lump) } } // This code is commented out because Gene Tech has broken include statements that blocks this feature.. - /*else if (sc.Compare("#include")) + else if (sc.Compare("#include")) { sc.MustGetString(); // This is not using sc.Open because it can print a more useful error message when done here int includelump = Wads.CheckNumForFullName(sc.String, true); if (includelump == -1) - sc.ScriptError("Lump '%s' not found", sc.String); + { + if (strcmp(sc.String, "sentinel.modl") != 0) // Gene Tech mod has a broken #include statement + sc.ScriptError("Lump '%s' not found", sc.String); + } else + { ParseModelDefLump(includelump); - }*/ + } + } } } From 771931db9f05648a34c75d5f8df6abbb04b2b31b Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 24 May 2018 01:00:31 +0200 Subject: [PATCH 39/40] - forgot to remove the remarked comment --- src/r_data/models/models.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index 84751baba..1a898f062 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -844,7 +844,6 @@ static void ParseModelDefLump(int Lump) } } } - // This code is commented out because Gene Tech has broken include statements that blocks this feature.. else if (sc.Compare("#include")) { sc.MustGetString(); From 8098657cf491da92410163ad0377e683bcdbfc95 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 24 May 2018 01:39:36 +0200 Subject: [PATCH 40/40] - add two-sided culling support in software and poly --- src/polyrenderer/drawers/poly_triangle.cpp | 24 ++++++++++++++++++++++ src/polyrenderer/drawers/poly_triangle.h | 15 ++++++++++++++ src/polyrenderer/scene/poly_model.cpp | 4 ++++ src/swrenderer/things/r_model.cpp | 4 ++++ 4 files changed, 47 insertions(+) diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index 37052aee7..beefb33d7 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -79,6 +79,11 @@ void PolyTriangleDrawer::SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw queue->Push(ccw); } +void PolyTriangleDrawer::SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided) +{ + queue->Push(twosided); +} + void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable) { queue->Push(enable); @@ -348,6 +353,14 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo } } + if (twosided && numclipvert > 2) + { + args->v1 = &clippedvert[0]; + args->v2 = &clippedvert[1]; + args->v3 = &clippedvert[2]; + ccw = !IsFrontfacing(args); + } + // Draw screen triangles if (ccw) { @@ -588,6 +601,17 @@ void PolySetCullCCWCommand::Execute(DrawerThread *thread) ///////////////////////////////////////////////////////////////////////////// +PolySetTwoSidedCommand::PolySetTwoSidedCommand(bool twosided) : twosided(twosided) +{ +} + +void PolySetTwoSidedCommand::Execute(DrawerThread *thread) +{ + PolyTriangleThreadData::Get(thread)->SetTwoSided(twosided); +} + +///////////////////////////////////////////////////////////////////////////// + PolySetWeaponSceneCommand::PolySetWeaponSceneCommand(bool value) : value(value) { } diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 3cd88d803..628bdb009 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -35,6 +35,7 @@ public: static void ClearBuffers(DCanvas *canvas); static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers); static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw); + static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided); static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable); static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip); }; @@ -47,6 +48,7 @@ public: void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers); void SetTransform(const Mat4f *objectToClip); void SetCullCCW(bool value) { ccw = value; } + void SetTwoSided(bool value) { twosided = value; } void SetWeaponScene(bool value) { weaponScene = value; } void DrawElements(const PolyDrawArgs &args); @@ -81,6 +83,7 @@ private: bool dest_bgra = false; uint8_t *dest = nullptr; bool ccw = true; + bool twosided = false; bool weaponScene = false; const Mat4f *objectToClip = nullptr; bool span_drawers = false; @@ -112,6 +115,18 @@ private: bool ccw; }; +class PolySetTwoSidedCommand : public DrawerCommand +{ +public: + PolySetTwoSidedCommand(bool twosided); + + void Execute(DrawerThread *thread) override; + FString DebugInfo() override { return "PolySetCullCCWCommand"; } + +private: + bool twosided; +}; + class PolySetWeaponSceneCommand : public DrawerCommand { public: diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index ac29af9bb..cc8a111ea 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -56,10 +56,12 @@ void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, co ModelActor = actor; const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); SetTransform(); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) { + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); ModelActor = nullptr; } @@ -98,12 +100,14 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT const_cast(objectToWorldMatrix).copy(ObjectToWorld.Matrix); SetTransform(); PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void PolyModelRenderer::EndDrawHUDModel(AActor *actor) { ModelActor = nullptr; PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } void PolyModelRenderer::SetInterpolation(double interpolation) diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index fe5769262..2d09ca276 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -120,11 +120,13 @@ namespace swrenderer } SetTransform(); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf) { ModelActor = nullptr; + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe) @@ -183,12 +185,14 @@ namespace swrenderer ClipBottom = {}; SetTransform(); PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true); } void SWModelRenderer::EndDrawHUDModel(AActor *actor) { ModelActor = nullptr; PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false); + PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false); } void SWModelRenderer::SetInterpolation(double interpolation)