- cleaned up the dependencies in the model rendering code and separated it into game-independent and game-dependent parts.

This commit is contained in:
Christoph Oelckers 2020-04-26 13:19:57 +02:00
parent 69d724ae73
commit 5611fe0f41
12 changed files with 197 additions and 148 deletions

View file

@ -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

View file

@ -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<FModelVertex*>(mVertexBuffer->Lock(size * sizeof(FModelVertex)));
}
//===========================================================================
//
//
//
//===========================================================================
void FModelVertexBuffer::UnlockVertexBuffer()
{
mVertexBuffer->Unlock();
}
//===========================================================================
//
//
//
//===========================================================================
unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
{
if (mIndexBuffer) return static_cast<unsigned int*>(mIndexBuffer->Lock(size * sizeof(unsigned int)));
else return nullptr;
}
//===========================================================================
//
//
//
//===========================================================================
void FModelVertexBuffer::UnlockIndexBuffer()
{
if (mIndexBuffer) mIndexBuffer->Unlock();
}

View file

@ -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; }
};

View file

@ -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;
};

View file

@ -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:

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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<FModelVertexBuffer*>(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<FModelVertex*>(mVertexBuffer->Lock(size * sizeof(FModelVertex)));
}
//===========================================================================
//
//
//
//===========================================================================
void FModelVertexBuffer::UnlockVertexBuffer()
{
mVertexBuffer->Unlock();
}
//===========================================================================
//
//
//
//===========================================================================
unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
{
if (mIndexBuffer) return static_cast<unsigned int*>(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<FHWModelRenderer*>(renderer)->state;
state.SetVertexBuffer(mVertexBuffer, frame1, frame2);
if (mIndexBuffer) state.SetIndexBuffer(mIndexBuffer);
}

View file

@ -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;
};