diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index ef3987f09..a1569c8d7 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -25,6 +25,25 @@ struct LevelSubmeshDrawRange int Count; }; +struct GeometryAllocInfo +{ + FFlatVertex* Vertices = nullptr; + int* UniformIndexes = nullptr; + uint32_t* Indexes = nullptr; + int VertexStart = 0; + int VertexCount = 0; + int IndexStart = 0; + int IndexCount = 0; +}; + +struct UniformsAllocInfo +{ + SurfaceUniforms* Uniforms = nullptr; + FMaterialState* Materials = nullptr; + int Start = 0; + int Count = 0; +}; + class LevelMesh { public: @@ -45,6 +64,44 @@ public: TArray Portals; + GeometryAllocInfo AllocGeometry(int vertexCount, int indexCount) + { + GeometryAllocInfo info; + info.VertexStart = Mesh.Vertices.Size(); + info.VertexCount = vertexCount; + info.IndexStart = Mesh.Indexes.Size(); + info.IndexCount = indexCount; + Mesh.Vertices.Resize(info.VertexStart + vertexCount); + Mesh.UniformIndexes.Resize(info.VertexStart + vertexCount); + Mesh.Indexes.Resize(info.IndexStart + indexCount); + info.Vertices = &Mesh.Vertices[info.VertexStart]; + info.UniformIndexes = &Mesh.UniformIndexes[info.VertexStart]; + info.Indexes = &Mesh.Indexes[info.IndexStart]; + return info; + } + + UniformsAllocInfo AllocUniforms(int count) + { + UniformsAllocInfo info; + info.Start = Mesh.Uniforms.Size(); + info.Count = count; + Mesh.Uniforms.Resize(info.Start + count); + Mesh.Materials.Resize(info.Start + count); + info.Uniforms = &Mesh.Uniforms[info.Start]; + info.Materials = &Mesh.Materials[info.Start]; + return info; + } + + void FreeGeometry(int vertexStart, int vertexCount, int indexStart, int indexCount) + { + for (int i = 0; i < indexCount; i++) + Mesh.Indexes[indexStart + i] = 0; + } + + void FreeUniforms(int start, int count) + { + } + struct { // Vertex data diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 066fd55a8..34b2952f7 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -455,37 +455,57 @@ void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, Mesh wallpart.DrawWall(&disp, state, translucent); } + int numVertices = 0; + int numIndexes = 0; + int numUniforms = 0; + for (auto& it : state.mSortedLists) + { + numUniforms++; + for (MeshDrawCommand& command : it.second.mDraws) + { + if (command.DrawType == DT_TriangleFan && command.Count >= 3) + { + numVertices += command.Count; + numIndexes += (command.Count - 2) * 3; + } + } + } + + GeometryAllocInfo ginfo = AllocGeometry(numVertices, numIndexes); + UniformsAllocInfo uinfo = AllocUniforms(numUniforms); + int pipelineID = 0; - int startVertIndex = Mesh.Vertices.Size(); - int startElementIndex = Mesh.Indexes.Size(); + int uniformsIndex = uinfo.Start; + int vertIndex = ginfo.VertexStart; for (auto& it : state.mSortedLists) { const MeshApplyState& applyState = it.first; pipelineID = screen->GetLevelMeshPipelineID(applyState.applyData, applyState.surfaceUniforms, applyState.material); - int uniformsIndex = Mesh.Uniforms.Size(); - Mesh.Uniforms.Push(applyState.surfaceUniforms); - Mesh.Materials.Push(applyState.material); - for (MeshDrawCommand& command : it.second.mDraws) { - for (int i = command.Start, end = command.Start + command.Count; i < end; i++) - { - Mesh.Vertices.Push(state.mVertices[i]); - Mesh.UniformIndexes.Push(uniformsIndex); - } - - if (command.DrawType == DT_TriangleFan) + if (command.DrawType == DT_TriangleFan && command.Count >= 3) { for (int i = 2, count = command.Count; i < count; i++) { - Mesh.Indexes.Push(startVertIndex); - Mesh.Indexes.Push(startVertIndex + i - 1); - Mesh.Indexes.Push(startVertIndex + i); + *(ginfo.Indexes++) = vertIndex; + *(ginfo.Indexes++) = vertIndex + i - 1; + *(ginfo.Indexes++) = vertIndex + i; } + + for (int i = command.Start, end = command.Start + command.Count; i < end; i++) + { + *(ginfo.Vertices++) = state.mVertices[i]; + *(ginfo.UniformIndexes++) = uniformsIndex; + } + vertIndex += command.Count; } } + + *(uinfo.Uniforms++) = applyState.surfaceUniforms; + *(uinfo.Materials++) = applyState.material; + uniformsIndex++; } state.mSortedLists.clear(); state.mVertices.Clear(); @@ -517,10 +537,10 @@ void DoomLevelMesh::CreateWallSurface(side_t* side, HWWallDispatcher& disp, Mesh surf.AlwaysUpdate = !!(side->sector->Flags & SECF_LM_DYNAMIC); surf.SectorGroup = sectorGroup[side->sector->Index()]; surf.Alpha = float(side->linedef->alpha); - surf.MeshLocation.StartVertIndex = startVertIndex; - surf.MeshLocation.StartElementIndex = startElementIndex; - surf.MeshLocation.NumVerts = Mesh.Vertices.Size() - startVertIndex; - surf.MeshLocation.NumElements = Mesh.Indexes.Size() - startElementIndex; + surf.MeshLocation.StartVertIndex = ginfo.VertexStart; + surf.MeshLocation.StartElementIndex = ginfo.IndexStart; + surf.MeshLocation.NumVerts = ginfo.VertexCount; + surf.MeshLocation.NumElements = ginfo.IndexCount; surf.Plane = FVector4(N.X, N.Y, 0.0f, v1 | N); surf.Texture = wallpart.texture; surf.PipelineID = pipelineID; @@ -627,18 +647,17 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state textureMatrix.loadIdentity(); int pipelineID = 0; - int uniformsIndex = 0; + const SurfaceUniforms* uniforms = nullptr; + const FMaterialState* material = nullptr; bool foundDraw = false; for (auto& it : state.mSortedLists) { const MeshApplyState& applyState = it.first; pipelineID = screen->GetLevelMeshPipelineID(applyState.applyData, applyState.surfaceUniforms, applyState.material); - uniformsIndex = Mesh.Uniforms.Size(); textureMatrix = applyState.textureMatrix; - Mesh.Uniforms.Push(applyState.surfaceUniforms); - Mesh.Materials.Push(applyState.material); - + uniforms = &applyState.surfaceUniforms; + material = &applyState.material; foundDraw = true; break; } @@ -649,6 +668,26 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state if (!foundDraw) continue; + int numVertices = 0; + int numIndexes = 0; + for (subsector_t* sub : flatpart.section->subsectors) + { + if (sub->numlines < 3) + continue; + numVertices += sub->numlines; + numIndexes += (sub->numlines - 2) * 3; + } + + GeometryAllocInfo ginfo = AllocGeometry(numVertices, numIndexes); + UniformsAllocInfo uinfo = AllocUniforms(1); + + *uinfo.Uniforms = *uniforms; + *uinfo.Materials = *material; + + int uniformsIndex = uinfo.Start; + int vertIndex = ginfo.VertexStart; + int elementIndex = ginfo.IndexStart; + uint16_t sampleDimension = 0; if (flatpart.ceiling) { @@ -683,8 +722,10 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state if (sub->numlines < 3) continue; - int startVertIndex = Mesh.Vertices.Size(); - int startElementIndex = Mesh.Indexes.Size(); + int startVertIndex = vertIndex; + int startElementIndex = elementIndex; + vertIndex += sub->numlines; + elementIndex += (sub->numlines - 2) * 3; for (int i = 0, end = sub->numlines; i < end; i++) { @@ -703,26 +744,26 @@ void DoomLevelMesh::CreateFlatSurface(HWFlatDispatcher& disp, MeshBuilder& state ffv.lv = 0.0f; ffv.lindex = -1.0f; - Mesh.Vertices.Push(ffv); - Mesh.UniformIndexes.Push(uniformsIndex); + *(ginfo.Vertices++) = ffv; + *(ginfo.UniformIndexes++) = uniformsIndex; } if (flatpart.ceiling) { for (int i = 2, count = sub->numlines; i < count; i++) { - Mesh.Indexes.Push(startVertIndex); - Mesh.Indexes.Push(startVertIndex + i - 1); - Mesh.Indexes.Push(startVertIndex + i); + *(ginfo.Indexes++) = startVertIndex; + *(ginfo.Indexes++) = startVertIndex + i - 1; + *(ginfo.Indexes++) = startVertIndex + i; } } else { for (int i = 2, count = sub->numlines; i < count; i++) { - Mesh.Indexes.Push(startVertIndex + i); - Mesh.Indexes.Push(startVertIndex + i - 1); - Mesh.Indexes.Push(startVertIndex); + *(ginfo.Indexes++) = startVertIndex + i; + *(ginfo.Indexes++) = startVertIndex + i - 1; + *(ginfo.Indexes++) = startVertIndex; } }