Skip to content
Permalink
Browse files

Added ShaderLibrary + misc fixes

  • Loading branch information...
TheCherno committed Sep 8, 2019
1 parent 7d120fb commit b576fd9f0326682da8ed8aa1a14abf25dc3bc630
@@ -6,28 +6,65 @@

namespace Hazel {

Shader* Shader::Create(const std::string& filepath)
Ref<Shader> Shader::Create(const std::string& filepath)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::None: HZ_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
case RendererAPI::API::OpenGL: return new OpenGLShader(filepath);
case RendererAPI::API::OpenGL: return std::make_shared<OpenGLShader>(filepath);
}

HZ_CORE_ASSERT(false, "Unknown RendererAPI!");
return nullptr;
}

Shader* Shader::Create(const std::string& vertexSrc, const std::string& fragmentSrc)
Ref<Shader> Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
{
switch (Renderer::GetAPI())
{
case RendererAPI::API::None: HZ_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
case RendererAPI::API::OpenGL: return new OpenGLShader(vertexSrc, fragmentSrc);
case RendererAPI::API::OpenGL: return std::make_shared<OpenGLShader>(name, vertexSrc, fragmentSrc);
}

HZ_CORE_ASSERT(false, "Unknown RendererAPI!");
return nullptr;
}

void ShaderLibrary::Add(const std::string& name, const Ref<Shader>& shader)
{
HZ_CORE_ASSERT(!Exists(name), "Shader already exists!");
m_Shaders[name] = shader;
}

void ShaderLibrary::Add(const Ref<Shader>& shader)
{
auto& name = shader->GetName();
Add(name, shader);
}

Hazel::Ref<Hazel::Shader> ShaderLibrary::Load(const std::string& filepath)
{
auto shader = Shader::Create(filepath);
Add(shader);
return shader;
}

Hazel::Ref<Hazel::Shader> ShaderLibrary::Load(const std::string& name, const std::string& filepath)
{
auto shader = Shader::Create(filepath);
Add(name, shader);
return shader;
}

Hazel::Ref<Hazel::Shader> ShaderLibrary::Get(const std::string& name)
{
HZ_CORE_ASSERT(Exists(name), "Shader not found!");
return m_Shaders[name];
}

bool ShaderLibrary::Exists(const std::string& name) const
{
return m_Shaders.find(name) != m_Shaders.end();
}

}
@@ -1,6 +1,7 @@
#pragma once

#include <string>
#include <unordered_map>

namespace Hazel {

@@ -12,8 +13,25 @@ namespace Hazel {
virtual void Bind() const = 0;
virtual void Unbind() const = 0;

static Shader* Create(const std::string& filepath);
static Shader* Create(const std::string& vertexSrc, const std::string& fragmentSrc);
virtual const std::string& GetName() const = 0;

static Ref<Shader> Create(const std::string& filepath);
static Ref<Shader> Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);
};

class ShaderLibrary
{
public:
void Add(const std::string& name, const Ref<Shader>& shader);
void Add(const Ref<Shader>& shader);
Ref<Shader> Load(const std::string& filepath);
Ref<Shader> Load(const std::string& name, const std::string& filepath);

Ref<Shader> Get(const std::string& name);

bool Exists(const std::string& name) const;
private:
std::unordered_map<std::string, Ref<Shader>> m_Shaders;
};

}
@@ -24,9 +24,17 @@ namespace Hazel {
std::string source = ReadFile(filepath);
auto shaderSources = PreProcess(source);
Compile(shaderSources);

// Extract name from filepath
auto lastSlash = filepath.find_last_of("/\\");
lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1;
auto lastDot = filepath.rfind('.');
auto count = lastDot == std::string::npos ? filepath.size() - lastSlash : lastDot - lastSlash;
m_Name = filepath.substr(lastSlash, count);
}

