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 599c9e088..82c336e2a 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 9d7ff2c66..2f3d2cc74 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 89577c44e..9a1d9d12a 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 96dfc0ce2..67cc1e688 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 4ce764e10..66ea42641 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 3e5b17618..986ac946a 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 a0340a3b8..d29b10ba3 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 };