From 240d68d7ae54718fd376df0e1a950ff06165372d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 20 Oct 2023 04:06:57 +0200 Subject: [PATCH] Merge SurfaceVertex with FFlatVertex and draw the lightmaps --- src/common/2d/v_2ddrawer.cpp | 2 +- src/common/2d/v_2ddrawer.h | 4 +- .../rendering/hwrenderer/data/flatvertices.h | 7 +- .../hwrenderer/data/hw_collision.cpp | 26 +- .../rendering/hwrenderer/data/hw_collision.h | 5 +- .../hwrenderer/data/hw_levelmesh.cpp | 2 - .../rendering/hwrenderer/data/hw_levelmesh.h | 5 +- .../rendering/hwrenderer/data/hw_mesh.cpp | 4 +- .../hwrenderer/data/hw_modelvertexbuffer.cpp | 4 +- .../rendering/hwrenderer/data/hw_skydome.cpp | 4 +- .../rendering/hwrenderer/data/hw_skydome.h | 2 +- src/common/rendering/i_modelvertexbuffer.h | 2 +- .../vulkan/accelstructs/vk_lightmap.cpp | 16 +- .../vulkan/accelstructs/vk_lightmap.h | 2 + .../vulkan/accelstructs/vk_raytrace.cpp | 17 +- .../vulkan/accelstructs/vk_raytrace.h | 11 +- .../rendering/vulkan/buffers/vk_rsbuffers.cpp | 4 +- .../rendering/vulkan/vk_renderdevice.cpp | 8 +- src/maploader/maploader.cpp | 14 +- src/rendering/hwrenderer/doom_levelmesh.cpp | 324 +++++++++--------- src/rendering/hwrenderer/doom_levelmesh.h | 5 +- src/rendering/hwrenderer/hw_vertexbuilder.cpp | 9 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 28 +- .../shaders/lightmap/binding_raytrace.glsl | 7 +- wadsrc/static/shaders/scene/bones.glsl | 6 +- wadsrc/static/shaders/scene/frag_main.glsl | 9 +- wadsrc/static/shaders/scene/layout_vert.glsl | 2 +- wadsrc/static/shaders/scene/light_shadow.glsl | 4 +- wadsrc/static/shaders/scene/vert_main.glsl | 6 +- 29 files changed, 263 insertions(+), 276 deletions(-) diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp index 24ca58e8f..3398c3be2 100644 --- a/src/common/2d/v_2ddrawer.cpp +++ b/src/common/2d/v_2ddrawer.cpp @@ -1217,7 +1217,7 @@ void F2DDrawer::OnFrameDone() F2DVertexBuffer::F2DVertexBuffer() { static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(F2DDrawer::TwoDVertex, x) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(F2DDrawer::TwoDVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(F2DDrawer::TwoDVertex, u) }, { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(F2DDrawer::TwoDVertex, color0) } }; diff --git a/src/common/2d/v_2ddrawer.h b/src/common/2d/v_2ddrawer.h index 5a6111225..5c10c0bc7 100644 --- a/src/common/2d/v_2ddrawer.h +++ b/src/common/2d/v_2ddrawer.h @@ -88,7 +88,7 @@ public: // This vertex type is hardware independent and needs conversion when put into a buffer. struct TwoDVertex { - float x, y, z; + float x, y, z, lindex; float u, v; PalEntry color0; @@ -100,6 +100,7 @@ public: u = 0; v = 0; color0 = 0; + lindex = -1.0f; } void Set(double xx, double yy, double zz, double uu, double vv, PalEntry col) @@ -110,6 +111,7 @@ public: u = (float)uu; v = (float)vv; color0 = col; + lindex = -1.0f; } }; diff --git a/src/common/rendering/hwrenderer/data/flatvertices.h b/src/common/rendering/hwrenderer/data/flatvertices.h index eac2107e7..1e13fd5b5 100644 --- a/src/common/rendering/hwrenderer/data/flatvertices.h +++ b/src/common/rendering/hwrenderer/data/flatvertices.h @@ -1,11 +1,11 @@ #pragma once -struct FFlatVertex +struct FFlatVertex // Note: this must always match the SurfaceVertex struct in shaders (std430 layout rules apply) { float x, z, y; // world position + float lindex; // lightmap texture index float u, v; // texture coordinates float lu, lv; // lightmap texture coordinates - float lindex; // lightmap texture index void Set(float xx, float zz, float yy, float uu, float vv) { @@ -22,11 +22,11 @@ struct FFlatVertex x = xx; z = zz; y = yy; + lindex = llindex; u = uu; v = vv; lu = llu; lv = llv; - lindex = llindex; } void SetVertex(float _x, float _y, float _z = 0) @@ -42,4 +42,5 @@ struct FFlatVertex v = _v; } + FVector3 fPos() const { return FVector3(x, y, z); } }; diff --git a/src/common/rendering/hwrenderer/data/hw_collision.cpp b/src/common/rendering/hwrenderer/data/hw_collision.cpp index 7978750bc..b41455607 100644 --- a/src/common/rendering/hwrenderer/data/hw_collision.cpp +++ b/src/common/rendering/hwrenderer/data/hw_collision.cpp @@ -28,7 +28,7 @@ #include #endif -TriangleMeshShape::TriangleMeshShape(const FVector3 *vertices, int num_vertices, const unsigned int *elements, int num_elements) +TriangleMeshShape::TriangleMeshShape(const FFlatVertex *vertices, int num_vertices, const unsigned int *elements, int num_elements) : vertices(vertices), num_vertices(num_vertices), elements(elements), num_elements(num_elements) { int num_triangles = num_elements / 3; @@ -44,7 +44,7 @@ TriangleMeshShape::TriangleMeshShape(const FVector3 *vertices, int num_vertices, triangles.push_back(i); int element_index = i * 3; - FVector3 centroid = (vertices[elements[element_index + 0]] + vertices[elements[element_index + 1]] + vertices[elements[element_index + 2]]) * (1.0f / 3.0f); + FVector3 centroid = (vertices[elements[element_index + 0]].fPos() + vertices[elements[element_index + 1]].fPos() + vertices[elements[element_index + 2]].fPos()) * (1.0f / 3.0f); centroids.push_back(centroid); } @@ -280,9 +280,9 @@ float TriangleMeshShape::intersect_triangle_ray(TriangleMeshShape *shape, const FVector3 p[3] = { - shape->vertices[shape->elements[start_element]], - shape->vertices[shape->elements[start_element + 1]], - shape->vertices[shape->elements[start_element + 2]] + shape->vertices[shape->elements[start_element]].fPos(), + shape->vertices[shape->elements[start_element + 1]].fPos(), + shape->vertices[shape->elements[start_element + 2]].fPos() }; // Moeller–Trumbore ray-triangle intersection algorithm: @@ -356,9 +356,9 @@ float TriangleMeshShape::sweep_intersect_triangle_sphere(TriangleMeshShape *shap FVector3 p[3] = { - shape1->vertices[shape1->elements[start_element]], - shape1->vertices[shape1->elements[start_element + 1]], - shape1->vertices[shape1->elements[start_element + 2]] + shape1->vertices[shape1->elements[start_element]].fPos(), + shape1->vertices[shape1->elements[start_element + 1]].fPos(), + shape1->vertices[shape1->elements[start_element + 2]].fPos() }; FVector3 c = shape2->center; @@ -528,9 +528,9 @@ bool TriangleMeshShape::overlap_triangle_sphere(TriangleMeshShape *shape1, Spher int element_index = shape1->nodes[shape1_node_index].element_index; FVector3 P = shape2->center; - FVector3 A = shape1->vertices[shape1->elements[element_index]] - P; - FVector3 B = shape1->vertices[shape1->elements[element_index + 1]] - P; - FVector3 C = shape1->vertices[shape1->elements[element_index + 2]] - P; + FVector3 A = shape1->vertices[shape1->elements[element_index]].fPos() - P; + FVector3 B = shape1->vertices[shape1->elements[element_index + 1]].fPos() - P; + FVector3 C = shape1->vertices[shape1->elements[element_index + 2]].fPos() - P; float r = shape2->radius; float rr = r * r; @@ -640,14 +640,14 @@ int TriangleMeshShape::subdivide(int *triangles, int num_triangles, const FVecto // Find bounding box and median of the triangle centroids FVector3 median; FVector3 min, max; - min = vertices[elements[triangles[0] * 3]]; + min = vertices[elements[triangles[0] * 3]].fPos(); max = min; for (int i = 0; i < num_triangles; i++) { int element_index = triangles[i] * 3; for (int j = 0; j < 3; j++) { - const FVector3 &vertex = vertices[elements[element_index + j]]; + const FVector3 &vertex = vertices[elements[element_index + j]].fPos(); min.X = std::min(min.X, vertex.X); min.Y = std::min(min.Y, vertex.Y); diff --git a/src/common/rendering/hwrenderer/data/hw_collision.h b/src/common/rendering/hwrenderer/data/hw_collision.h index 756ffc031..911fe947e 100644 --- a/src/common/rendering/hwrenderer/data/hw_collision.h +++ b/src/common/rendering/hwrenderer/data/hw_collision.h @@ -23,6 +23,7 @@ #pragma once #include "common/utility/vectors.h" +#include "flatvertices.h" #include #include @@ -86,7 +87,7 @@ public: class TriangleMeshShape { public: - TriangleMeshShape(const FVector3 *vertices, int num_vertices, const unsigned int *elements, int num_elements); + TriangleMeshShape(const FFlatVertex *vertices, int num_vertices, const unsigned int *elements, int num_elements); int get_min_depth() const; int get_max_depth() const; @@ -121,7 +122,7 @@ public: int get_root() const { return root; } private: - const FVector3 *vertices = nullptr; + const FFlatVertex* vertices = nullptr; const int num_vertices = 0; const unsigned int *elements = nullptr; int num_elements = 0; diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp index 6b8a74021..272ca09cd 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -80,8 +80,6 @@ LevelSubmesh::LevelSubmesh() MeshVertices.Push({ minval, maxval, maxval }); MeshVertices.Push({ maxval, maxval, maxval }); - MeshVertexUVs.Resize(MeshVertices.Size()); - for (int i = 0; i < 3 * 4; i++) MeshElements.Push(i); diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index d8e287bf2..3dd060165 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -9,6 +9,7 @@ #include #include #include "textureid.h" +#include "flatvertices.h" #include @@ -36,7 +37,6 @@ struct LevelMeshSurface int numVerts = 0; unsigned int startVertIndex = 0; - unsigned int startUvIndex = 0; unsigned int startElementIndex = 0; unsigned int numElements = 0; FVector4 plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f); @@ -183,8 +183,7 @@ public: virtual unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const { return 0xffffffff; } virtual int GetSurfaceCount() { return 0; } - TArray MeshVertices; - TArray MeshVertexUVs; + TArray MeshVertices; TArray MeshElements; TArray MeshSurfaceIndexes; diff --git a/src/common/rendering/hwrenderer/data/hw_mesh.cpp b/src/common/rendering/hwrenderer/data/hw_mesh.cpp index e061da43f..ddab5f767 100644 --- a/src/common/rendering/hwrenderer/data/hw_mesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_mesh.cpp @@ -13,9 +13,9 @@ void Mesh::Draw(FRenderState& renderstate) { static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }, - { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) }, + { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) }, }; mVertexBuffer.reset(screen->CreateVertexBuffer(1, 3, sizeof(FFlatVertex), format)); mVertexBuffer->SetData(mVertices.Size() * sizeof(FFlatVertex), mVertices.Data(), BufferUsageType::Static); diff --git a/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp index c6e0d9783..6de55d36d 100644 --- a/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp +++ b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp @@ -41,10 +41,10 @@ FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) { static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FModelVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FModelVertex, u) }, { 0, VATTR_NORMAL, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) }, - { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FModelVertex, lu) }, + { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FModelVertex, lu) }, { 0, VATTR_BONESELECTOR, VFmt_Byte4_UInt, (int)myoffsetof(FModelVertex, boneselector[0])}, { 0, VATTR_BONEWEIGHT, VFmt_Byte4, (int)myoffsetof(FModelVertex, boneweight[0]) }, { 1, VATTR_VERTEX2, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, diff --git a/src/common/rendering/hwrenderer/data/hw_skydome.cpp b/src/common/rendering/hwrenderer/data/hw_skydome.cpp index 3c2b903fd..a15735492 100644 --- a/src/common/rendering/hwrenderer/data/hw_skydome.cpp +++ b/src/common/rendering/hwrenderer/data/hw_skydome.cpp @@ -124,10 +124,10 @@ FSkyVertexBuffer::FSkyVertexBuffer(DFrameBuffer* fb) : fb(fb) CreateDome(); static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FSkyVertex, x) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FSkyVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FSkyVertex, u) }, { 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) }, - { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FSkyVertex, lu) }, + { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FSkyVertex, lu) }, }; mVertexBuffer = fb->CreateVertexBuffer(1, 4, sizeof(FSkyVertex), format); mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], BufferUsageType::Static); diff --git a/src/common/rendering/hwrenderer/data/hw_skydome.h b/src/common/rendering/hwrenderer/data/hw_skydome.h index 7bd402289..400c9f061 100644 --- a/src/common/rendering/hwrenderer/data/hw_skydome.h +++ b/src/common/rendering/hwrenderer/data/hw_skydome.h @@ -17,7 +17,7 @@ const int skyoffsetfactor = 57; struct FSkyVertex { - float x, y, z, u, v, lu, lv, lindex; + float x, y, z, lindex, u, v, lu, lv; PalEntry color; void Set(float xx, float zz, float yy, float uu=0, float vv=0, PalEntry col=0xffffffff) diff --git a/src/common/rendering/i_modelvertexbuffer.h b/src/common/rendering/i_modelvertexbuffer.h index 927fcfbf3..1d1bed9c4 100644 --- a/src/common/rendering/i_modelvertexbuffer.h +++ b/src/common/rendering/i_modelvertexbuffer.h @@ -6,10 +6,10 @@ struct FModelVertex { float x, y, z; // world position + float lindex; // lightmap texture index float u, v; // texture coordinates unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. float lu, lv; // lightmap texture coordinates - float lindex; // lightmap texture index uint8_t boneselector[4]; uint8_t boneweight[4]; diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index 90fe427f6..b3ae224eb 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -201,9 +201,9 @@ void VkLightmap::Render() pc.TextureSize = (float)bakeImageSize; pc.TileWidth = (float)targetSurface->AtlasTile.Width; pc.TileHeight = (float)targetSurface->AtlasTile.Height; - pc.WorldToLocal = targetSurface->translateWorldToLocal; - pc.ProjLocalToU = targetSurface->projLocalToU; - pc.ProjLocalToV = targetSurface->projLocalToV; + pc.WorldToLocal = SwapYZ(targetSurface->translateWorldToLocal); + pc.ProjLocalToU = SwapYZ(targetSurface->projLocalToU); + pc.ProjLocalToV = SwapYZ(targetSurface->projLocalToV); bool buffersFull = false; @@ -229,13 +229,13 @@ void VkLightmap::Render() for (int i = 0; i < lightCount; i++) { const LevelMeshLight* light = &templightlist[i]; - lightinfo->Origin = light->Origin; - lightinfo->RelativeOrigin = light->RelativeOrigin; + lightinfo->Origin = SwapYZ(light->Origin); + lightinfo->RelativeOrigin = SwapYZ(light->RelativeOrigin); lightinfo->Radius = light->Radius; lightinfo->Intensity = light->Intensity; lightinfo->InnerAngleCos = light->InnerAngleCos; lightinfo->OuterAngleCos = light->OuterAngleCos; - lightinfo->SpotDir = light->SpotDir; + lightinfo->SpotDir = SwapYZ(light->SpotDir); lightinfo->Color = light->Color; lightinfo++; } @@ -294,7 +294,7 @@ void VkLightmap::Render() void VkLightmap::UploadUniforms() { Uniforms values = {}; - values.SunDir = mesh->SunDirection; + values.SunDir = SwapYZ(mesh->SunDirection); values.SunColor = mesh->SunColor; values.SunIntensity = 1.0f; @@ -760,7 +760,7 @@ void VkLightmap::CreateRaytracePipeline() .RenderPass(raytrace.renderPass.get()) .AddVertexShader(shaders.vertRaytrace.get()) .AddFragmentShader(shaders.fragRaytrace[i].get()) - .AddVertexBufferBinding(0, sizeof(SurfaceVertex)) + .AddVertexBufferBinding(0, sizeof(FFlatVertex)) .AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0) .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) .AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT) diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h index f920c9d50..13240c1db 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h @@ -158,6 +158,8 @@ private: static FString LoadPublicShaderLump(const char* lumpname); static ShaderIncludeResult OnInclude(FString headerName, FString includerName, size_t depth, bool system); + FVector3 SwapYZ(const FVector3& v) { return FVector3(v.X, v.Z, v.Y); } + VulkanRenderDevice* fb = nullptr; LevelMesh* mesh = nullptr; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index 52913618e..8cfd4ad4c 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -141,7 +141,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) for (unsigned int i = start; i < end; i++) { const SubmeshBufferLocation& cur = locations[i]; - transferBufferSize += cur.Submesh->MeshVertices.Size() * sizeof(SurfaceVertex); + transferBufferSize += cur.Submesh->MeshVertices.Size() * sizeof(FFlatVertex); transferBufferSize += cur.Submesh->MeshElements.Size() * sizeof(uint32_t); transferBufferSize += cur.Submesh->Collision->get_nodes().size() * sizeof(CollisionNode); transferBufferSize += cur.Submesh->MeshSurfaceIndexes.Size() * sizeof(int); @@ -205,13 +205,10 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) const SubmeshBufferLocation& cur = locations[i]; auto submesh = cur.Submesh; - SurfaceVertex* vertices = (SurfaceVertex*)(data + datapos); - for (int j = 0, count = submesh->MeshVertices.Size(); j < count; ++j) - *(vertices++) = { { submesh->MeshVertices[j], 1.0f }, submesh->MeshVertexUVs[j], float(j), j + 10000.0f, FVector3(0.0f, 0.0f, -1.0f), 0.0f}; - - size_t copysize = submesh->MeshVertices.Size() * sizeof(SurfaceVertex); + size_t copysize = submesh->MeshVertices.Size() * sizeof(FFlatVertex); + memcpy(data + datapos, submesh->MeshVertices.Data(), copysize); if (copysize > 0) - cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(SurfaceVertex), copysize); + cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(FFlatVertex), copysize); datapos += copysize; } @@ -283,7 +280,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) LevelMeshSurface* surface = submesh->GetSurface(j); SurfaceInfo info; - info.Normal = surface->plane.XYZ(); + info.Normal = FVector3(surface->plane.X, surface->plane.Z, surface->plane.Y); info.PortalIndex = surface->portalIndex; info.SamplingDistance = (float)surface->sampleDimension; info.Sky = surface->bSky; @@ -371,7 +368,7 @@ void VkRaytrace::CreateBuffers() VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0) | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) - .Size(GetMaxVertexBufferSize() * sizeof(SurfaceVertex)) + .Size(GetMaxVertexBufferSize() * sizeof(FFlatVertex)) .DebugName("VertexBuffer") .Create(fb->GetDevice()); @@ -425,7 +422,7 @@ VkRaytrace::BLAS VkRaytrace::CreateBLAS(LevelSubmesh* submesh, bool preferFastBu accelStructBLDesc.geometry.triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR }; accelStructBLDesc.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; accelStructBLDesc.geometry.triangles.vertexData.deviceAddress = VertexBuffer->GetDeviceAddress(); - accelStructBLDesc.geometry.triangles.vertexStride = sizeof(SurfaceVertex); + accelStructBLDesc.geometry.triangles.vertexStride = sizeof(FFlatVertex); accelStructBLDesc.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32; accelStructBLDesc.geometry.triangles.indexData.deviceAddress = IndexBuffer->GetDeviceAddress() + indexOffset * sizeof(uint32_t); accelStructBLDesc.geometry.triangles.maxVertex = vertexOffset + submesh->MeshVertices.Size() - 1; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h index 64c644497..9a0b8f682 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h @@ -37,15 +37,6 @@ struct SurfaceInfo float Alpha; }; -struct SurfaceVertex -{ - FVector4 pos; - FVector2 uv; - float Padding1, Padding2; - FVector3 lightmap; - float Padding3; -}; - struct PortalInfo { VSMatrix transformation; @@ -125,7 +116,7 @@ private: std::unique_ptr NodeBuffer; - TArray Vertices; + TArray Vertices; static const int MaxDynamicVertices = 100'000; static const int MaxDynamicIndexes = 100'000; static const int MaxDynamicSurfaces = 100'000; diff --git a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp index 960894f84..f9cb50039 100644 --- a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp +++ b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp @@ -32,9 +32,9 @@ VkRSBuffers::VkRSBuffers(VulkanRenderDevice* fb) { static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }, - { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) }, + { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) }, }; Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format); diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 8e0b39558..9614bc833 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -657,11 +657,11 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint) static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(SurfaceVertex, pos.X) }, - { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(SurfaceVertex, uv.X) }, - { 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(SurfaceVertex, lightmap.X) }, + { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) }, + { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }, + { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) }, }; - int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(SurfaceVertex), format); + int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format); VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetVertexBuffer()->buffer }; VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index aa22333dc..4272a4dfb 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3357,27 +3357,27 @@ bool MapLoader::LoadLightmap(MapData* map) { auto& realSurface = *surface.targetSurface; - auto* UVs = &submesh->LightmapUvs[realSurface.startUvIndex]; + auto* vertices = &submesh->MeshVertices[realSurface.startVertIndex]; auto* newUVs = &zdrayUvs[surface.uvOffset]; for (uint32_t i = 0; i < surface.uvCount; ++i) { - FVector2 oldUv = UVs[i]; + FVector2 oldUv = FVector2(vertices[i].lu, vertices[i].lv); if (developer >= 5) { - Printf("Old UV: %.6f %.6f (w:%d, h:%d) (x:%d, y:%d), Lump UVs %.3f %.3f\n", UVs[i].X, UVs[i].Y, realSurface.AtlasTile.Width, realSurface.AtlasTile.Height, realSurface.AtlasTile.X, realSurface.AtlasTile.Y, newUVs[i].X, newUVs[i].Y); + Printf("Old UV: %.6f %.6f (w:%d, h:%d) (x:%d, y:%d), Lump UVs %.3f %.3f\n", vertices[i].lu, vertices[i].lv, realSurface.AtlasTile.Width, realSurface.AtlasTile.Height, realSurface.AtlasTile.X, realSurface.AtlasTile.Y, newUVs[i].X, newUVs[i].Y); } // Finish surface - UVs[i].X = (newUVs[i].X + realSurface.AtlasTile.X) / textureSize; - UVs[i].Y = (newUVs[i].Y + realSurface.AtlasTile.Y) / textureSize; + vertices[i].lu = (newUVs[i].X + realSurface.AtlasTile.X) / textureSize; + vertices[i].lv = (newUVs[i].Y + realSurface.AtlasTile.Y) / textureSize; if (developer >= 5) { - if (abs(oldUv.X - UVs[i].X) >= 0.0000001f || abs(oldUv.Y - UVs[i].Y) >= 0.0000001f) + if (abs(oldUv.X - vertices[i].lu) >= 0.0000001f || abs(oldUv.Y - vertices[i].lv) >= 0.0000001f) { - Printf("New UV: %.6f %.6f\n", UVs[i].X, UVs[i].Y); + Printf("New UV: %.6f %.6f\n", vertices[i].lu, vertices[i].lv); } } } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 5ab386334..97a126e03 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -267,7 +267,6 @@ int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLi void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) { MeshVertices.Clear(); - MeshVertexUVs.Clear(); MeshElements.Clear(); LightmapSampleDistance = doomMap.LightmapSampleDistance; @@ -299,10 +298,8 @@ void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap, int lightmapStartInd { Surfaces.Clear(); MeshVertices.Clear(); - MeshVertexUVs.Clear(); MeshElements.Clear(); MeshSurfaceIndexes.Clear(); - LightmapUvs.Clear(); // Look for polyobjects for (unsigned int i = 0; i < doomMap.lines.Size(); i++) @@ -340,16 +337,16 @@ void DoomLevelSubmesh::CreateIndexes() DoomLevelMeshSurface& s = Surfaces[i]; int numVerts = s.numVerts; unsigned int pos = s.startVertIndex; - FVector3* verts = &MeshVertices[pos]; + FFlatVertex* verts = &MeshVertices[pos]; s.startElementIndex = MeshElements.Size(); s.numElements = 0; - if (s.Type == ST_FLOOR || s.Type == ST_CEILING) + if (s.Type == ST_CEILING) { for (int j = 2; j < numVerts; j++) { - if (!IsDegenerate(verts[0], verts[j - 1], verts[j])) + if (!IsDegenerate(verts[0].fPos(), verts[j - 1].fPos(), verts[j].fPos())) { MeshElements.Push(pos); MeshElements.Push(pos + j - 1); @@ -359,9 +356,23 @@ void DoomLevelSubmesh::CreateIndexes() } } } + else if (s.Type == ST_FLOOR) + { + for (int j = 2; j < numVerts; j++) + { + if (!IsDegenerate(verts[0].fPos(), verts[j - 1].fPos(), verts[j].fPos())) + { + MeshElements.Push(pos + j); + MeshElements.Push(pos + j - 1); + MeshElements.Push(pos); + MeshSurfaceIndexes.Push((int)i); + s.numElements += 3; + } + } + } else if (s.Type == ST_MIDDLESIDE || s.Type == ST_UPPERSIDE || s.Type == ST_LOWERSIDE) { - if (!IsDegenerate(verts[0], verts[1], verts[2])) + if (!IsDegenerate(verts[0].fPos(), verts[2].fPos(), verts[1].fPos())) { MeshElements.Push(pos + 0); MeshElements.Push(pos + 1); @@ -369,11 +380,11 @@ void DoomLevelSubmesh::CreateIndexes() MeshSurfaceIndexes.Push((int)i); s.numElements += 3; } - if (!IsDegenerate(verts[1], verts[2], verts[3])) + if (!IsDegenerate(verts[0].fPos(), verts[2].fPos(), verts[3].fPos())) { - MeshElements.Push(pos + 3); + MeshElements.Push(pos + 0); MeshElements.Push(pos + 2); - MeshElements.Push(pos + 1); + MeshElements.Push(pos + 3); MeshSurfaceIndexes.Push((int)i); s.numElements += 3; } @@ -542,33 +553,11 @@ void DoomLevelSubmesh::CreatePortals() void DoomLevelSubmesh::BindLightmapSurfacesToGeometry(FLevelLocals& doomMap) { - // You have no idea how long this took me to figure out... - - // Reorder vertices into renderer format - for (DoomLevelMeshSurface& surface : Surfaces) - { - if (surface.Type == ST_FLOOR) - { - // reverse vertices on floor - for (int j = surface.startUvIndex + surface.numVerts - 1, k = surface.startUvIndex; j > k; j--, k++) - { - std::swap(LightmapUvs[k], LightmapUvs[j]); - } - } - else if (surface.Type != ST_CEILING) // walls - { - // from 0 1 2 3 - // to 0 2 1 3 - std::swap(LightmapUvs[surface.startUvIndex + 1], LightmapUvs[surface.startUvIndex + 2]); - std::swap(LightmapUvs[surface.startUvIndex + 2], LightmapUvs[surface.startUvIndex + 3]); - } - - surface.TexCoords = (float*)&LightmapUvs[surface.startUvIndex]; - } - // Link surfaces for (auto& surface : Surfaces) { + surface.Vertices = &MeshVertices[surface.startVertIndex]; + if (surface.Type == ST_FLOOR || surface.Type == ST_CEILING) { surface.Subsector = &doomMap.subsectors[surface.TypeIndex]; @@ -648,15 +637,15 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevelLocals& doomMap, side_t* si float v2Top = (float)front->ceilingplane.ZatPoint(v2); float v2Bottom = (float)front->floorplane.ZatPoint(v2); - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; - verts[0].Z = v1Bottom; - verts[1].Z = v2Bottom; - verts[2].Z = v1Top; - verts[3].Z = v2Top; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; + verts[0].z = v1Bottom; + verts[1].z = v2Bottom; + verts[2].z = v1Top; + verts[3].z = v2Top; DoomLevelMeshSurface surf; surf.Submesh = this; @@ -672,7 +661,7 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevelLocals& doomMap, side_t* si MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); @@ -751,24 +740,24 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevelLocals& doomMap, side_t* s surf.bSky = front->GetTexture(sector_t::floor) == skyflatnum || front->GetTexture(sector_t::ceiling) == skyflatnum; surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; - verts[0].Z = v1Bottom; - verts[1].Z = v2Bottom; - verts[2].Z = v1Top; - verts[3].Z = v2Top; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; + verts[0].z = v1Bottom; + verts[1].z = v2Bottom; + verts[2].z = v1Top; + verts[3].z = v2Top; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); - MeshVertices.Push(verts[1]); MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); @@ -796,15 +785,15 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid float v2Top = (float)front->ceilingplane.ZatPoint(v2); float v2Bottom = (float)front->floorplane.ZatPoint(v2); - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; - verts[0].Z = v1Bottom; - verts[1].Z = v2Bottom; - verts[2].Z = v1Top; - verts[3].Z = v2Top; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; + verts[0].z = v1Bottom; + verts[1].z = v2Bottom; + verts[2].z = v1Top; + verts[3].z = v2Top; DoomLevelMeshSurface surf; surf.Submesh = this; @@ -813,11 +802,11 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid surf.numVerts = 4; surf.bSky = false; MeshVertices.Push(verts[0]); - MeshVertices.Push(verts[1]); MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; @@ -843,20 +832,20 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) float v2Top = (float)front->ceilingplane.ZatPoint(v2); float v2Bottom = (float)front->floorplane.ZatPoint(v2); - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; const auto& texture = side->textures[side_t::mid].texture; if ((side->Flags & WALLF_WRAP_MIDTEX) || (side->linedef->flags & WALLF_WRAP_MIDTEX)) { - verts[0].Z = v1Bottom; - verts[1].Z = v2Bottom; - verts[2].Z = v1Top; - verts[3].Z = v2Top; + verts[0].z = v1Bottom; + verts[1].z = v2Bottom; + verts[2].z = v1Top; + verts[3].z = v2Top; } else { @@ -880,10 +869,10 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) yTextureOffset += (float)(side->sector->planes[sector_t::ceiling].TexZ - gameTexture->GetDisplayHeight() / side->textures[side_t::mid].yScale); } - verts[0].Z = min(max(yTextureOffset + mid1Bottom, v1Bottom), v1Top); - verts[1].Z = min(max(yTextureOffset + mid2Bottom, v2Bottom), v2Top); - verts[2].Z = max(min(yTextureOffset + mid1Top, v1Top), v1Bottom); - verts[3].Z = max(min(yTextureOffset + mid2Top, v2Top), v2Bottom); + verts[0].z = min(max(yTextureOffset + mid1Bottom, v1Bottom), v1Top); + verts[1].z = min(max(yTextureOffset + mid2Bottom, v2Bottom), v2Top); + verts[2].z = max(min(yTextureOffset + mid1Top, v1Top), v1Bottom); + verts[3].z = max(min(yTextureOffset + mid2Top, v2Top), v2Bottom); } // mid texture @@ -893,9 +882,7 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; surf.bSky = false; - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); - - FVector3 offset = surf.plane.XYZ() * 0.05f; // for better accuracy when raytracing mid-textures from each side + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); if (side->linedef->sidedef[0] != side) { @@ -903,10 +890,10 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) surf.plane.W = -surf.plane.W; } - MeshVertices.Push(verts[0] + offset); - MeshVertices.Push(verts[1] + offset); - MeshVertices.Push(verts[2] + offset); - MeshVertices.Push(verts[3] + offset); + MeshVertices.Push(verts[0]); + MeshVertices.Push(verts[2]); + MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); @@ -917,7 +904,7 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) surf.alpha = float(side->linedef->alpha); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); - SetSideTextureUVs(surf, side, side_t::top, verts[2].Z, verts[0].Z, verts[3].Z, verts[1].Z); + SetSideTextureUVs(surf, side, side_t::top, verts[2].z, verts[0].z, verts[3].z, verts[1].z); Surfaces.Push(surf); } @@ -965,24 +952,24 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevelLocals& doomMap, side_t* float tlZ = (float)xfloor->model->ceilingplane.ZatPoint(v1); float trZ = (float)xfloor->model->ceilingplane.ZatPoint(v2); - FVector3 verts[4]; - verts[0].X = verts[2].X = v2.X; - verts[0].Y = verts[2].Y = v2.Y; - verts[1].X = verts[3].X = v1.X; - verts[1].Y = verts[3].Y = v1.Y; - verts[0].Z = brZ; - verts[1].Z = blZ; - verts[2].Z = trZ; - verts[3].Z = tlZ; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v2.X; + verts[0].y = verts[2].y = v2.Y; + verts[1].x = verts[3].x = v1.X; + verts[1].y = verts[3].y = v1.Y; + verts[0].z = brZ; + verts[1].z = blZ; + verts[2].z = trZ; + verts[3].z = tlZ; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); - MeshVertices.Push(verts[1]); MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.texture = side->textures[side_t::mid].texture; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); @@ -1010,26 +997,26 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) if (!bSky && !IsTopSideVisible(side)) return; - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; - verts[0].Z = v1TopBack; - verts[1].Z = v2TopBack; - verts[2].Z = v1Top; - verts[3].Z = v2Top; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; + verts[0].z = v1TopBack; + verts[1].z = v2TopBack; + verts[2].z = v1Top; + verts[3].z = v2Top; DoomLevelMeshSurface surf; surf.Submesh = this; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); - MeshVertices.Push(verts[1]); MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_UPPERSIDE; surf.TypeIndex = side->Index(); surf.bSky = bSky; @@ -1060,26 +1047,26 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si float v1BottomBack = (float)back->floorplane.ZatPoint(v1); float v2BottomBack = (float)back->floorplane.ZatPoint(v2); - FVector3 verts[4]; - verts[0].X = verts[2].X = v1.X; - verts[0].Y = verts[2].Y = v1.Y; - verts[1].X = verts[3].X = v2.X; - verts[1].Y = verts[3].Y = v2.Y; - verts[0].Z = v1Bottom; - verts[1].Z = v2Bottom; - verts[2].Z = v1BottomBack; - verts[3].Z = v2BottomBack; + FFlatVertex verts[4]; + verts[0].x = verts[2].x = v1.X; + verts[0].y = verts[2].y = v1.Y; + verts[1].x = verts[3].x = v2.X; + verts[1].y = verts[3].y = v2.Y; + verts[0].z = v1Bottom; + verts[1].z = v2Bottom; + verts[2].z = v1BottomBack; + verts[3].z = v2BottomBack; DoomLevelMeshSurface surf; surf.Submesh = this; surf.startVertIndex = MeshVertices.Size(); surf.numVerts = 4; MeshVertices.Push(verts[0]); - MeshVertices.Push(verts[1]); MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + MeshVertices.Push(verts[1]); - surf.plane = ToPlane(verts[0], verts[1], verts[2], verts[3]); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_LOWERSIDE; surf.TypeIndex = side->Index(); surf.bSky = false; @@ -1096,8 +1083,7 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, side_t* side, side_t::ETexpart texpart, float v1TopZ, float v1BottomZ, float v2TopZ, float v2BottomZ) { - MeshVertexUVs.Reserve(4); - FVector2* uvs = &MeshVertexUVs[surface.startVertIndex]; + FFlatVertex* uvs = &MeshVertices[surface.startVertIndex]; if (surface.texture.isValid()) { @@ -1109,26 +1095,30 @@ void DoomLevelSubmesh::SetSideTextureUVs(DoomLevelMeshSurface& surface, side_t* float startU = tci.FloatToTexU(tci.TextureOffset((float)side->GetTextureXOffset(texpart)) + tci.TextureOffset((float)side->GetTextureXOffset(texpart))); float endU = startU + tci.FloatToTexU(side->TexelLength); - uvs[0].X = startU; - uvs[1].X = endU; - uvs[2].X = startU; - uvs[3].X = endU; + uvs[0].u = startU; + uvs[1].u = endU; + uvs[2].u = startU; + uvs[3].u = endU; // To do: the ceiling version is apparently used in some situation related to 3d floors (rover->top.isceiling) //float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(sector_t::ceiling); float offset = tci.RowOffset((float)side->GetTextureYOffset(texpart)) + tci.RowOffset((float)side->GetTextureYOffset(texpart)) + (float)side->sector->GetPlaneTexZ(sector_t::floor); - uvs[0].Y = tci.FloatToTexV(offset - v1BottomZ); - uvs[1].Y = tci.FloatToTexV(offset - v2BottomZ); - uvs[2].Y = tci.FloatToTexV(offset - v1TopZ); - uvs[3].Y = tci.FloatToTexV(offset - v2TopZ); + uvs[0].v = tci.FloatToTexV(offset - v1BottomZ); + uvs[1].v = tci.FloatToTexV(offset - v2BottomZ); + uvs[2].v = tci.FloatToTexV(offset - v1TopZ); + uvs[3].v = tci.FloatToTexV(offset - v2TopZ); } else { - uvs[0] = FVector2(0.0f, 0.0f); - uvs[1] = FVector2(0.0f, 0.0f); - uvs[2] = FVector2(0.0f, 0.0f); - uvs[3] = FVector2(0.0f, 0.0f); + uvs[0].u = 0.0f; + uvs[0].v = 0.0f; + uvs[1].u = 0.0f; + uvs[1].v = 0.0f; + uvs[2].u = 0.0f; + uvs[2].v = 0.0f; + uvs[3].u = 0.0f; + uvs[3].v = 0.0f; } } @@ -1160,21 +1150,20 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor); MeshVertices.Resize(surf.startVertIndex + surf.numVerts); - MeshVertexUVs.Resize(surf.startVertIndex + surf.numVerts); - FVector3* verts = &MeshVertices[surf.startVertIndex]; - FVector2* uvs = &MeshVertexUVs[surf.startVertIndex]; + FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; for (int j = 0; j < surf.numVerts; j++) { - seg_t *seg = &sub->firstline[(surf.numVerts - 1) - j]; + seg_t* seg = &sub->firstline[j]; FVector2 v1 = ToFVector2(seg->v1->fPos()); + FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex - verts[j].X = v1.X; - verts[j].Y = v1.Y; - verts[j].Z = (float)plane.ZatPoint(verts[j]); - - uvs[j] = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex + verts[j].x = v1.X; + verts[j].y = v1.Y; + verts[j].z = (float)plane.ZatPoint(v1); + verts[j].u = uv.X; + verts[j].v = uv.Y; } surf.Type = ST_FLOOR; @@ -1216,21 +1205,20 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling); MeshVertices.Resize(surf.startVertIndex + surf.numVerts); - MeshVertexUVs.Resize(surf.startVertIndex + surf.numVerts); - FVector3* verts = &MeshVertices[surf.startVertIndex]; - FVector2* uvs = &MeshVertexUVs[surf.startVertIndex]; + FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; for (int j = 0; j < surf.numVerts; j++) { - seg_t *seg = &sub->firstline[j]; + seg_t* seg = &sub->firstline[j]; FVector2 v1 = ToFVector2(seg->v1->fPos()); + FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex - verts[j].X = v1.X; - verts[j].Y = v1.Y; - verts[j].Z = (float)plane.ZatPoint(verts[j]); - - uvs[j] = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex + verts[j].x = v1.X; + verts[j].y = v1.Y; + verts[j].z = (float)plane.ZatPoint(v1); + verts[j].u = uv.X; + verts[j].v = uv.Y; } surf.Type = ST_CEILING; @@ -1321,14 +1309,12 @@ void DoomLevelSubmesh::DumpMesh(const FString& objFilename, const FString& mtlFi for (const auto& v : MeshVertices) { - fprintf(f, "v %f %f %f\n", v.X * scale, v.Y * scale, v.Z * scale); + fprintf(f, "v %f %f %f\n", v.x * scale, v.y * scale, v.z * scale); } + for (const auto& v : MeshVertices) { - for (const auto& uv : LightmapUvs) - { - fprintf(f, "vt %f %f\n", uv.X, uv.Y); - } + fprintf(f, "vt %f %f\n", v.lu, v.lv); } auto name = [](DoomLevelMeshSurfaceType type) -> const char* { @@ -1459,10 +1445,10 @@ void DoomLevelSubmesh::PackLightmapAtlas(int lightmapStartIndex) // calculate final texture coordinates for (int i = 0; i < (int)surf->numVerts; i++) { - auto& u = LightmapUvs[surf->startUvIndex + i].X; - auto& v = LightmapUvs[surf->startUvIndex + i].Y; - u = (u + x) / (float)LMTextureSize; - v = (v + y) / (float)LMTextureSize; + auto& vertex = MeshVertices[surf->startVertIndex + i]; + vertex.lu = (vertex.lu + x) / (float)LMTextureSize; + vertex.lv = (vertex.lv + y) / (float)LMTextureSize; + vertex.lindex = (float)surf->AtlasTile.ArrayIndex; } } @@ -1480,13 +1466,13 @@ BBox DoomLevelSubmesh::GetBoundsFromSurface(const LevelMeshSurface& surface) con { for (int j = 0; j < 3; j++) { - if (MeshVertices[i][j] < low[j]) + if (MeshVertices[i].fPos()[j] < low[j]) { - low[j] = MeshVertices[i][j]; + low[j] = MeshVertices[i].fPos()[j]; } - if (MeshVertices[i][j] > hi[j]) + if (MeshVertices[i].fPos()[j] > hi[j]) { - hi[j] = MeshVertices[i][j]; + hi[j] = MeshVertices[i].fPos()[j]; } } } @@ -1598,14 +1584,12 @@ void DoomLevelSubmesh::BuildSurfaceParams(int lightMapTextureWidth, int lightMap surface.projLocalToU = tCoords[0]; surface.projLocalToV = tCoords[1]; - surface.startUvIndex = AllocUvs(surface.numVerts); - for (int i = 0; i < surface.numVerts; i++) { - FVector3 tDelta = MeshVertices[surface.startVertIndex + i] - surface.translateWorldToLocal; + FVector3 tDelta = MeshVertices[surface.startVertIndex + i].fPos() - surface.translateWorldToLocal; - LightmapUvs[surface.startUvIndex + i].X = (tDelta | surface.projLocalToU); - LightmapUvs[surface.startUvIndex + i].Y = (tDelta | surface.projLocalToV); + MeshVertices[surface.startVertIndex + i].lu = (tDelta | surface.projLocalToU); + MeshVertices[surface.startVertIndex + i].lv = (tDelta | surface.projLocalToV); } // project tCoords so they lie on the plane diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index 6e70e1eaa..254e64dba 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -33,7 +33,7 @@ struct DoomLevelMeshSurface : public LevelMeshSurface side_t* Side = nullptr; sector_t* ControlSector = nullptr; - float* TexCoords = nullptr; + FFlatVertex* Vertices = nullptr; }; class DoomLevelSubmesh : public LevelSubmesh @@ -56,7 +56,6 @@ public: void DisableLightmaps() { Surfaces.Clear(); } // Temp hack that disables lightmapping TArray Surfaces; - TArray LightmapUvs; TArray sectorGroup; // index is sector, value is sectorGroup TArray> PolyLMSurfaces; @@ -122,8 +121,6 @@ private: static PlaneAxis BestAxis(const FVector4& p); BBox GetBoundsFromSurface(const LevelMeshSurface& surface) const; - inline int AllocUvs(int amount) { return LightmapUvs.Reserve(amount); } - void BuildSurfaceParams(int lightMapTextureWidth, int lightMapTextureHeight, LevelMeshSurface& surface); static bool IsDegenerate(const FVector3& v0, const FVector3& v1, const FVector3& v2); diff --git a/src/rendering/hwrenderer/hw_vertexbuilder.cpp b/src/rendering/hwrenderer/hw_vertexbuilder.cpp index 03f60219c..a31d2c76d 100644 --- a/src/rendering/hwrenderer/hw_vertexbuilder.cpp +++ b/src/rendering/hwrenderer/hw_vertexbuilder.cpp @@ -195,7 +195,7 @@ static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plan ffv.lindex = -1.0f; } -static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plane, float llu, float llv, int llindex) +static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plane, float llu, float llv, float llindex) { ffv.x = (float)vt->fX(); ffv.y = (float)vt->fY(); @@ -204,7 +204,7 @@ static void SetFlatVertex(FFlatVertex& ffv, vertex_t* vt, const secplane_t& plan ffv.v = -(float)vt->fY() / 64.f; ffv.lu = llu; ffv.lv = llv; - ffv.lindex = (float)llindex; + ffv.lindex = llindex; } //========================================================================== @@ -246,11 +246,10 @@ static int CreateIndexedSectorVerticesLM(FRenderState& renderstate, sector_t* se DoomLevelMeshSurface* lightmap = sub->lightmap[h].Size() > lightmapIndex ? sub->lightmap[h][lightmapIndex] : nullptr; if (lightmap && lightmap->Type != ST_UNKNOWN) // lightmap may be missing if the subsector is degenerate triangle { - float* luvs = lightmap->TexCoords; - int lindex = lightmap->AtlasTile.ArrayIndex; + FFlatVertex* luvs = lightmap->Vertices; for (unsigned int j = 0; j < sub->numlines; j++) { - SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane, luvs[j * 2], luvs[j * 2 + 1], lindex); + SetFlatVertex(vbo_shadowdata[vi + pos], sub->firstline[j].v1, plane, luvs[j].lu, luvs[j].lv, luvs[j].lindex); vbo_shadowdata[vi + pos].z += diff; pos++; } diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index b6896577e..f36ecc8e3 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -917,15 +917,21 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto texlength = 0; } - texcoord* srclightuv; + texcoord srclightuv[4]; if (lightmap && lightmap->Type != ST_UNKNOWN) { - srclightuv = (texcoord*)lightmap->TexCoords; - lindex = (float)lightmap->AtlasTile.ArrayIndex; + srclightuv[0] = { lightmap->Vertices[0].lu, lightmap->Vertices[0].lv }; + srclightuv[1] = { lightmap->Vertices[1].lu, lightmap->Vertices[1].lv }; + srclightuv[2] = { lightmap->Vertices[2].lu, lightmap->Vertices[2].lv }; + srclightuv[3] = { lightmap->Vertices[3].lu, lightmap->Vertices[3].lv }; + lindex = lightmap->Vertices[0].lindex; } else { - srclightuv = (texcoord*)ZeroLightmapUVs; + srclightuv[0] = { 0.0f, 0.0f }; + srclightuv[1] = { 0.0f, 0.0f }; + srclightuv[2] = { 0.0f, 0.0f }; + srclightuv[3] = { 0.0f, 0.0f }; lindex = -1.0f; } @@ -1639,15 +1645,21 @@ void HWWall::BuildFFBlock(HWWallDispatcher *di, FRenderState& state, seg_t * seg type = RENDERWALL_FFBLOCK; CheckTexturePosition(&tci); - texcoord* srclightuv; + texcoord srclightuv[4]; if (lightmap && lightmap->Type != ST_UNKNOWN) { - srclightuv = (texcoord*)lightmap->TexCoords; - lindex = (float)lightmap->AtlasTile.ArrayIndex; + srclightuv[0] = { lightmap->Vertices[0].lu, lightmap->Vertices[0].lv }; + srclightuv[1] = { lightmap->Vertices[1].lu, lightmap->Vertices[1].lv }; + srclightuv[2] = { lightmap->Vertices[2].lu, lightmap->Vertices[2].lv }; + srclightuv[3] = { lightmap->Vertices[3].lu, lightmap->Vertices[3].lv }; + lindex = lightmap->Vertices[0].lindex; } else { - srclightuv = (texcoord*)ZeroLightmapUVs; + srclightuv[0] = { 0.0f, 0.0f }; + srclightuv[1] = { 0.0f, 0.0f }; + srclightuv[2] = { 0.0f, 0.0f }; + srclightuv[3] = { 0.0f, 0.0f }; lindex = -1.0f; } diff --git a/wadsrc/static/shaders/lightmap/binding_raytrace.glsl b/wadsrc/static/shaders/lightmap/binding_raytrace.glsl index 44effc4b4..88c9eeefe 100644 --- a/wadsrc/static/shaders/lightmap/binding_raytrace.glsl +++ b/wadsrc/static/shaders/lightmap/binding_raytrace.glsl @@ -28,11 +28,12 @@ layout(std430, set = 1, binding = 0) buffer NodeBuffer #endif -struct SurfaceVertex +struct SurfaceVertex // Note: this must always match the FFlatVertex struct { - vec4 pos; + vec3 pos; + float lindex; vec2 uv; - float Padding1, Padding2; + vec2 luv; }; layout(std430, set = 1, binding = 1) buffer VertexBuffer { SurfaceVertex vertices[]; }; diff --git a/wadsrc/static/shaders/scene/bones.glsl b/wadsrc/static/shaders/scene/bones.glsl index c9edc46bd..05e7030ea 100644 --- a/wadsrc/static/shaders/scene/bones.glsl +++ b/wadsrc/static/shaders/scene/bones.glsl @@ -26,7 +26,7 @@ void AddWeightedBone(uint boneIndex, float weight, inout vec4 position, inout ve { mat4 transform = bones[uBoneIndexBase + int(boneIndex)]; mat3 rotation = mat3(transform); - position += (transform * aPosition) * weight; + position += (transform * vec4(aPosition.xyz, 1.0)) * weight; normal += (rotation * aNormal.xyz) * weight; } } @@ -53,7 +53,7 @@ BonesResult ApplyBones() } else { - result.Position = aPosition; + result.Position = vec4(aPosition.xyz, 1.0); result.Normal = GetAttrNormal(); } return result; @@ -64,7 +64,7 @@ BonesResult ApplyBones() BonesResult ApplyBones() { BonesResult result; - result.Position = aPosition; + result.Position = vec4(aPosition.xyz, 1.0); return result; } diff --git a/wadsrc/static/shaders/scene/frag_main.glsl b/wadsrc/static/shaders/scene/frag_main.glsl index 6051a0eb2..e9f07be92 100644 --- a/wadsrc/static/shaders/scene/frag_main.glsl +++ b/wadsrc/static/shaders/scene/frag_main.glsl @@ -2,7 +2,14 @@ void main() { #ifdef USE_LEVELMESH - FragColor = vec4(vec3(pixelpos.w / 1000), 1.0); + if (vLightmap.z >= 0.0) + { + FragColor = vec4(texture(LightMap, vLightmap).rgb, 1.0); + } + else + { + FragColor = vec4(vec3(pixelpos.w / 1000), 1.0); + } #else #ifdef NO_CLIPDISTANCE_SUPPORT diff --git a/wadsrc/static/shaders/scene/layout_vert.glsl b/wadsrc/static/shaders/scene/layout_vert.glsl index d1c635795..d672669a5 100644 --- a/wadsrc/static/shaders/scene/layout_vert.glsl +++ b/wadsrc/static/shaders/scene/layout_vert.glsl @@ -11,7 +11,7 @@ layout(location = 9) out vec3 vLightmap; layout(location = 3) in vec4 aVertex2; layout(location = 4) in vec4 aNormal; layout(location = 5) in vec4 aNormal2; -layout(location = 6) in vec3 aLightmap; +layout(location = 6) in vec2 aLightmap; layout(location = 7) in vec4 aBoneWeight; layout(location = 8) in uvec4 aBoneSelector; diff --git a/wadsrc/static/shaders/scene/light_shadow.glsl b/wadsrc/static/shaders/scene/light_shadow.glsl index d6d734511..493a7bc8d 100644 --- a/wadsrc/static/shaders/scene/light_shadow.glsl +++ b/wadsrc/static/shaders/scene/light_shadow.glsl @@ -184,8 +184,8 @@ vec2 getVogelDiskSample(int sampleIndex, int sampleCount, float phi) float traceShadow(vec4 lightpos, int quality) { - vec3 origin = pixelpos.xzy; - vec3 target = lightpos.xzy + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes + vec3 origin = pixelpos.xyz; + vec3 target = lightpos.xyz + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes vec3 direction = normalize(target - origin); float dist = distance(origin, target); diff --git a/wadsrc/static/shaders/scene/vert_main.glsl b/wadsrc/static/shaders/scene/vert_main.glsl index 8f0bb0271..6d851c828 100644 --- a/wadsrc/static/shaders/scene/vert_main.glsl +++ b/wadsrc/static/shaders/scene/vert_main.glsl @@ -12,10 +12,6 @@ void main() parmTexCoord = aTexCoord; parmPosition = bones.Position; - - #ifdef USE_LEVELMESH - parmPosition.xyz = parmPosition.xzy; // The level mesh is in world coordinates - #endif #ifndef SIMPLE vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor); @@ -35,7 +31,7 @@ void main() #endif #ifndef SIMPLE - vLightmap = aLightmap; + vLightmap = vec3(aLightmap, aPosition.w); pixelpos.xyz = worldcoord.xyz; pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;