diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc82019069..9e281cbda5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1142,6 +1142,7 @@ set (PCH_SOURCES common/rendering/r_videoscale.cpp common/rendering/hwrenderer/data/flatvertices.cpp common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp + common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp common/rendering/hwrenderer/data/hw_cvars.cpp common/rendering/hwrenderer/data/hw_vrmodes.cpp common/rendering/hwrenderer/data/hw_lightbuffer.cpp diff --git a/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp new file mode 100644 index 0000000000..e4d5ba030b --- /dev/null +++ b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.cpp @@ -0,0 +1,112 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2005-2020 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_models.cpp +** +** hardware renderer model handling code +** +**/ + + +#include "v_video.h" +#include "cmdlib.h" +#include "hw_modelvertexbuffer.h" + +//=========================================================================== +// +// +// +//=========================================================================== + +FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) +{ + mVertexBuffer = screen->CreateVertexBuffer(); + mIndexBuffer = needindex ? screen->CreateIndexBuffer() : nullptr; + + static const FVertexBufferAttribute format[] = { + { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, + { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FModelVertex, u) }, + { 0, VATTR_NORMAL, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) }, + { 1, VATTR_VERTEX2, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, + { 1, VATTR_NORMAL2, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) } + }; + mVertexBuffer->SetFormat(2, 5, sizeof(FModelVertex), format); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +FModelVertexBuffer::~FModelVertexBuffer() +{ + if (mIndexBuffer) delete mIndexBuffer; + delete mVertexBuffer; +} + +//=========================================================================== +// +// +// +//=========================================================================== + +FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) +{ + return static_cast(mVertexBuffer->Lock(size * sizeof(FModelVertex))); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FModelVertexBuffer::UnlockVertexBuffer() +{ + mVertexBuffer->Unlock(); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) +{ + if (mIndexBuffer) return static_cast(mIndexBuffer->Lock(size * sizeof(unsigned int))); + else return nullptr; +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void FModelVertexBuffer::UnlockIndexBuffer() +{ + if (mIndexBuffer) mIndexBuffer->Unlock(); +} + + diff --git a/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.h b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.h new file mode 100644 index 0000000000..4907637d46 --- /dev/null +++ b/src/common/rendering/hwrenderer/data/hw_modelvertexbuffer.h @@ -0,0 +1,26 @@ +#pragma once + +#include "hwrenderer/data/buffers.h" +#include "i_modelvertexbuffer.h" + +class FModelRenderer; + +class FModelVertexBuffer : public IModelVertexBuffer +{ + IVertexBuffer *mVertexBuffer; + IIndexBuffer *mIndexBuffer; + +public: + + FModelVertexBuffer(bool needindex, bool singleframe); + ~FModelVertexBuffer(); + + FModelVertex *LockVertexBuffer(unsigned int size) override; + void UnlockVertexBuffer() override; + + unsigned int *LockIndexBuffer(unsigned int size) override; + void UnlockIndexBuffer() override; + + IVertexBuffer* vertexBuffer() const { return mVertexBuffer; } + IIndexBuffer* indexBuffer() const { return mIndexBuffer; } +}; diff --git a/src/common/rendering/i_modelvertexbuffer.h b/src/common/rendering/i_modelvertexbuffer.h new file mode 100644 index 0000000000..febec3c71b --- /dev/null +++ b/src/common/rendering/i_modelvertexbuffer.h @@ -0,0 +1,43 @@ +#pragma once + +#include "templates.h" + +struct FModelVertex +{ + float x, y, z; // world position + float u, v; // texture coordinates + unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. + + void Set(float xx, float yy, float zz, float uu, float vv) + { + x = xx; + y = yy; + z = zz; + u = uu; + v = vv; + } + + void SetNormal(float nx, float ny, float nz) + { + int inx = clamp(int(nx * 512), -512, 511); + int iny = clamp(int(ny * 512), -512, 511); + int inz = clamp(int(nz * 512), -512, 511); + int inw = 0; + packedNormal = (inw << 30) | ((inz & 1023) << 20) | ((iny & 1023) << 10) | (inx & 1023); + } +}; + +#define VMO ((FModelVertex*)nullptr) + +class IModelVertexBuffer +{ +public: + virtual ~IModelVertexBuffer() { } + + virtual FModelVertex *LockVertexBuffer(unsigned int size) = 0; + virtual void UnlockVertexBuffer() = 0; + + virtual unsigned int *LockIndexBuffer(unsigned int size) = 0; + virtual void UnlockIndexBuffer() = 0; +}; + diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index e6c30323fb..33e9056deb 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -31,6 +31,7 @@ #include "r_data/voxels.h" #include "info.h" #include "g_levellocals.h" +#include "i_modelvertexbuffer.h" #define MAX_LODS 4 @@ -47,6 +48,7 @@ FTextureID LoadSkin(const char * path, const char * fn); struct FSpriteModelFrame; class IModelVertexBuffer; struct FLevelLocals; +class FModel; enum ModelRendererType { @@ -80,54 +82,12 @@ public: virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) = 0; virtual void DrawArrays(int start, int count) = 0; virtual void DrawElements(int numIndices, size_t offset) = 0; + virtual void SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size) = 0; private: void RenderFrameModels(FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation); }; -struct FModelVertex -{ - float x, y, z; // world position - float u, v; // texture coordinates - unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. - - void Set(float xx, float yy, float zz, float uu, float vv) - { - x = xx; - y = yy; - z = zz; - u = uu; - v = vv; - } - - void SetNormal(float nx, float ny, float nz) - { - int inx = clamp(int(nx * 512), -512, 511); - int iny = clamp(int(ny * 512), -512, 511); - int inz = clamp(int(nz * 512), -512, 511); - int inw = 0; - packedNormal = (inw << 30) | ((inz & 1023) << 20) | ((iny & 1023) << 10) | (inx & 1023); - } -}; - -#define VMO ((FModelVertex*)NULL) - -class FModelRenderer; - -class IModelVertexBuffer -{ -public: - virtual ~IModelVertexBuffer() { } - - virtual FModelVertex *LockVertexBuffer(unsigned int size) = 0; - virtual void UnlockVertexBuffer() = 0; - - virtual unsigned int *LockIndexBuffer(unsigned int size) = 0; - virtual void UnlockIndexBuffer() = 0; - - virtual void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) = 0; -}; - class FModel { public: diff --git a/src/r_data/models/models_md2.cpp b/src/r_data/models/models_md2.cpp index 31387f000a..f4142ea631 100644 --- a/src/r_data/models/models_md2.cpp +++ b/src/r_data/models/models_md2.cpp @@ -371,7 +371,7 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f renderer->SetInterpolation(inter); renderer->SetMaterial(skin, false, translation); - GetVertexBuffer(renderer)->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3); + renderer->SetupFrame(this, 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 b37b3df36f..42e2fd4963 100644 --- a/src/r_data/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -372,7 +372,7 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f } renderer->SetMaterial(surfaceSkin, false, translation); - GetVertexBuffer(renderer)->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices); + renderer->SetupFrame(this, 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_obj.cpp b/src/r_data/models/models_obj.cpp index 67c1106357..7028ca22b7 100644 --- a/src/r_data/models/models_obj.cpp +++ b/src/r_data/models/models_obj.cpp @@ -652,7 +652,7 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f } renderer->SetMaterial(userSkin, false, translation); - GetVertexBuffer(renderer)->SetupFrame(renderer, surf->vbStart, surf->vbStart, surf->numTris * 3); + renderer->SetupFrame(this, surf->vbStart, surf->vbStart, surf->numTris * 3); renderer->DrawArrays(0, surf->numTris * 3); } } diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index 7d53798916..8ee05b9db9 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -246,7 +246,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int f // TODO: Handle per-group render styles and other flags once functions for it are implemented // Future note: poly renderstyles should always be enforced unless the actor itself has a style other than Normal renderer->SetMaterial(sskin,false,translation); - GetVertexBuffer(renderer)->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize); + renderer->SetupFrame(this, vofs+frame*fsize,vofs+frame2*fsize,vsize); renderer->DrawArrays(0,vsize); vofs += vsize; } diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index cfa65f4b3a..5eedc08660 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -398,7 +398,7 @@ float FVoxelModel::getAspectFactor(FLevelLocals *Level) void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation) { renderer->SetMaterial(skin, true, translation); - GetVertexBuffer(renderer)->SetupFrame(renderer, 0, 0, 0); + renderer->SetupFrame(this, 0, 0, 0); renderer->DrawElements(mNumIndices, 0); } diff --git a/src/rendering/hwrenderer/models/hw_models.cpp b/src/rendering/hwrenderer/models/hw_models.cpp index 8bf1ce55e0..20d2386d58 100644 --- a/src/rendering/hwrenderer/models/hw_models.cpp +++ b/src/rendering/hwrenderer/models/hw_models.cpp @@ -134,88 +134,10 @@ void FHWModelRenderer::DrawElements(int numIndices, size_t offset) // //=========================================================================== -FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) +void FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size) { - mVertexBuffer = screen->CreateVertexBuffer(); - mIndexBuffer = needindex ? screen->CreateIndexBuffer() : nullptr; - - static const FVertexBufferAttribute format[] = { - { 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, - { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FModelVertex, u) }, - { 0, VATTR_NORMAL, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) }, - { 1, VATTR_VERTEX2, VFmt_Float3, (int)myoffsetof(FModelVertex, x) }, - { 1, VATTR_NORMAL2, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) } - }; - mVertexBuffer->SetFormat(2, 5, sizeof(FModelVertex), format); + auto mdbuff = static_cast(model->GetVertexBuffer(this)); + state.SetVertexBuffer(mdbuff->vertexBuffer(), frame1, frame2); + if (mdbuff->indexBuffer()) state.SetIndexBuffer(mdbuff->indexBuffer()); } -//=========================================================================== -// -// -// -//=========================================================================== - -FModelVertexBuffer::~FModelVertexBuffer() -{ - if (mIndexBuffer) delete mIndexBuffer; - delete mVertexBuffer; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) -{ - return static_cast(mVertexBuffer->Lock(size * sizeof(FModelVertex))); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FModelVertexBuffer::UnlockVertexBuffer() -{ - mVertexBuffer->Unlock(); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) -{ - if (mIndexBuffer) return static_cast(mIndexBuffer->Lock(size * sizeof(unsigned int))); - else return nullptr; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FModelVertexBuffer::UnlockIndexBuffer() -{ - if (mIndexBuffer) mIndexBuffer->Unlock(); -} - - -//=========================================================================== -// -// -// -//=========================================================================== - -void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) -{ - auto &state = static_cast(renderer)->state; - state.SetVertexBuffer(mVertexBuffer, frame1, frame2); - if (mIndexBuffer) state.SetIndexBuffer(mIndexBuffer); -} diff --git a/src/rendering/hwrenderer/models/hw_models.h b/src/rendering/hwrenderer/models/hw_models.h index efe1e18698..5644ab09df 100644 --- a/src/rendering/hwrenderer/models/hw_models.h +++ b/src/rendering/hwrenderer/models/hw_models.h @@ -27,29 +27,12 @@ #include "r_data/voxels.h" #include "r_data/models/models.h" #include "hwrenderer/data/buffers.h" +#include "hw_modelvertexbuffer.h" class HWSprite; struct HWDrawInfo; class FRenderState; -class FModelVertexBuffer : public IModelVertexBuffer -{ - IVertexBuffer *mVertexBuffer; - IIndexBuffer *mIndexBuffer; - -public: - - FModelVertexBuffer(bool needindex, bool singleframe); - ~FModelVertexBuffer(); - - FModelVertex *LockVertexBuffer(unsigned int size) override; - void UnlockVertexBuffer() override; - - unsigned int *LockIndexBuffer(unsigned int size) override; - void UnlockIndexBuffer() override; - - void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) override; -}; class FHWModelRenderer : public FModelRenderer { @@ -71,5 +54,7 @@ public: void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override; void DrawArrays(int start, int count) override; void DrawElements(int numIndices, size_t offset) override; + void SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size) override; + };