I made this Renderer
class recently, to simplify the user interface of my library's API. I would like to ask advice about the move semantics (copy constructor, std::unique_ptr
, ...), or any other things you can point out to improve my code.
As you can see, I take in parameters in RenderObject
in the form of a pointer. This is simply because Material
uses a Texture
class, whose assignment operators are disabled. It only has a move constructor (C++11), but Material cannot use it.
RenderObject.h
#pragma once
#include "alpha/Mesh.h"
#include "alpha/Texture.h"
#include "alpha/Light.h"
#include "alpha/Transform.h"
class RenderObject
{
public:
RenderObject(
Mesh* mesh, Material* material,
Transform transform = Transform()
)
:
m_pmesh(mesh),
m_pmaterial(material),
m_transform(transform)
{}
~RenderObject(){}
void SetTransform(Transform transform){
m_transform = transform;
}
Transform GetTransform(){
return m_transform;
}
Mesh* GetMesh(){
return m_pmesh;
}
void SetMesh(Mesh* mesh){
m_pmesh = mesh;
}
Material* GetMaterial(){
return m_pmaterial;
}
void SetMaterial(Material* material){
m_pmaterial = material;
}
void SetPosition(glm::vec3 position){
m_transform.SetPos(position);
}
void SetRotation(glm::vec3 rotation){
m_transform.SetRot(rotation);
}
void SetScale(glm::vec3 scale){
m_transform.SetScale(scale);
}
glm::vec3 GetPosition(){
return m_transform.GetPos();
}
glm::vec3 GetRotation(){
return m_transform.GetRot();
}
glm::vec3 GetScale(){
return m_transform.GetScale();
}
private:
Transform m_transform;
Mesh* m_pmesh = nullptr;
Material* m_pmaterial = nullptr;
};
Material.h
class Material{
public:
template<typename T>
Material(T&& texture, float shininess,
const glm::vec3& specularColor = glm::vec3(0.5, 1.0, 1.5),
const glm::vec3& emissiveColor = glm::vec3(0.0, 0.0, 0.0)
)
:
m_texture(std::forward<T>(texture)),
m_shininess(shininess),
m_specularColor(specularColor),
m_emissiveColor(emissiveColor)
{}
~Material(){
m_texture.Dispose(); ///not necessary... ressources are automatically disposed in texture !
}
void Bind(unsigned unit = 0){
this->m_texture.Bind(unit);
}
void SetUniforms(Shader& shader) const{
shader.UpdateUniform3fv("materialSpecularColor" ,glm::value_ptr(this->m_specularColor));
shader.UpdateUniform1f("materialShininess", this->m_shininess);
shader.UpdateUniform3fv("materialEmissiveColor", glm::value_ptr(this->m_emissiveColor));
}
void SetShininess(float shininess){
m_shininess = shininess;
}
void SetSpecularColor(glm::vec3 specularColor){
m_specularColor = specularColor;
}
void SetEmissiveColor(glm::vec3 emissiveColor){
m_emissiveColor = emissiveColor;
}
float GetShininess(){
return m_shininess;
}
glm::vec3 GetSpecularColor(){
return m_specularColor;
}
glm::vec3 GetEmissiveColor(){
return m_emissiveColor;
}
Texture& GetTexture(){
return m_texture;
}
Material& operator=(const Material& other) = delete;
Material(const Material& other) = delete;
protected:
float m_shininess;
glm::vec3 m_specularColor;
glm::vec3 m_emissiveColor;
Texture m_texture;
///more lighting... normal maps...
};
Renderer.h
#pragma once
#include <vector>
#include "alpha/Light.h"
#include "alpha/Mesh.h"
#include "alpha/Texture.h"
#include "alpha/Light.h"
#include "alpha/Transform.h"
#include "alpha/RenderObject.h"
class ForwardRenderer
{
public:
ForwardRenderer(){}///default ctor
ForwardRenderer(std::vector<RenderObject>* objects)
:
m_pobjects(objects),
m_shader("res/basicShader.glslv", "res/phongShader.glslf")
{}
ForwardRenderer(
std::vector<RenderObject>* objects,
PhongLight* light
)
:
m_pobjects(objects),
m_plight(light),
m_shader("res/basicShader.glslv", "res/phongShader.glslf")
{}
~ForwardRenderer(){}///default dtor
void RenderAll(Camera& camera){
m_shader.Bind();
for(auto it = m_pobjects->begin(); it != m_pobjects->end(); ++it){
///Set Uniforms
camera.SetUniforms(m_shader, it->GetTransform());
it->GetMaterial()->SetUniforms(m_shader);
m_plight->SetUniforms(m_shader);
///Render
it->GetMaterial()->Bind(0);///sampler slot = 0;
it->GetMesh()->Draw();
camera.SetUniforms(m_shader, Transform());
}
}
ForwardRenderer& operator=(const ForwardRenderer& other) = delete;
ForwardRenderer(const ForwardRenderer& other) = delete;
private:
std::vector<RenderObject>* m_pobjects = nullptr;
PhongLight* m_plight = nullptr;
Shader m_shader;
};
typedef ForwardRenderer BasicRenderer;