From 65b0047b263f51601a0a018de60d1db31dec2d88 Mon Sep 17 00:00:00 2001 From: Erick Vasquez Garcia Date: Fri, 19 Feb 2021 08:01:06 +0100 Subject: [PATCH] SoftPoly: Fixed the md3 models, you can now correctly display the frame of the model, in addition, interpolation is added to the model. This error is mentioned by drfrag in the following link https://forum.zdoom.org/viewtopic.php?f=336&t=71228 --- .../polyrenderer/backend/poly_buffers.cpp | 29 ++++++++++++++++--- .../polyrenderer/backend/poly_buffers.h | 2 +- .../polyrenderer/backend/poly_renderstate.cpp | 5 +++- .../polyrenderer/drawers/poly_thread.cpp | 2 +- .../polyrenderer/drawers/poly_thread.h | 6 +++- .../polyrenderer/drawers/poly_triangle.cpp | 11 ++++--- .../polyrenderer/drawers/poly_triangle.h | 4 +-- 7 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/common/rendering/polyrenderer/backend/poly_buffers.cpp b/src/common/rendering/polyrenderer/backend/poly_buffers.cpp index 599c9e088b..82c336e2ab 100644 --- a/src/common/rendering/polyrenderer/backend/poly_buffers.cpp +++ b/src/common/rendering/polyrenderer/backend/poly_buffers.cpp @@ -105,16 +105,37 @@ void PolyVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t ///////////////////////////////////////////////////////////////////////////// -void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *vertices, int index) +void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) { - const uint8_t *vertex = static_cast(vertices) + mStride * index; - const float *attrVertex = reinterpret_cast(vertex + mOffsets[VATTR_VERTEX]); + uint8_t* buff = (uint8_t*)vertices; + + // [GEC] finds the right frame. + uint32_t offsets[2] = { static_cast(frame0 * Stride), static_cast(frame1 * Stride) }; + uint8_t* vertexBuffers[2] = { buff + offsets[0], buff + offsets[1] }; + + const uint8_t* vertex = static_cast(vertexBuffers[0]) + mStride * index; + const float* attrVertex = reinterpret_cast(vertex + mOffsets[VATTR_VERTEX]); + + const uint8_t* vertex2 = static_cast(vertexBuffers[1]) + mStride * index; + const float* attrVertex2 = reinterpret_cast(vertex2 + mOffsets[VATTR_VERTEX]); + const float *attrTexcoord = reinterpret_cast(vertex + mOffsets[VATTR_TEXCOORD]); const uint8_t *attrColor = reinterpret_cast(vertex + mOffsets[VATTR_COLOR]); const uint32_t* attrNormal = reinterpret_cast(vertex + mOffsets[VATTR_NORMAL]); const uint32_t* attrNormal2 = reinterpret_cast(vertex + mOffsets[VATTR_NORMAL2]); - thread->mainVertexShader.aPosition = { attrVertex[0], attrVertex[1], attrVertex[2], 1.0f }; + // [GEC] Apply the formula for model interpolation + + float newVertex[3]; + + float t = thread->mainVertexShader.Data.uInterpolationFactor; + float invt = 1.0f - t; + + newVertex[0] = (invt * attrVertex[0]) + (t * attrVertex2[0]); + newVertex[1] = (invt * attrVertex[1]) + (t * attrVertex2[1]); + newVertex[2] = (invt * attrVertex[2]) + (t * attrVertex2[2]); + + thread->mainVertexShader.aPosition = { newVertex[0], newVertex[1], newVertex[2], 1.0f }; thread->mainVertexShader.aTexCoord = { attrTexcoord[0], attrTexcoord[1] }; if ((UseVertexData & 1) == 0) diff --git a/src/common/rendering/polyrenderer/backend/poly_buffers.h b/src/common/rendering/polyrenderer/backend/poly_buffers.h index 9d7ff2c667..2f3d2cc747 100644 --- a/src/common/rendering/polyrenderer/backend/poly_buffers.h +++ b/src/common/rendering/polyrenderer/backend/poly_buffers.h @@ -48,7 +48,7 @@ public: std::vector Attrs; int UseVertexData; - void Load(PolyTriangleThreadData *thread, const void *vertices, int index) override; + void Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) override; }; class PolyVertexBuffer : public IVertexBuffer, public PolyBuffer diff --git a/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp index 89577c44e3..9a1d9d12a4 100644 --- a/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/common/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -258,7 +258,10 @@ void PolyRenderState::Apply() ApplyMaterial(); - if (mVertexBuffer) mDrawCommands->SetVertexBuffer(mVertexBuffer->Memory()); + if (mVertexBuffer) + { + mDrawCommands->SetVertexBuffer(mVertexBuffer->Memory(), mVertexOffsets[0], mVertexOffsets[1]); // [GEC] Add offset params + } if (mIndexBuffer) mDrawCommands->SetIndexBuffer(mIndexBuffer->Memory()); mDrawCommands->SetInputAssembly(static_cast(mVertexBuffer)->VertexFormat); mDrawCommands->SetRenderStyle(mRenderStyle); diff --git a/src/common/rendering/polyrenderer/drawers/poly_thread.cpp b/src/common/rendering/polyrenderer/drawers/poly_thread.cpp index 96dfc0ce2d..67cc1e688d 100644 --- a/src/common/rendering/polyrenderer/drawers/poly_thread.cpp +++ b/src/common/rendering/polyrenderer/drawers/poly_thread.cpp @@ -388,7 +388,7 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode) ShadedTriVertex PolyTriangleThreadData::ShadeVertex(int index) { - inputAssembly->Load(this, vertices, index); + inputAssembly->Load(this, vertices, frame0, frame1, index); mainVertexShader.SIMPLE = (SpecialEffect == EFF_BURN) || (SpecialEffect == EFF_STENCIL); mainVertexShader.SPHEREMAP = (SpecialEffect == EFF_SPHEREMAP); mainVertexShader.main(); diff --git a/src/common/rendering/polyrenderer/drawers/poly_thread.h b/src/common/rendering/polyrenderer/drawers/poly_thread.h index 4ce764e10f..66ea426415 100644 --- a/src/common/rendering/polyrenderer/drawers/poly_thread.h +++ b/src/common/rendering/polyrenderer/drawers/poly_thread.h @@ -44,7 +44,7 @@ public: void SetTwoSided(bool value) { twosided = value; } void SetInputAssembly(PolyInputAssembly *input) { inputAssembly = input; } - void SetVertexBuffer(const void *data) { vertices = data; } + void SetVertexBuffer(const void *data, int offset0, int offset1) { vertices = data; frame0 = offset0; frame1 = offset1;} //[GEC] Save frame params void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; } void SetLightBuffer(const void *data) { lights = (const FVector4 *)data; } void SetViewpointUniforms(const HWViewpointUniforms *uniforms); @@ -145,6 +145,10 @@ public: uint32_t AlphaThreshold = 0x7f000000; const PolyPushConstants* PushConstants = nullptr; + // [GEC] Add frame params, necessary to project frames and model interpolation correctly + int frame0 = 0; + int frame1 = 0; + const void *vertices = nullptr; const unsigned int *elements = nullptr; const FVector4 *lights = nullptr; diff --git a/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp index 3e5b176181..986ac946a2 100644 --- a/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/common/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -186,11 +186,14 @@ private: class PolySetVertexBufferCommand : public PolyDrawerCommand { public: - PolySetVertexBufferCommand(const void* vertices) : vertices(vertices) { } - void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetVertexBuffer(vertices); } + PolySetVertexBufferCommand(const void* vertices, int offset0, int offset1) : vertices(vertices), offset0(offset0), offset1(offset1){ } + void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetVertexBuffer(vertices, offset0, offset1); } private: const void* vertices; + // [GEC] Add offset params, necessary to project frames and model interpolation correctly + int offset0; + int offset1; }; class PolySetIndexBufferCommand : public PolyDrawerCommand @@ -345,9 +348,9 @@ void PolyCommandBuffer::SetInputAssembly(PolyInputAssembly *input) mQueue->Push(input); } -void PolyCommandBuffer::SetVertexBuffer(const void *vertices) +void PolyCommandBuffer::SetVertexBuffer(const void *vertices, int offset0, int offset1) { - mQueue->Push(vertices); + mQueue->Push(vertices, offset0, offset1); } void PolyCommandBuffer::SetIndexBuffer(const void *elements) diff --git a/src/common/rendering/polyrenderer/drawers/poly_triangle.h b/src/common/rendering/polyrenderer/drawers/poly_triangle.h index a0340a3b8d..d29b10ba34 100644 --- a/src/common/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/common/rendering/polyrenderer/drawers/poly_triangle.h @@ -50,7 +50,7 @@ public: void SetViewport(int x, int y, int width, int height, DCanvas *canvas, PolyDepthStencil *depthStencil, bool topdown); void SetInputAssembly(PolyInputAssembly *input); - void SetVertexBuffer(const void *vertices); + void SetVertexBuffer(const void *vertices, int offset0, int offset1); // [GEC] Add offset params void SetIndexBuffer(const void *elements); void SetLightBuffer(const void *lights); void SetViewpointUniforms(const HWViewpointUniforms *uniforms); @@ -117,5 +117,5 @@ struct PolyPushConstants class PolyInputAssembly { public: - virtual void Load(PolyTriangleThreadData *thread, const void *vertices, int index) = 0; + virtual void Load(PolyTriangleThreadData *thread, const void *vertices, int frame0, int frame1, int index) = 0; // [GEC] Add frame params };