Merges ModelRenderer and ShaderModelRenderer

We use only shaders to render models so we don't need a separate class.

BatchModelRenderer was renamed in 6bc33fe8bd.
m_Renderer became unused in 0346ba1b18.
This commit is contained in:
Vladislav Belov 2026-08-04 23:06:07 +02:00
parent 8a2bb10827
commit 764a420797
No known key found for this signature in database
GPG key ID: 353545E45DB9CCB3
4 changed files with 67 additions and 145 deletions

View file

@ -102,15 +102,11 @@ CMaterial::Pass GetMaterialPassFromCullGroup(const int cullGroup, const ERenderM
}
void ModelRenderer::Init()
{
}
// Helper function to copy object-space position and normal vectors into arrays.
// static
void ModelRenderer::CopyPositionAndNormals(
const CModelDefPtr& mdef,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal)
const CModelDefPtr& mdef,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal)
{
size_t numVertices = mdef->GetNumVertices();
SModelVertex* vertices = mdef->GetVertices();
@ -122,11 +118,11 @@ void ModelRenderer::CopyPositionAndNormals(
}
}
// Helper function to transform position and normal vectors into world-space.
// static
void ModelRenderer::BuildPositionAndNormals(
CModel* model,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal)
CModel* model,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal)
{
CModelDefPtr mdef = model->GetModelDef();
size_t numVertices = mdef->GetNumVertices();
@ -160,12 +156,11 @@ void ModelRenderer::BuildPositionAndNormals(
}
}
// Helper function for lighting
// static
void ModelRenderer::BuildColor4ub(
CModel* model,
const VertexArrayIterator<CVector3D>& Normal,
const VertexArrayIterator<SColor4ub>& Color)
CModel* model,
const VertexArrayIterator<CVector3D>& Normal,
const VertexArrayIterator<SColor4ub>& Color)
{
PROFILE("lighting vertices");
@ -184,19 +179,16 @@ void ModelRenderer::BuildColor4ub(
}
}
// static
void ModelRenderer::GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning)
{
MikkTSpace ms(mdef, newVertices, gpuSkinning);
ms.Generate();
}
// Copy UV coordinates
// static
void ModelRenderer::BuildUV(
const CModelDefPtr& mdef,
const VertexArrayIterator<float[2]>& UV,
int UVset)
const CModelDefPtr& mdef, const VertexArrayIterator<float[2]>& UV, int UVset)
{
const size_t numVertices = mdef->GetNumVertices();
const size_t numberOfUVPerVertex = mdef->GetNumUVsPerVertex();
@ -209,11 +201,9 @@ void ModelRenderer::BuildUV(
}
}
// Build default indices array.
// static
void ModelRenderer::BuildIndices(
const CModelDefPtr& mdef,
const VertexArrayIterator<u16>& Indices)
const CModelDefPtr& mdef, const VertexArrayIterator<u16>& Indices)
{
size_t idxidx = 0;
SModelFace* faces = mdef->GetFaces();
@ -227,25 +217,14 @@ void ModelRenderer::BuildIndices(
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
// ShaderModelRenderer implementation
/**
* Internal data of the ShaderModelRenderer.
* Internal data of the ModelRenderer.
*
* Separated into the source file to increase implementation hiding (and to
* avoid some causes of recompiles).
*/
struct ShaderModelRenderer::ShaderModelRendererInternals
struct ModelRenderer::ModelRendererInternals
{
ShaderModelRendererInternals(ShaderModelRenderer* r) : m_Renderer(r) { }
/// Back-link to "our" renderer
ShaderModelRenderer* m_Renderer;
/// ModelVertexRenderer used for vertex transformations
ModelVertexRendererPtr vertexRenderer;
@ -253,21 +232,16 @@ struct ShaderModelRenderer::ShaderModelRendererInternals
std::vector<CModel*> submissions[CSceneRenderer::CULL_MAX];
};
// Construction/Destruction
ShaderModelRenderer::ShaderModelRenderer(ModelVertexRendererPtr vertexrenderer)
ModelRenderer::ModelRenderer(ModelVertexRendererPtr vertexrenderer)
{
m = new ShaderModelRendererInternals(this);
m = std::unique_ptr<ModelRendererInternals>(new ModelRendererInternals());
m->vertexRenderer = vertexrenderer;
}
ShaderModelRenderer::~ShaderModelRenderer()
{
delete m;
}
ModelRenderer::~ModelRenderer() = default;
// Submit one model.
void ShaderModelRenderer::Submit(int cullGroup, CModel* model)
void ModelRenderer::Submit(int cullGroup, CModel* model)
{
CModelRData* rdata = (CModelRData*)model->GetRenderData();
@ -286,7 +260,7 @@ void ShaderModelRenderer::Submit(int cullGroup, CModel* model)
// Call update for all submitted models and enter the rendering phase
void ShaderModelRenderer::PrepareModels(
void ModelRenderer::PrepareModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
{
for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
@ -309,7 +283,7 @@ void ShaderModelRenderer::PrepareModels(
}
}
void ShaderModelRenderer::UploadModels(
void ModelRenderer::UploadModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext)
{
for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
@ -319,7 +293,7 @@ void ShaderModelRenderer::UploadModels(
}
// Clear the submissions list
void ShaderModelRenderer::EndFrame()
void ModelRenderer::EndFrame()
{
for (int cullGroup = 0; cullGroup < CSceneRenderer::CULL_MAX; ++cullGroup)
m->submissions[cullGroup].clear();
@ -413,7 +387,7 @@ struct SMRCompareTechBucket
}
};
void ShaderModelRenderer::Render(
void ModelRenderer::Render(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
const RenderModifierPtr& modifier, const CShaderDefines& context,
int cullGroup, int flags, const ERenderMode renderMode)

View file

@ -80,25 +80,12 @@ private:
/**
* Class ModelRenderer: Abstract base class for all model renders.
* ModelRenderer manages a per-frame list of models. It loads the appropriate
* shaders for rendering each model, and that batches by shader technique (and
* by mesh and texture).
*
* A ModelRenderer manages a per-frame list of models.
*
* It is supposed to be derived in order to create new ways in which
* the per-frame list of models can be managed (for batching, for
* transparent rendering, etc.) or potentially for rarely used special
* effects.
*
* A typical ModelRenderer will delegate vertex transformation/setup
* to a ModelVertexRenderer.
* It will delegate fragment stage setup to a RenderModifier.
*
* For most purposes, you should use a BatchModelRenderer with
* specialized ModelVertexRenderer and RenderModifier implementations.
*
* It is suggested that a derived class implement the provided generic
* Render function, however in some cases it may be necessary to supply
* a Render function with a different prototype.
* ModelRenderer delegates vertex transformation/setup to a
* ModelVertexRenderer. It delegates fragment stage setup to a RenderModifier.
*
* ModelRenderer also contains a number of static helper functions
* for building vertex arrays.
@ -106,14 +93,8 @@ private:
class ModelRenderer
{
public:
ModelRenderer() { }
virtual ~ModelRenderer() { }
/**
* Initialise global settings.
* Should be called before using the class.
*/
static void Init();
ModelRenderer(ModelVertexRendererPtr vertexrenderer);
~ModelRenderer();
/**
* Submit: Submit a model for rendering this frame.
@ -125,7 +106,7 @@ public:
* @param model The model that will be added to the list of models
* submitted this frame.
*/
virtual void Submit(int cullGroup, CModel* model) = 0;
void Submit(int cullGroup, CModel* model);
/**
* PrepareModels: Calculate renderer data for all previously
@ -134,8 +115,8 @@ public:
* Must be called before any rendering calls and after all models
* for this frame have been submitted.
*/
virtual void PrepareModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext) = 0;
void PrepareModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
/**
* Upload renderer data for all previously submitted models to backend.
@ -143,24 +124,19 @@ public:
* Must be called before any rendering calls and after all models
* for this frame have been prepared.
*/
virtual void UploadModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext) = 0;
void UploadModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
/**
* EndFrame: Remove all models from the list of submitted
* models.
*/
virtual void EndFrame() = 0;
void EndFrame();
/**
* Render: Render submitted models, using the given RenderModifier to setup
* the fragment stage.
*
* @note It is suggested that derived model renderers implement and use
* this Render functions. However, a highly specialized model renderer
* may need to "disable" this function and provide its own Render function
* with a different prototype.
*
* preconditions : PrepareModels must be called after all models have been
* submitted and before calling Render.
*
@ -169,10 +145,10 @@ public:
* If flags is non-zero, only models that contain flags in their
* CModel::GetFlags() are rendered.
*/
virtual void Render(
void Render(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
const RenderModifierPtr& modifier, const CShaderDefines& context,
int cullGroup, int flags, const ERenderMode renderMode) = 0;
int cullGroup, int flags, const ERenderMode renderMode);
/**
* CopyPositionAndNormals: Copy unanimated object-space vertices and
@ -187,9 +163,9 @@ public:
* The array behind the iterator must be as large as the Position array.
*/
static void CopyPositionAndNormals(
const CModelDefPtr& mdef,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal);
const CModelDefPtr& mdef,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal);
/**
* BuildPositionAndNormals: Build animated vertices and normals,
@ -206,9 +182,9 @@ public:
* the Position array.
*/
static void BuildPositionAndNormals(
CModel* model,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal);
CModel* model,
const VertexArrayIterator<CVector3D>& Position,
const VertexArrayIterator<CVector3D>& Normal);
/**
* BuildColor4ub: Build lighting colors for the given model,
@ -222,9 +198,9 @@ public:
* model->GetModelDef()->GetNumVertices() vertices.
*/
static void BuildColor4ub(
CModel* model,
const VertexArrayIterator<CVector3D>& Normal,
const VertexArrayIterator<SColor4ub>& Color);
CModel* model,
const VertexArrayIterator<CVector3D>& Normal,
const VertexArrayIterator<SColor4ub>& Color);
/**
* BuildUV: Copy UV coordinates into the given vertex array.
@ -235,9 +211,9 @@ public:
* mdef->GetNumVertices() vertices.
*/
static void BuildUV(
const CModelDefPtr& mdef,
const VertexArrayIterator<float[2]>& UV,
int UVset);
const CModelDefPtr& mdef,
const VertexArrayIterator<float[2]>& UV,
int UVset);
/**
* BuildIndices: Create the indices array for the given CModelDef.
@ -247,8 +223,7 @@ public:
* mdef->GetNumFaces()*3 elements.
*/
static void BuildIndices(
const CModelDefPtr& mdef,
const VertexArrayIterator<u16>& Indices);
const CModelDefPtr& mdef, const VertexArrayIterator<u16>& Indices);
/**
* GenTangents: Generate tangents for the given CModelDef.
@ -258,35 +233,10 @@ public:
* The new vertices cannot be used with existing face index and must be welded/reindexed.
*/
static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
};
/**
* Implementation of ModelRenderer that loads the appropriate shaders for
* rendering each model, and that batches by shader technique (and by mesh and texture).
*/
class ShaderModelRenderer : public ModelRenderer
{
friend struct ShaderModelRendererInternals;
public:
ShaderModelRenderer(ModelVertexRendererPtr vertexrender);
~ShaderModelRenderer() override;
// Batching implementations
void Submit(int cullGroup, CModel* model) override;
void PrepareModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override;
void UploadModels(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override;
void EndFrame() override;
void Render(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
const RenderModifierPtr& modifier, const CShaderDefines& context,
int cullGroup, int flags, const ERenderMode renderMode) override;
private:
struct ShaderModelRendererInternals;
ShaderModelRendererInternals* m;
struct ModelRendererInternals;
std::unique_ptr<ModelRendererInternals> m;
};
#endif // INCLUDED_MODELRENDERER

View file

@ -62,7 +62,6 @@
#include "ps/VideoMode.h"
#include "ps/World.h"
#include "renderer/DebugRenderer.h"
#include "renderer/ModelRenderer.h"
#include "renderer/PostprocManager.h"
#include "renderer/RenderingOptions.h"
#include "renderer/SceneRenderer.h"
@ -456,7 +455,6 @@ CRenderer::CRenderer(Renderer::Backend::IDevice* device)
ModelDefActivateFastImpl();
ColorActivateFastImpl();
ModelRenderer::Init();
}
CRenderer::~CRenderer()

