Skip to content

Commit

Permalink
[LMAE-23] - Materials
Browse files Browse the repository at this point in the history
  • Loading branch information
progrematic committed Sep 1, 2021
1 parent 4c8a144 commit d941bb9
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 37 deletions.
82 changes: 82 additions & 0 deletions hippo/include/hippo/graphics/material.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#pragma once

#include <memory>
#include <unordered_map>
#include <string>
#include <type_traits>

#include "external/glm/glm.hpp"

namespace hippo::graphics
{
class Shader;
class Texture;
class Material
{
public:
Material(std::shared_ptr<Shader> shader, std::shared_ptr<Texture> texture = nullptr);
Material(const Material& other);
~Material();

inline Shader* GetShader() const { return mShader.get(); }
inline Texture* GetTexture() const { return mTexture.get(); }

void SetShader(std::shared_ptr<Shader> shader);
void SetTexture(std::shared_ptr<Texture> texture);
void UpdateShaderUniforms();

#define GETUNIFORMVALUE(mapName, defaultReturn) \
const auto& it = mapName.find(name);\
if (it != mapName.end())\
{\
return it->second;\
}\
return defaultReturn;

template<typename T>
inline T GetUniformValue(const std::string& name) const
{
if constexpr (std::is_same<T, int>()) { GETUNIFORMVALUE(mUniformInts, 0) }
else if constexpr (std::is_same<T, float>()) { GETUNIFORMVALUE(mUniformFloats, 0.f) }
else if constexpr (std::is_same<T, glm::vec2>()) { GETUNIFORMVALUE(mUniformFloat2s, glm::vec2(0.f)) }
else if constexpr (std::is_same<T, glm::vec3>()) { GETUNIFORMVALUE(mUniformFloat3s, glm::vec3(0.f)) }
else if constexpr (std::is_same<T, glm::vec4>()) { GETUNIFORMVALUE(mUniformFloat4s, glm::vec4(0.f)) }
else if constexpr (std::is_same<T, glm::mat3>()) { GETUNIFORMVALUE(mUniformMat3s, glm::mat3(1.f)) }
else if constexpr (std::is_same<T, glm::mat4>()) { GETUNIFORMVALUE(mUniformMat4s, glm::mat4(1.f)) }
else
{
static_assert(false, "Unsupported data type in Material::GetUniformValue()");
}
}
#undef GETUNIFORMVALUE

template<typename T>
inline void SetUniformValue(const std::string& name, const T& val)
{
if constexpr (std::is_same<T, int>()) { mUniformInts[name] = val; }
else if constexpr (std::is_same<T, float>()) { mUniformFloats[name] = val; }
else if constexpr (std::is_same<T, glm::vec2>()) { mUniformFloat2s[name] = val; }
else if constexpr (std::is_same<T, glm::vec3>()) { mUniformFloat3s[name] = val; }
else if constexpr (std::is_same<T, glm::vec4>()) { mUniformFloat4s[name] = val; }
else if constexpr (std::is_same<T, glm::mat3>()) { mUniformMat3s[name] = val; }
else if constexpr (std::is_same<T, glm::mat4>()) { mUniformMat4s[name] = val; }
else
{
static_assert(false, "Unsupported data type in Material::SetUniformValue()");
}
}

private:
std::shared_ptr<Shader> mShader;
std::shared_ptr<Texture> mTexture;

// Data
std::unordered_map<std::string, int> mUniformInts;
std::unordered_map<std::string, float> mUniformFloats;
std::unordered_map<std::string, glm::vec2> mUniformFloat2s;
std::unordered_map<std::string, glm::vec3> mUniformFloat3s;
std::unordered_map<std::string, glm::vec4> mUniformFloat4s;
std::unordered_map<std::string, glm::mat3> mUniformMat3s;
std::unordered_map<std::string, glm::mat4> mUniformMat4s;
};
}
27 changes: 25 additions & 2 deletions hippo/include/hippo/graphics/rendercommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

#include <memory>

#include "external/glm/glm.hpp"