OpenGLShader::OpenGLShader(const std::string& vertexSrc, const std::string& fragmentSrc)
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
: m_Name(name)
{
std::unordered_map<GLenum, std::string> sources;
sources[GL_VERTEX_SHADER] = vertexSrc;
@@ -42,7 +50,7 @@ namespace Hazel {
std::string OpenGLShader::ReadFile(const std::string& filepath)
{
std::string result;
std::ifstream in(filepath, std::ios::in, std::ios::binary);
std::ifstream in(filepath, std::ios::in | std::ios::binary);
if (in)
{
in.seekg(0, std::ios::end);
@@ -85,7 +93,9 @@ namespace Hazel {
void OpenGLShader::Compile(const std::unordered_map<GLenum, std::string>& shaderSources)
{
GLuint program = glCreateProgram();
std::vector<GLenum> glShaderIDs(shaderSources.size());
HZ_CORE_ASSERT(shaderSources.size() <= 2, "We only support 2 shaders for now");
std::array<GLenum, 2> glShaderIDs;
int glShaderIDIndex = 0;
for (auto& kv : shaderSources)
{
GLenum type = kv.first;
@@ -116,7 +126,7 @@ namespace Hazel {
}

glAttachShader(program, shader);
glShaderIDs.push_back(shader);
glShaderIDs[glShaderIDIndex++] = shader;
}

m_RendererID = program;
@@ -12,12 +12,14 @@ namespace Hazel {
{
public:
OpenGLShader(const std::string& filepath);
OpenGLShader(const std::string& vertexSrc, const std::string& fragmentSrc);
OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);
virtual ~OpenGLShader();

virtual void Bind() const override;
virtual void Unbind() const override;

virtual const std::string& GetName() const override { return m_Name; }

void UploadUniformInt(const std::string& name, int value);

void UploadUniformFloat(const std::string& name, float value);
@@ -33,6 +35,7 @@ namespace Hazel {
void Compile(const std::unordered_map<GLenum, std::string>& shaderSources);
private:
uint32_t m_RendererID;
std::string m_Name;
};

}
@@ -8,6 +8,7 @@

#include <string>
#include <sstream>
#include <array>
#include <vector>
#include <unordered_map>
#include <unordered_set>
@@ -92,7 +92,7 @@ class ExampleLayer : public Hazel::Layer
}
)";

m_Shader.reset(Hazel::Shader::Create(vertexSrc, fragmentSrc));
m_Shader = Hazel::Shader::Create("VertexPosColor", vertexSrc, fragmentSrc);

std::string flatColorShaderVertexSrc = R"(
#version 330 core
@@ -126,15 +126,15 @@ class ExampleLayer : public Hazel::Layer
}
)";

m_FlatColorShader.reset(Hazel::Shader::Create(flatColorShaderVertexSrc, flatColorShaderFragmentSrc));
m_FlatColorShader = Hazel::Shader::Create("FlatColor", flatColorShaderVertexSrc, flatColorShaderFragmentSrc);

m_TextureShader.reset(Hazel::Shader::Create("assets/shaders/Texture.glsl"));
auto textureShader = m_ShaderLibrary.Load("assets/shaders/Texture.glsl");

m_Texture = Hazel::Texture2D::Create("assets/textures/Checkerboard.png");
m_ChernoLogoTexture = Hazel::Texture2D::Create("assets/textures/ChernoLogo.png");

std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_TextureShader)->Bind();
std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_TextureShader)->UploadUniformInt("u_Texture", 0);
std::dynamic_pointer_cast<Hazel::OpenGLShader>(textureShader)->Bind();
std::dynamic_pointer_cast<Hazel::OpenGLShader>(textureShader)->UploadUniformInt("u_Texture", 0);
}

void OnUpdate(Hazel::Timestep ts) override
@@ -177,11 +177,12 @@ class ExampleLayer : public Hazel::Layer
}
}

auto textureShader = m_ShaderLibrary.Get("Texture");

m_Texture->Bind();
Hazel::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
Hazel::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
m_ChernoLogoTexture->Bind();
Hazel::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));

Hazel::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));

// Triangle
// Hazel::Renderer::Submit(m_Shader, m_VertexArray);
@@ -200,10 +201,11 @@ class ExampleLayer : public Hazel::Layer
{
}
private:
Hazel::ShaderLibrary m_ShaderLibrary;
Hazel::Ref<Hazel::Shader> m_Shader;
Hazel::Ref<Hazel::VertexArray> m_VertexArray;

Hazel::Ref<Hazel::Shader> m_FlatColorShader, m_TextureShader;
Hazel::Ref<Hazel::Shader> m_FlatColorShader;
Hazel::Ref<Hazel::VertexArray> m_SquareVA;

Hazel::Ref<Hazel::Texture2D> m_Texture, m_ChernoLogoTexture;

0 comments on commit b576fd9

Please sign in to comment.
You can’t perform that action at this time.