Abstracting shaders

This commit is contained in:
Vitor Fernandes 2020-06-21 21:46:07 +01:00
parent 7b1268d4a4
commit a42eabd694
No known key found for this signature in database
GPG key ID: EBFB4EE09F348A26
6 changed files with 201 additions and 111 deletions

View file

@ -4,12 +4,15 @@ find_package(glfw3 3.3 REQUIRED)
#find_package(GLEW REQUIRED)
# Search for OpenGL
find_package(OpenGL REQUIRED)
add_compile_definitions(IS_DEBUG=1)
# Add gl1 executable build from gl1.cpp, glew.c and Renderer.cpp
add_executable(
gl1
gl1.cpp
Shader.cpp
Renderer.cpp
VertexBuffer.cpp
IndexBuffer.cpp
@ -17,6 +20,7 @@ add_executable(
glew.c
)
# Link gl1 with glew
#target_link_libraries(gl1 glew)
# Link gl1 with glfw lib

125
src/opengl/Shader.cpp Normal file
View file

@ -0,0 +1,125 @@
#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include "Shader.h"
#include "Renderer.h"
#include "utils.h"
Shader::Shader(const std::string &filepath)
: m_FilePath(filepath), m_RendererID(0)
{
//ShaderProgramSource source = ParseShader(m_FilePath);
//m_RendererID = CreateShader(source.VertexSource, source.FragmentSource);
}
Shader::~Shader()
{
}
void Shader::Bind()
{
}
void Shader::Unbind()
{
}
//Set uniforms
void Shader::SetUniform4f(const std::string &name, float v0, float v1, float v2, float v3)
{
}
unsigned int Shader::GetUniformLocation(const std::string &name)
{
}
/**
* Creates both shaders, links them and returns an identifier
*/
unsigned int Shader::CreateShader(const std::string &vertexShader, const std::string &fragmentShader)
{
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
unsigned int Shader::CompileShader(unsigned int type, const std::string &source)
{
unsigned int id = glCreateShader(type);
LOG("Shader ID: " << id);
const char *const src = source.c_str();
LOG("Source: " << std::endl
<< src << std::endl);
glShaderSource(id, 1, &src, nullptr);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
LOG("Length: " << length);
char *message = (char *)malloc(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
LOG("Failed to compile "
<< (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader: " << std::endl);
LOG(message);
free(message);
glDeleteProgram(id);
return 0;
}
return id;
}
ShaderProgramSource Shader::ParseShader(const std::string &path)
{
std::ifstream stream(path);
std::string line;
enum class ShaderType
{
NONE = -1,
VERTEX = 0,
FRAGMENT = 1
};
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != std::string::npos)
{
if (line.find("vertex") != std::string::npos)
{
//vertex
type = ShaderType::VERTEX;
}
else if (line.find("fragment") != std::string::npos)
{
//Fragment
type = ShaderType::FRAGMENT;
}
}
else
{
ss[(int)type] << line << '\n';
}
}
return {ss[0].str(), ss[1].str()};
}

33
src/opengl/Shader.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include <string>
struct ShaderProgramSource
{
std::string VertexSource;
std::string FragmentSource;
};
/**
* Class to abstrac shaders
*/
class Shader
{
private:
unsigned int m_RendererID;
std::string m_FilePath;
ShaderProgramSource ParseShader(const std::string &filepath);
unsigned int CreateShader(const std::string &vertexShader, const std::string &fragmentShader);
unsigned int CompileShader(unsigned int type, const std::string &source);
unsigned int GetUniformLocation(const std::string &name);
public:
Shader(const std::string &filepath);
~Shader();
void Bind();
void Unbind();
//Set uniforms
void SetUniform4f(const std::string &name, float v0, float v1, float v2, float v3);
};

View file

@ -1,4 +1,5 @@
#pragma once
#include <iostream>
class VertexBuffer
{
@ -11,5 +12,10 @@ public:
void Bind() const;
void Unbind() const;
//Overload to enable toString operations
friend std::ostream& operator<<(std::ostream &stream, VertexBuffer const &vb){
return stream << "[VertexBuffer rendererID=" << vb.m_RendererID;
}
};

View file

@ -4,131 +4,44 @@
#include <string>
#include <sstream>
#include <signal.h>
#include "Shader.h"
#include "Renderer.h"
#include "VertexBuffer.h"
#include "IndexBuffer.h"
#include "VertexArray.h"
#include "utils.h"
typedef unsigned int uint;
struct ShaderProgramSource
{
std::string VertexSource;
std::string FragmentSource;
};
const std::string SHADERS_PATH = "src/opengl/res/shaders/Basic.shader";
static ShaderProgramSource ParseShader(const std::string path)
{
std::ifstream stream(path);
std::string line;
enum class ShaderType
{
NONE = -1,
VERTEX = 0,
FRAGMENT = 1
};
std::stringstream ss[2];
ShaderType type = ShaderType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != std::string::npos)
{
if (line.find("vertex") != std::string::npos)
{
//vertex
type = ShaderType::VERTEX;
}
else if (line.find("fragment") != std::string::npos)
{
//Fragment
type = ShaderType::FRAGMENT;
}
}
else
{
ss[(int)type] << line << '\n';
}
}
return {ss[0].str(), ss[1].str()};
}
static uint CompileShader(uint type, const std::string &source)
{
uint id = glCreateShader(type);
std::cout << "Shader ID: " << id << std::endl;
const char *const src = source.c_str();
//std::cout << "Source: " << std::endl << src << std::endl << std::endl;
glShaderSource(id, 1, &src, nullptr);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
std::cout << "Length: " << length << std::endl;
char *message = (char *)malloc(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
std::cout << "Failed to compile "
<< (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader: " << std::endl;
std::cout << message << std::endl;
free(message);
glDeleteProgram(id);
return 0;
}
return id;
};
/**
* Creates both shaders, links them and returns an identifier
*/
static uint CreateShader(const std::string &vertexShader, const std::string &fragmentShader)
{
uint program = glCreateProgram();
uint vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
uint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
};
//const std::string SHADERS_PATH = "src/opengl/res/shaders/Basic.shader";
int main(void)
{
LOG("Start OpenGL Demo");
GLFWwindow *window;
//glDebugMessageCallback(ErrorGLCallback,0); Enable when glew installed properly
/* Initialize the library */
LOG("Initialize glfw");
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
LOG("Create Window");
window = glfwCreateWindow(640, 480, "OpenGL Window", NULL, NULL);
if (!window)
{
LOG("Terminate because not window");
glfwTerminate();
return -1;
}
/* Make the window's context current */
LOG("GLFW Make context");
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
//Print opengl version
std::cout << glGetString(GL_VERSION) << std::endl;
LOG("GL_VERSION: " << glGetString(GL_VERSION));
float positions[] =
{
@ -142,26 +55,26 @@ int main(void)
//Create buffer
//Buffer id
LOG("VertexArray defining");
VertexArray va;
LOG("VertexArray defined");
LOG("VertexBuffer to be created");
VertexBuffer vb(positions, 4 * 2 * sizeof(float));
//LOG("Create VertexBuffer: " << vb);
VertexBufferLayout layout;
layout.Push<float>(2);
va.AddBuffer(vb,layout);
IndexBuffer ib(indexes,6);
ShaderProgramSource source = ParseShader(SHADERS_PATH);
uint shader = CreateShader(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(shader));
//Find the shader uniform color
int uniform_location = glGetUniformLocation(shader, "u_color");
//int uniform_location = glGetUniformLocation(shader, "u_color");
if (uniform_location == -1)
{
std::cout << "Error fetching uniform location" << std::endl;
}
//if (uniform_location == -1) LOG("Error fetching uniform location");
float red = 0.0f;
float increment = 0.05f;
@ -183,13 +96,13 @@ int main(void)
//glDrawArrays(GL_TRIANGLES, 0, 12);
//GLClearError();
GLCall(glUseProgram(shader));
//GLCall(glUseProgram(shader));
GLCall(glUniform4f(uniform_location, 0.2f, 0.3f, 0.8f, 1.0f));
//GLCall(glUniform4f(uniform_location, 0.2f, 0.3f, 0.8f, 1.0f));
ib.Bind();
//ib.Bind();
GLCall(glDrawElements(GL_TRIANGLES, 6 * sizeof(uint), GL_UNSIGNED_INT, nullptr));
//GLCall(glDrawElements(GL_TRIANGLES, 6 * sizeof(uint), GL_UNSIGNED_INT, nullptr));
if (red > 1.0f)
increment = -0.05f;
@ -206,5 +119,6 @@ int main(void)
}
glfwTerminate();
return 0;
}

8
src/opengl/utils.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <iostream>
#if IS_DEBUG==1
#define LOG(x) std::cout << x << std::endl
#else
#define LOG(x)
#endif