namespace hippo::graphics
{
class VertexArray;
class Shader;
class Texture;
class Framebuffer;
class Camera;
class Material;

namespace rendercommands
{
Expand All @@ -22,31 +25,51 @@ namespace hippo::graphics
class RenderVertexArray : public RenderCommand
{
public:
RenderVertexArray(std::weak_ptr<VertexArray> vertexArray, std::weak_ptr<Shader> shader)
RenderVertexArray(std::weak_ptr<VertexArray> vertexArray, std::weak_ptr<Shader> shader, const glm::mat4 modelMatrix = glm::mat4(1.f))
: mVertexArray(vertexArray)
, mShader(shader)
, mModelMatrix(modelMatrix)
{}
virtual void Execute() override;

private:
std::weak_ptr<VertexArray> mVertexArray;
std::weak_ptr<Shader> mShader;
glm::mat4 mModelMatrix;
};

class RenderVertexArrayTextured : public RenderCommand
{
public:
RenderVertexArrayTextured(std::weak_ptr<VertexArray> vertexArray, std::weak_ptr<Texture> texture, std::weak_ptr<Shader> shader)
RenderVertexArrayTextured(std::weak_ptr<VertexArray> vertexArray, std::weak_ptr<Texture> texture, std::weak_ptr<Shader> shader, const glm::mat4 modelMatrix = glm::mat4(1.f))
: mVertexArray(vertexArray)
, mTexture(texture)
, mShader(shader)
, mModelMatrix(modelMatrix)
{}
virtual void Execute() override;

private:
std::weak_ptr<VertexArray> mVertexArray;
std::weak_ptr<Texture> mTexture;
std::weak_ptr<Shader> mShader;
glm::mat4 mModelMatrix;
};

class RenderVertexArrayMaterial: public RenderCommand
{
public:
RenderVertexArrayMaterial(std::weak_ptr<VertexArray> vertexArray, std::weak_ptr<Material> material, const glm::mat4 modelMatrix = glm::mat4(1.f))
: mVertexArray(vertexArray)
, mMaterial(material)
, mModelMatrix(modelMatrix)
{}
virtual void Execute() override;

private:
std::weak_ptr<VertexArray> mVertexArray;
std::weak_ptr<Material> mMaterial;
glm::mat4 mModelMatrix;
};

class PushFramebuffer : public RenderCommand
Expand Down
82 changes: 82 additions & 0 deletions hippo/src/graphics/material.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "hippo/graphics/material.h"
#include "hippo/graphics/shader.h"

#include "hippo/log.h"

namespace hippo::graphics
{

Material::Material(std::shared_ptr<Shader> shader, std::shared_ptr<Texture> texture /*= nullptr*/)
: mShader(shader)
, mTexture(texture)
{
HIPPO_ASSERT(mShader, "Attempting to instantiate a material with a nullptr shader");
}

Material::Material(const Material& other)
{
mShader = other.mShader;
mTexture = other.mTexture;

// Data
mUniformInts = other.mUniformInts;
mUniformFloats = other.mUniformFloats;
mUniformFloat2s = other.mUniformFloat2s;
mUniformFloat3s = other.mUniformFloat3s;
mUniformFloat4s = other.mUniformFloat4s;
mUniformMat3s = other.mUniformMat3s;
mUniformMat4s = other.mUniformMat4s;
}

Material::~Material() {}

void Material::SetShader(std::shared_ptr<Shader> shader)
{
HIPPO_ASSERT(shader, "Attempting to set a nullptr shader");
if (shader)
{
mShader = shader;
}
}

void Material::SetTexture(std::shared_ptr<Texture> texture)
{
mTexture = texture;
}

void Material::UpdateShaderUniforms()
{
if (mShader)
{
for (const auto& it : mUniformInts)
{
mShader->SetUniformInt(it.first, it.second);
}
for (const auto& it : mUniformFloats)
{
mShader->SetUniformFloat(it.first, it.second);
}
for (const auto& it : mUniformFloat2s)
{
mShader->SetUniformFloat2(it.first, it.second);
}
for (const auto& it : mUniformFloat3s)
{
mShader->SetUniformFloat3(it.first, it.second);
}
for (const auto& it : mUniformFloat4s)
{
mShader->SetUniformFloat4(it.first, it.second);
}
for (const auto& it : mUniformMat3s)
{
mShader->SetUniformMat3(it.first, it.second);
}
for (const auto& it : mUniformMat4s)
{
mShader->SetUniformMat4(it.first, it.second);
}
}
}

}
64 changes: 64 additions & 0 deletions hippo/src/graphics/rendercommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "hippo/graphics/texture.h"
#include "hippo/graphics/framebuffer.h"
#include "hippo/graphics/camera.h"
#include "hippo/graphics/material.h"

#include "glad/glad.h"

Expand All @@ -34,6 +35,8 @@ namespace hippo::graphics::rendercommands
shader->SetUniformMat4("view", cam->GetViewMatrix());
}

shader->SetUniformMat4("model", mModelMatrix);

if (va->GetElementCount() > 0)
{
glDrawElements(GL_TRIANGLES, va->GetElementCount(), GL_UNSIGNED_INT, 0);
Expand Down Expand Up @@ -76,6 +79,8 @@ namespace hippo::graphics::rendercommands
shader->SetUniformMat4("view", cam->GetViewMatrix());
}

shader->SetUniformMat4("model", mModelMatrix);

if (va->GetElementCount() > 0)
{
glDrawElements(GL_TRIANGLES, va->GetElementCount(), GL_UNSIGNED_INT, 0);
Expand All @@ -96,6 +101,65 @@ namespace hippo::graphics::rendercommands
}
}

void RenderVertexArrayMaterial::Execute()
{
std::shared_ptr<VertexArray> va = mVertexArray.lock();
std::shared_ptr<Material> mat = mMaterial.lock();
if (va && mat)
{
HIPPO_ASSERT(va->IsValid(), "Attempting to execute invalid RenderVertexArrayMaterial - did you forget to call VertexArray::Upload()?");
if (va->IsValid())
{
va->Bind();

Shader* shader = mat->GetShader();
Texture* texture = mat->GetTexture();
HIPPO_ASSERT(shader, "Attempting to execute invalid RenderVertexArrayMaterial - shader is nullptr");
if (shader)
{
mat->UpdateShaderUniforms();
shader->Bind();
if (texture)
{
texture->Bind();
}

// TODO: Convert camera matrices to leverage UBOs
const auto& rm = Engine::Instance().GetRenderManager();
const auto& cam = rm.GetActiveCamera();
if (cam)
{
shader->SetUniformMat4("proj", cam->GetProjectionMatrix());
shader->SetUniformMat4("view", cam->GetViewMatrix());
}

shader->SetUniformMat4("model", mModelMatrix);

if (va->GetElementCount() > 0)
{
glDrawElements(GL_TRIANGLES, va->GetElementCount(), GL_UNSIGNED_INT, 0);
}
else
{
glDrawArrays(GL_TRIANGLE_STRIP, 0, va->GetVertexCount()); HIPPO_CHECK_GL_ERROR;
}

if (texture)
{
texture->Unbind();
}
shader->Unbind();
}

va->Unbind();
}
}
else
{
HIPPO_WARN("Attempting to execute RenderVertexArrayMaterial with invalid data");
}
}

void PushFramebuffer::Execute()
{
std::shared_ptr<Framebuffer> fb = mFramebuffer.lock();
Expand Down
Loading

0 comments on commit d941bb9

Please sign in to comment.