2015-01-25 04:10:58 +01:00
|
|
|
/* Copyright (C) 2015 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-04-18 19:51:05 +02:00
|
|
|
/*
|
|
|
|
* Home to the ModelRenderer class, an abstract base class that manages
|
|
|
|
* a per-frame list of submitted models, as well as simple helper
|
|
|
|
* classes.
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
|
|
|
|
2007-05-07 18:33:24 +02:00
|
|
|
#ifndef INCLUDED_MODELRENDERER
|
|
|
|
#define INCLUDED_MODELRENDERER
|
2005-10-25 03:43:07 +02:00
|
|
|
|
2015-01-25 04:10:58 +01:00
|
|
|
#include <memory>
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
#include "graphics/MeshManager.h"
|
|
|
|
#include "graphics/RenderableObject.h"
|
2006-09-26 03:44:20 +02:00
|
|
|
#include "graphics/SColor.h"
|
2005-10-25 03:43:07 +02:00
|
|
|
#include "renderer/VertexArray.h"
|
|
|
|
|
|
|
|
class RenderModifier;
|
2007-12-20 21:21:45 +01:00
|
|
|
typedef shared_ptr<RenderModifier> RenderModifierPtr;
|
2005-10-25 03:43:07 +02:00
|
|
|
|
2006-03-26 01:54:20 +01:00
|
|
|
class LitRenderModifier;
|
2007-12-20 21:21:45 +01:00
|
|
|
typedef shared_ptr<LitRenderModifier> LitRenderModifierPtr;
|
2006-03-26 01:54:20 +01:00
|
|
|
|
2005-11-06 00:15:23 +01:00
|
|
|
class ModelVertexRenderer;
|
2007-12-20 21:21:45 +01:00
|
|
|
typedef shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
|
2005-11-06 00:15:23 +01:00
|
|
|
|
2012-04-03 20:44:46 +02:00
|
|
|
class ModelRenderer;
|
|
|
|
typedef shared_ptr<ModelRenderer> ModelRendererPtr;
|
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
class CModel;
|
2012-04-03 20:44:46 +02:00
|
|
|
class CShaderDefines;
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
2006-02-13 15:18:20 +01:00
|
|
|
* Class CModelRData: Render data that is maintained per CModel.
|
2005-10-25 03:43:07 +02:00
|
|
|
* ModelRenderer implementations may derive from this class to store
|
|
|
|
* per-CModel data.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-10-25 03:43:07 +02:00
|
|
|
* The main purpose of this class over CRenderData is to track which
|
|
|
|
* ModelRenderer the render data belongs to (via the key that is passed
|
|
|
|
* to the constructor). When a model changes the renderer it uses
|
|
|
|
* (e.g. via run-time modification of the renderpath configuration),
|
|
|
|
* the old ModelRenderer's render data is supposed to be replaced by
|
|
|
|
* the new data.
|
|
|
|
*/
|
|
|
|
class CModelRData : public CRenderData
|
|
|
|
{
|
|
|
|
public:
|
2012-04-03 20:44:46 +02:00
|
|
|
CModelRData(const void* key) : m_Key(key) { }
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GetKey: Retrieve the key that can be used to identify the
|
|
|
|
* ModelRenderer that created this data.
|
|
|
|
*
|
|
|
|
* @return The opaque key that was passed to the constructor.
|
|
|
|
*/
|
|
|
|
const void* GetKey() const { return m_Key; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// The key for model renderer identification
|
|
|
|
const void* m_Key;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class ModelRenderer: Abstract base class for all model renders.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-10-25 03:43:07 +02:00
|
|
|
* A ModelRenderer manages a per-frame list of models.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-11-06 00:15:23 +01:00
|
|
|
* 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.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-11-06 00:15:23 +01:00
|
|
|
* A typical ModelRenderer will delegate vertex transformation/setup
|
|
|
|
* to a ModelVertexRenderer.
|
|
|
|
* It will delegate fragment stage setup to a RenderModifier.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-11-06 00:15:23 +01:00
|
|
|
* For most purposes, you should use a BatchModelRenderer with
|
|
|
|
* specialized ModelVertexRenderer and RenderModifier implementations.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-10-25 03:43:07 +02:00
|
|
|
* 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.
|
2006-02-13 15:18:20 +01:00
|
|
|
*
|
2005-10-25 03:43:07 +02:00
|
|
|
* ModelRenderer also contains a number of static helper functions
|
|
|
|
* for building vertex arrays.
|
|
|
|
*/
|
|
|
|
class ModelRenderer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ModelRenderer() { }
|
|
|
|
virtual ~ModelRenderer() { }
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2011-11-10 00:11:28 +01:00
|
|
|
/**
|
|
|
|
* Initialise global settings.
|
|
|
|
* Should be called before using the class.
|
|
|
|
*/
|
|
|
|
static void Init();
|
2016-11-23 12:18:37 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* Submit: Submit a model for rendering this frame.
|
|
|
|
*
|
|
|
|
* preconditions : The model must not have been submitted to any
|
|
|
|
* ModelRenderer in this frame. Submit may only be called
|
|
|
|
* after EndFrame and before PrepareModels.
|
|
|
|
*
|
|
|
|
* @param model The model that will be added to the list of models
|
|
|
|
* submitted this frame.
|
|
|
|
*/
|
2014-06-25 03:11:10 +02:00
|
|
|
virtual void Submit(int cullGroup, CModel* model) = 0;
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* PrepareModels: Calculate renderer data for all previously
|
|
|
|
* submitted models.
|
|
|
|
*
|
|
|
|
* Must be called before any rendering calls and after all models
|
|
|
|
* for this frame have been submitted.
|
|
|
|
*/
|
|
|
|
virtual void PrepareModels() = 0;
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* EndFrame: Remove all models from the list of submitted
|
|
|
|
* models.
|
|
|
|
*/
|
|
|
|
virtual void EndFrame() = 0;
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* Render: Render submitted models, using the given RenderModifier to setup
|
|
|
|
* the fragment stage.
|
|
|
|
*
|
2006-02-13 15:18:20 +01:00
|
|
|
* @note It is suggested that derived model renderers implement and use
|
2005-10-25 03:43:07 +02:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* @param modifier The RenderModifier that specifies the fragment stage.
|
|
|
|
* @param flags If flags is 0, all submitted models are rendered.
|
|
|
|
* If flags is non-zero, only models that contain flags in their
|
|
|
|
* CModel::GetFlags() are rendered.
|
|
|
|
*/
|
2014-06-25 03:11:10 +02:00
|
|
|
virtual void Render(const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) = 0;
|
2011-07-13 01:48:05 +02:00
|
|
|
|
2005-10-30 02:22:22 +02:00
|
|
|
/**
|
|
|
|
* CopyPositionAndNormals: Copy unanimated object-space vertices and
|
|
|
|
* normals into the given vertex array.
|
|
|
|
*
|
|
|
|
* @param mdef The underlying CModelDef that contains mesh data.
|
|
|
|
* @param Position Points to the array that will receive
|
|
|
|
* position vectors. The array behind the iterator
|
|
|
|
* must be large enough to hold model->GetModelDef()->GetNumVertices()
|
|
|
|
* vertices.
|
|
|
|
* @param Normal Points to the array that will receive normal vectors.
|
|
|
|
* The array behind the iterator must be as large as the Position array.
|
|
|
|
*/
|
|
|
|
static void CopyPositionAndNormals(
|
2008-07-17 16:23:51 +02:00
|
|
|
const CModelDefPtr& mdef,
|
|
|
|
const VertexArrayIterator<CVector3D>& Position,
|
|
|
|
const VertexArrayIterator<CVector3D>& Normal);
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
2006-02-13 15:18:20 +01:00
|
|
|
* BuildPositionAndNormals: Build animated vertices and normals,
|
2005-10-25 03:43:07 +02:00
|
|
|
* transformed into world space.
|
|
|
|
*
|
|
|
|
* @param model The model that is to be transformed.
|
|
|
|
* @param Position Points to the array that will receive
|
|
|
|
* transformed position vectors. The array behind the iterator
|
|
|
|
* must be large enough to hold model->GetModelDef()->GetNumVertices()
|
2011-11-10 00:11:28 +01:00
|
|
|
* vertices. It must allow 16 bytes to be written to each element
|
|
|
|
* (i.e. provide 4 bytes of padding after each CVector3D).
|
2005-10-25 03:43:07 +02:00
|
|
|
* @param Normal Points to the array that will receive transformed
|
|
|
|
* normal vectors. The array behind the iterator must be as large as
|
|
|
|
* the Position array.
|
|
|
|
*/
|
|
|
|
static void BuildPositionAndNormals(
|
|
|
|
CModel* model,
|
2008-07-17 16:23:51 +02:00
|
|
|
const VertexArrayIterator<CVector3D>& Position,
|
|
|
|
const VertexArrayIterator<CVector3D>& Normal);
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* BuildColor4ub: Build lighting colors for the given model,
|
|
|
|
* based on previously calculated world space normals.
|
|
|
|
*
|
|
|
|
* @param model The model that is to be lit.
|
|
|
|
* @param Normal Array of the model's normal vectors, animated and
|
|
|
|
* transformed into world space.
|
|
|
|
* @param Color Points to the array that will receive the lit vertex color.
|
|
|
|
* The array behind the iterator must large enough to hold
|
|
|
|
* model->GetModelDef()->GetNumVertices() vertices.
|
|
|
|
*/
|
|
|
|
static void BuildColor4ub(
|
|
|
|
CModel* model,
|
2008-07-17 16:23:51 +02:00
|
|
|
const VertexArrayIterator<CVector3D>& Normal,
|
2011-04-07 00:07:13 +02:00
|
|
|
const VertexArrayIterator<SColor4ub>& Color);
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
/**
|
|
|
|
* BuildUV: Copy UV coordinates into the given vertex array.
|
|
|
|
*
|
|
|
|
* @param mdef The model def.
|
|
|
|
* @param UV Points to the array that will receive UV coordinates.
|
|
|
|
* The array behind the iterator must large enough to hold
|
|
|
|
* mdef->GetNumVertices() vertices.
|
|
|
|
*/
|
|
|
|
static void BuildUV(
|
2008-07-17 16:23:51 +02:00
|
|
|
const CModelDefPtr& mdef,
|
2012-07-24 00:49:46 +02:00
|
|
|
const VertexArrayIterator<float[2]>& UV,
|
|
|
|
int UVset);
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* BuildIndices: Create the indices array for the given CModelDef.
|
|
|
|
*
|
|
|
|
* @param mdef The model definition object.
|
2006-02-13 15:18:20 +01:00
|
|
|
* @param Indices The index array, must be able to hold
|
2005-10-25 03:43:07 +02:00
|
|
|
* mdef->GetNumFaces()*3 elements.
|
|
|
|
*/
|
|
|
|
static void BuildIndices(
|
2008-07-17 16:23:51 +02:00
|
|
|
const CModelDefPtr& mdef,
|
2011-03-13 19:58:09 +01:00
|
|
|
const VertexArrayIterator<u16>& Indices);
|
2016-11-23 12:18:37 +01:00
|
|
|
|
2012-08-06 21:10:47 +02:00
|
|
|
/**
|
|
|
|
* GenTangents: Generate tangents for the given CModelDef.
|
|
|
|
*
|
|
|
|
* @param mdef The model definition object.
|
2016-11-23 12:18:37 +01:00
|
|
|
* @param newVertices An out vector of the unindexed vertices with tangents added.
|
2012-08-06 21:10:47 +02:00
|
|
|
* The new vertices cannot be used with existing face index and must be welded/reindexed.
|
|
|
|
*/
|
2012-10-29 14:20:21 +01:00
|
|
|
static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
|
2005-10-25 03:43:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-04-03 20:44:46 +02:00
|
|
|
struct ShaderModelRendererInternals;
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
/**
|
2012-04-03 20:44:46 +02:00
|
|
|
* Implementation of ModelRenderer that loads the appropriate shaders for
|
|
|
|
* rendering each model, and that batches by shader (and by mesh and texture).
|
2016-11-23 12:18:37 +01:00
|
|
|
*
|
2012-04-03 20:44:46 +02:00
|
|
|
* Note that the term "Shader" is somewhat misleading, as this handled
|
|
|
|
* fixed-function rendering using the same API as real GLSL/ARB shaders.
|
2005-10-25 03:43:07 +02:00
|
|
|
*/
|
2012-04-03 20:44:46 +02:00
|
|
|
class ShaderModelRenderer : public ModelRenderer
|
2005-10-25 03:43:07 +02:00
|
|
|
{
|
2012-04-03 20:44:46 +02:00
|
|
|
friend struct ShaderModelRendererInternals;
|
2006-02-13 15:18:20 +01:00
|
|
|
|
2005-10-25 03:43:07 +02:00
|
|
|
public:
|
2012-04-03 20:44:46 +02:00
|
|
|
ShaderModelRenderer(ModelVertexRendererPtr vertexrender);
|
|
|
|
virtual ~ShaderModelRenderer();
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
// Batching implementations
|
2014-06-25 03:11:10 +02:00
|
|
|
virtual void Submit(int cullGroup, CModel* model);
|
2005-10-25 03:43:07 +02:00
|
|
|
virtual void PrepareModels();
|
|
|
|
virtual void EndFrame();
|
2014-06-25 03:11:10 +02:00
|
|
|
virtual void Render(const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags);
|
2005-10-25 03:43:07 +02:00
|
|
|
|
|
|
|
private:
|
2012-04-03 20:44:46 +02:00
|
|
|
ShaderModelRendererInternals* m;
|
2005-10-25 03:43:07 +02:00
|
|
|
};
|
|
|
|
|
2007-05-07 18:33:24 +02:00
|
|
|
#endif // INCLUDED_MODELRENDERER
|