View file

@ -135,10 +135,10 @@ public:
// model instance (except for skinned models), so non-skinned models
// get different ModelVertexRenderers
std::unique_ptr<ShaderModelRenderer> OpaqueSkinned;
std::unique_ptr<ShaderModelRenderer> OpaqueUnskinned;
std::unique_ptr<ShaderModelRenderer> TransparentSkinned;
std::unique_ptr<ShaderModelRenderer> TransparentUnskinned;
std::unique_ptr<ModelRenderer> OpaqueSkinned;
std::unique_ptr<ModelRenderer> OpaqueUnskinned;
std::unique_ptr<ModelRenderer> TransparentSkinned;
std::unique_ptr<ModelRenderer> TransparentUnskinned;
ModelVertexRendererPtr VertexRendererShader;
ModelVertexRendererPtr VertexInstancingShader;
@ -241,18 +241,18 @@ void CSceneRenderer::ReloadShaders([[maybe_unused]] Renderer::Backend::IDevice*
if (g_RenderingOptions.GetGPUSkinning())
{
m->Model.VertexGPUSkinningShader = ModelVertexRendererPtr(new GPUSkinnedModelModelRenderer());
m->Model.OpaqueSkinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexGPUSkinningShader);
m->Model.TransparentSkinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexGPUSkinningShader);
m->Model.OpaqueSkinned = std::make_unique<ModelRenderer>(m->Model.VertexGPUSkinningShader);
m->Model.TransparentSkinned = std::make_unique<ModelRenderer>(m->Model.VertexGPUSkinningShader);
}
else
{
m->Model.VertexGPUSkinningShader.reset();
m->Model.OpaqueSkinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexRendererShader);
m->Model.TransparentSkinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexRendererShader);
m->Model.OpaqueSkinned = std::make_unique<ModelRenderer>(m->Model.VertexRendererShader);
m->Model.TransparentSkinned = std::make_unique<ModelRenderer>(m->Model.VertexRendererShader);
}
m->Model.OpaqueUnskinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexInstancingShader);
m->Model.TransparentUnskinned = std::make_unique<ShaderModelRenderer>(m->Model.VertexInstancingShader);
m->Model.OpaqueUnskinned = std::make_unique<ModelRenderer>(m->Model.VertexInstancingShader);
m->Model.TransparentUnskinned = std::make_unique<ModelRenderer>(m->Model.VertexInstancingShader);
}
void CSceneRenderer::Initialize()