LCOV - code coverage report
Current view: top level - source/renderer - ModelRenderer.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 5 0.0 %
Date: 2023-01-19 00:18:29 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : /*
      19             :  * Home to the ModelRenderer class, an abstract base class that manages
      20             :  * a per-frame list of submitted models, as well as simple helper
      21             :  * classes.
      22             :  */
      23             : 
      24             : #ifndef INCLUDED_MODELRENDERER
      25             : #define INCLUDED_MODELRENDERER
      26             : 
      27             : #include <memory>
      28             : 
      29             : #include "graphics/MeshManager.h"
      30             : #include "graphics/RenderableObject.h"
      31             : #include "graphics/SColor.h"
      32             : #include "renderer/backend/IDeviceCommandContext.h"
      33             : #include "renderer/VertexArray.h"
      34             : 
      35             : class RenderModifier;
      36             : typedef std::shared_ptr<RenderModifier> RenderModifierPtr;
      37             : 
      38             : class LitRenderModifier;
      39             : typedef std::shared_ptr<LitRenderModifier> LitRenderModifierPtr;
      40             : 
      41             : class ModelVertexRenderer;
      42             : typedef std::shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
      43             : 
      44             : class ModelRenderer;
      45             : typedef std::shared_ptr<ModelRenderer> ModelRendererPtr;
      46             : 
      47             : class CModel;
      48             : class CShaderDefines;
      49             : 
      50             : /**
      51             :  * Class CModelRData: Render data that is maintained per CModel.
      52             :  * ModelRenderer implementations may derive from this class to store
      53             :  * per-CModel data.
      54             :  *
      55             :  * The main purpose of this class over CRenderData is to track which
      56             :  * ModelRenderer the render data belongs to (via the key that is passed
      57             :  * to the constructor). When a model changes the renderer it uses
      58             :  * (e.g. via run-time modification of the renderpath configuration),
      59             :  * the old ModelRenderer's render data is supposed to be replaced by
      60             :  * the new data.
      61             :  */
      62           0 : class CModelRData : public CRenderData
      63             : {
      64             : public:
      65           0 :     CModelRData(const void* key) : m_Key(key) { }
      66             : 
      67             :     /**
      68             :      * GetKey: Retrieve the key that can be used to identify the
      69             :      * ModelRenderer that created this data.
      70             :      *
      71             :      * @return The opaque key that was passed to the constructor.
      72             :      */
      73           0 :     const void* GetKey() const { return m_Key; }
      74             : 
      75             : private:
      76             :     /// The key for model renderer identification
      77             :     const void* m_Key;
      78             : };
      79             : 
      80             : 
      81             : /**
      82             :  * Class ModelRenderer: Abstract base class for all model renders.
      83             :  *
      84             :  * A ModelRenderer manages a per-frame list of models.
      85             :  *
      86             :  * It is supposed to be derived in order to create new ways in which
      87             :  * the per-frame list of models can be managed (for batching, for
      88             :  * transparent rendering, etc.) or potentially for rarely used special
      89             :  * effects.
      90             :  *
      91             :  * A typical ModelRenderer will delegate vertex transformation/setup
      92             :  * to a ModelVertexRenderer.
      93             :  * It will delegate fragment stage setup to a RenderModifier.
      94             :  *
      95             :  * For most purposes, you should use a BatchModelRenderer with
      96             :  * specialized ModelVertexRenderer and RenderModifier implementations.
      97             :  *
      98             :  * It is suggested that a derived class implement the provided generic
      99             :  * Render function, however in some cases it may be necessary to supply
     100             :  * a Render function with a different prototype.
     101             :  *
     102             :  * ModelRenderer also contains a number of static helper functions
     103             :  * for building vertex arrays.
     104             :  */
     105             : class ModelRenderer
     106             : {
     107             : public:
     108           0 :     ModelRenderer() { }
     109           0 :     virtual ~ModelRenderer() { }
     110             : 
     111             :     /**
     112             :      * Initialise global settings.
     113             :      * Should be called before using the class.
     114             :      */
     115             :     static void Init();
     116             : 
     117             :     /**
     118             :      * Submit: Submit a model for rendering this frame.
     119             :      *
     120             :      * preconditions : The model must not have been submitted to any
     121             :      * ModelRenderer in this frame. Submit may only be called
     122             :      * after EndFrame and before PrepareModels.
     123             :      *
     124             :      * @param model The model that will be added to the list of models
     125             :      * submitted this frame.
     126             :      */
     127             :     virtual void Submit(int cullGroup, CModel* model) = 0;
     128             : 
     129             :     /**
     130             :      * PrepareModels: Calculate renderer data for all previously
     131             :      * submitted models.
     132             :      *
     133             :      * Must be called before any rendering calls and after all models
     134             :      * for this frame have been submitted.
     135             :      */
     136             :     virtual void PrepareModels() = 0;
     137             : 
     138             :     /**
     139             :      * Upload renderer data for all previously submitted models to backend.
     140             :      *
     141             :      * Must be called before any rendering calls and after all models
     142             :      * for this frame have been prepared.
     143             :      */
     144             :     virtual void UploadModels(
     145             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext) = 0;
     146             : 
     147             :     /**
     148             :      * EndFrame: Remove all models from the list of submitted
     149             :      * models.
     150             :      */
     151             :     virtual void EndFrame() = 0;
     152             : 
     153             :     /**
     154             :      * Render: Render submitted models, using the given RenderModifier to setup
     155             :      * the fragment stage.
     156             :      *
     157             :      * @note It is suggested that derived model renderers implement and use
     158             :      * this Render functions. However, a highly specialized model renderer
     159             :      * may need to "disable" this function and provide its own Render function
     160             :      * with a different prototype.
     161             :      *
     162             :      * preconditions  : PrepareModels must be called after all models have been
     163             :      * submitted and before calling Render.
     164             :      *
     165             :      * @param modifier The RenderModifier that specifies the fragment stage.
     166             :      * @param flags If flags is 0, all submitted models are rendered.
     167             :      * If flags is non-zero, only models that contain flags in their
     168             :      * CModel::GetFlags() are rendered.
     169             :      */
     170             :     virtual void Render(
     171             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
     172             :         const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) = 0;
     173             : 
     174             :     /**
     175             :      * CopyPositionAndNormals: Copy unanimated object-space vertices and
     176             :      * normals into the given vertex array.
     177             :      *
     178             :      * @param mdef The underlying CModelDef that contains mesh data.
     179             :      * @param Position Points to the array that will receive
     180             :      * position vectors. The array behind the iterator
     181             :      * must be large enough to hold model->GetModelDef()->GetNumVertices()
     182             :      * vertices.
     183             :      * @param Normal Points to the array that will receive normal vectors.
     184             :      * The array behind the iterator must be as large as the Position array.
     185             :      */
     186             :     static void CopyPositionAndNormals(
     187             :             const CModelDefPtr& mdef,
     188             :             const VertexArrayIterator<CVector3D>& Position,
     189             :             const VertexArrayIterator<CVector3D>& Normal);
     190             : 
     191             :     /**
     192             :      * BuildPositionAndNormals: Build animated vertices and normals,
     193             :      * transformed into world space.
     194             :      *
     195             :      * @param model The model that is to be transformed.
     196             :      * @param Position Points to the array that will receive
     197             :      * transformed position vectors. The array behind the iterator
     198             :      * must be large enough to hold model->GetModelDef()->GetNumVertices()
     199             :      * vertices. It must allow 16 bytes to be written to each element
     200             :      * (i.e. provide 4 bytes of padding after each CVector3D).
     201             :      * @param Normal Points to the array that will receive transformed
     202             :      * normal vectors. The array behind the iterator must be as large as
     203             :      * the Position array.
     204             :      */
     205             :     static void BuildPositionAndNormals(
     206             :             CModel* model,
     207             :             const VertexArrayIterator<CVector3D>& Position,
     208             :             const VertexArrayIterator<CVector3D>& Normal);
     209             : 
     210             :     /**
     211             :      * BuildColor4ub: Build lighting colors for the given model,
     212             :      * based on previously calculated world space normals.
     213             :      *
     214             :      * @param model The model that is to be lit.
     215             :      * @param Normal Array of the model's normal vectors, animated and
     216             :      * transformed into world space.
     217             :      * @param Color Points to the array that will receive the lit vertex color.
     218             :      * The array behind the iterator must large enough to hold
     219             :      * model->GetModelDef()->GetNumVertices() vertices.
     220             :      */
     221             :     static void BuildColor4ub(
     222             :             CModel* model,
     223             :             const VertexArrayIterator<CVector3D>& Normal,
     224             :             const VertexArrayIterator<SColor4ub>& Color);
     225             : 
     226             :     /**
     227             :      * BuildUV: Copy UV coordinates into the given vertex array.
     228             :      *
     229             :      * @param mdef The model def.
     230             :      * @param UV Points to the array that will receive UV coordinates.
     231             :      * The array behind the iterator must large enough to hold
     232             :      * mdef->GetNumVertices() vertices.
     233             :      */
     234             :     static void BuildUV(
     235             :             const CModelDefPtr& mdef,
     236             :             const VertexArrayIterator<float[2]>& UV,
     237             :             int UVset);
     238             : 
     239             :     /**
     240             :      * BuildIndices: Create the indices array for the given CModelDef.
     241             :      *
     242             :      * @param mdef The model definition object.
     243             :      * @param Indices The index array, must be able to hold
     244             :      * mdef->GetNumFaces()*3 elements.
     245             :      */
     246             :     static void BuildIndices(
     247             :             const CModelDefPtr& mdef,
     248             :             const VertexArrayIterator<u16>& Indices);
     249             : 
     250             :     /**
     251             :      * GenTangents: Generate tangents for the given CModelDef.
     252             :      *
     253             :      * @param mdef The model definition object.
     254             :      * @param newVertices An out vector of the unindexed vertices with tangents added.
     255             :      * The new vertices cannot be used with existing face index and must be welded/reindexed.
     256             :      */
     257             :     static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
     258             : };
     259             : 
     260             : /**
     261             :  * Implementation of ModelRenderer that loads the appropriate shaders for
     262             :  * rendering each model, and that batches by shader technique (and by mesh and texture).
     263             :  */
     264             : class ShaderModelRenderer : public ModelRenderer
     265             : {
     266             :     friend struct ShaderModelRendererInternals;
     267             : 
     268             : public:
     269             :     ShaderModelRenderer(ModelVertexRendererPtr vertexrender);
     270             :     ~ShaderModelRenderer() override;
     271             : 
     272             :     // Batching implementations
     273             :     void Submit(int cullGroup, CModel* model) override;
     274             :     void PrepareModels() override;
     275             :     void UploadModels(
     276             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override;
     277             :     void EndFrame() override;
     278             :     void Render(
     279             :         Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
     280             :         const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) override;
     281             : 
     282             : private:
     283             :     struct ShaderModelRendererInternals;
     284             :     ShaderModelRendererInternals* m;
     285             : };
     286             : 
     287             : #endif // INCLUDED_MODELRENDERER

Generated by: LCOV version 1.13