Recently, I implemented an RenderBatch
class, which renders any objects, using a specific shader (with its configuration). I'd like to improve on the way my render process works.
RenderBatch.h:
#pragma once
#include "alpha/Shader.h"
#include "alpha/RenderComponent.h"
#include <glm/glm.hpp>
#include "alpha/Mesh.h"
#include "alpha/Transform.h"
#include "alpha/Model.h"
class ShaderConfiguration
{
public:
ShaderConfiguration();
virtual ~ShaderConfiguration();
virtual void Update(Shader& shader);
void SetProjectionView(const glm::mat4& projectionView){
m_projectionView = projectionView;
}
glm::mat4 GetProjectionView() const{
return m_projectionView;
}
void SetTransform(const Transform& transform){
m_transform = transform;
}
Transform GetTransform(){
return m_transform;
}
protected:
glm::mat4 m_projectionView;
Transform m_transform;
};
typedef ShaderConfiguration DefaultShaderConfiguration;
///Render Batch is really low lovel... It is only advised to use it
///in case you want to experiment with GLSL shaders : for more basic uses,
///ModelBatch is actually integrated in the GameObject system...
class RenderBatch : RenderComponent
{
public:
RenderBatch(){
m_shader.loadFromFile(GL_VERTEX_SHADER, "res/basicShader.glslv");
m_shader.loadFromFile(GL_FRAGMENT_SHADER, "res/basicShader.glslf");
m_shader.CreateAndLink();
}
RenderBatch(Shader shader)
: m_shader(shader){}
virtual ~RenderBatch(){}
void SetShader(Shader shader){this->m_shader = shader;}
Shader GetShader()const {return m_shader;}
///Genereal way of updating -----------------> using polymorphism
void UpdateShaderConfiguration(ShaderConfiguration* config){
m_shader.Bind();
config->Update(m_shader);
m_shader.UnBind();
}
///Update for simple rendering --------------> ProjectionView + Transform ()
///Equivalent of :
///DefaultShaderConfiguration defaultShaderConfiguration
///UpdateShaderConfiguration(&defaultShaderConfiguration);
void Update(glm::mat4 projectionView, Transform transform){
m_shader.Bind();
glUniformMatrix4fv(
m_shader.GetUniformLocation("MVP"),
1,
GL_FALSE,
glm::value_ptr(projectionView * transform.GetModelView())
);
m_shader.UnBind();
}
void Render(Mesh& mesh){
m_shader.Bind();
mesh.Draw();
m_shader.UnBind();
}
glm::mat4 GetProjectionViewMatrix(){
return m_projectionView;
}
void SetProjectionViewMatrix(glm::mat4 projectionView){
this->m_projectionView = projectionView;
}
protected:
Shader m_shader;
glm::mat4 m_projectionView;
};
RenderBatch.cpp
#include "alpha/RenderBatch.h"
ShaderConfiguration::ShaderConfiguration()
: m_projectionView(glm::mat4(1))
{}
ShaderConfiguration::~ShaderConfiguration(){}
void DefaultShaderConfiguration::Update(Shader& shader){
glUniformMatrix4fv(
shader.GetUniformLocation("MVP"),
1,
GL_FALSE,
glm::value_ptr(m_projectionView * m_transform.GetModelView())
);
}
Main.cpp
///example 1 ---->using defaults
RenderBatch batch = RenderBatch();
Mesh mesh("res/Test.obj");
Camera camera;
while(isRunning)
{
/*Update */
batch.Update(camera.Combined(), transform)
/*some more update code...*/
/*Render*/
batch.Render(mesh);
}
///example 2 ---->using custom configuration
RenderBatch batch = RenderBatch();
Mesh mesh("res/Test.obj");
Camera camera;
ShaderConfiguration config;
while(isRunning)
{
config.SetProjectionView(camera.combined());
config.SetTransform(transform)
/*Update */
batch.Update(config);
/*some more update code...*/
/*Render*/
batch.Render(mesh);
}