Shader abstraction
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,3 @@
|
|||||||
Renderer.cpp
|
Main.cpp
|
||||||
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
|
C:\dev\Glfw_Practice\c++\Window_practice\Window_practice\src\VertexBufferLayout.h(5,10): warning C4067: unexpected tokens following preprocessor directive - expected a newline
|
||||||
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
|
|
||||||
glew32s.lib(glew.obj) : warning LNK4099: PDB 'vc120.pdb' was not found with 'glew32s.lib(glew.obj)' or at 'C:\dev\Glfw_Practice\c++\Window_practice\Debug\vc120.pdb'; linking object as if no debug info
|
|
||||||
Window_practice.vcxproj -> C:\dev\Glfw_Practice\c++\Window_practice\Debug\Window_practice.exe
|
Window_practice.vcxproj -> C:\dev\Glfw_Practice\c++\Window_practice\Debug\Window_practice.exe
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -148,6 +148,7 @@
|
|||||||
<ClCompile Include="src\IndexBuffer.cpp" />
|
<ClCompile Include="src\IndexBuffer.cpp" />
|
||||||
<ClCompile Include="src\Main.cpp" />
|
<ClCompile Include="src\Main.cpp" />
|
||||||
<ClCompile Include="src\Renderer.cpp" />
|
<ClCompile Include="src\Renderer.cpp" />
|
||||||
|
<ClCompile Include="src\Shader.cpp" />
|
||||||
<ClCompile Include="src\VertexArray.cpp" />
|
<ClCompile Include="src\VertexArray.cpp" />
|
||||||
<ClCompile Include="src\VertexBuffer.cpp" />
|
<ClCompile Include="src\VertexBuffer.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -155,6 +156,7 @@
|
|||||||
<ClInclude Include="src\IndexBuffer.h" />
|
<ClInclude Include="src\IndexBuffer.h" />
|
||||||
<ClInclude Include="src\Main.h" />
|
<ClInclude Include="src\Main.h" />
|
||||||
<ClInclude Include="src\Renderer.h" />
|
<ClInclude Include="src\Renderer.h" />
|
||||||
|
<ClInclude Include="src\Shader.h" />
|
||||||
<ClInclude Include="src\VertexArray.h" />
|
<ClInclude Include="src\VertexArray.h" />
|
||||||
<ClInclude Include="src\VertexBuffer.h" />
|
<ClInclude Include="src\VertexBuffer.h" />
|
||||||
<ClInclude Include="src\VertexBufferLayout.h" />
|
<ClInclude Include="src\VertexBufferLayout.h" />
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
<ClCompile Include="src\VertexArray.cpp">
|
<ClCompile Include="src\VertexArray.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Shader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\Main.h">
|
<ClInclude Include="src\Main.h">
|
||||||
@@ -50,6 +53,9 @@
|
|||||||
<ClInclude Include="src\VertexBufferLayout.h">
|
<ClInclude Include="src\VertexBufferLayout.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\Shader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="res\shaders\Basic.shader" />
|
<None Include="res\shaders\Basic.shader" />
|
||||||
|
|||||||
@@ -2,93 +2,12 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "VertexBuffer.h"
|
#include "VertexBuffer.h"
|
||||||
#include "IndexBuffer.h"
|
#include "IndexBuffer.h"
|
||||||
#include "VertexArray.h"
|
#include "VertexArray.h"
|
||||||
|
#include "Shader.h"
|
||||||
struct ShaderProgramSource {
|
|
||||||
std::string VertexSource;
|
|
||||||
std::string FragmentSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
//For reading in the shader from file
|
|
||||||
static ShaderProgramSource ParseShader(const std::string& filepath) {
|
|
||||||
std::ifstream stream(filepath);
|
|
||||||
|
|
||||||
enum class ShaderType {
|
|
||||||
NONE = -1, VERTEX = 0, FRAGMENT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
std::stringstream ss[2]; //one is the vertex other is the fragment shader
|
|
||||||
ShaderType type = ShaderType::NONE;
|
|
||||||
|
|
||||||
while (getline(stream, line)) {
|
|
||||||
if (line.find("#shader") != std::string::npos) {
|
|
||||||
if (line.find("vertex") != std::string::npos) {
|
|
||||||
//set mode to vertex
|
|
||||||
type = ShaderType::VERTEX;
|
|
||||||
}
|
|
||||||
else if (line.find("fragment") != std::string::npos) {
|
|
||||||
//set mode to fragment
|
|
||||||
type = ShaderType::FRAGMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ss[(int)type] << line << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { ss[0].str(), ss[1].str() };
|
|
||||||
}
|
|
||||||
|
|
||||||
//Shader compiler
|
|
||||||
static unsigned int CompileShader(unsigned int type, const std::string& source) {
|
|
||||||
unsigned int id = glCreateShader(type);
|
|
||||||
const char* src = source.c_str();
|
|
||||||
glShaderSource(id, 1, &src, nullptr);
|
|
||||||
glCompileShader(id);
|
|
||||||
|
|
||||||
//Error handling
|
|
||||||
int result;
|
|
||||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
|
||||||
|
|
||||||
if (result == GL_FALSE) {
|
|
||||||
int length;
|
|
||||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
|
||||||
char* message = (char*)_malloca(length * sizeof(char)); //_malloca is more secure than alloca
|
|
||||||
glGetShaderInfoLog(id, length, &length, message);
|
|
||||||
|
|
||||||
std::cout << "Failed to compile " <<
|
|
||||||
(type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader" << std::endl;
|
|
||||||
std::cout << message << std::endl;
|
|
||||||
|
|
||||||
glDeleteShader(id);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int 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);
|
|
||||||
|
|
||||||
GLCall(glAttachShader(program, vs));
|
|
||||||
GLCall(glAttachShader(program, fs));
|
|
||||||
GLCall(glLinkProgram(program));
|
|
||||||
GLCall(glValidateProgram(program));
|
|
||||||
GLCall(glDeleteShader(vs));
|
|
||||||
GLCall(glDeleteShader(fs));
|
|
||||||
|
|
||||||
return program;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void){
|
int main(void){
|
||||||
// GLFW init
|
// GLFW init
|
||||||
@@ -147,23 +66,15 @@ int main(void){
|
|||||||
va.AddBuffer(vb, layout);
|
va.AddBuffer(vb, layout);
|
||||||
IndexBuffer ib(indecies, 6);
|
IndexBuffer ib(indecies, 6);
|
||||||
|
|
||||||
ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
|
Shader shader("res/shaders/Basic.shader");
|
||||||
|
shader.Bind();
|
||||||
//Creating the shader
|
shader.SetUniform4f("u_Color", 0.8f, 0.3f, 0.8f, 1.0f);
|
||||||
unsigned int shader = CreateShader(source.VertexSource, source.FragmentSource);
|
|
||||||
glUseProgram(shader);
|
|
||||||
|
|
||||||
//Shader Uniform
|
|
||||||
//need to bound a shader before this
|
|
||||||
GLCall(int location = glGetUniformLocation(shader, "u_Color")); //finding u_Color location
|
|
||||||
ASSERT(location != -1);
|
|
||||||
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));
|
|
||||||
|
|
||||||
//unbinding the buffers
|
//unbinding the buffers
|
||||||
GLCall(glBindVertexArray(0));
|
va.Unbind();
|
||||||
GLCall(glUseProgram(0));
|
vb.Unbind();
|
||||||
GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
|
ib.Unbind();
|
||||||
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
shader.Unbind();
|
||||||
|
|
||||||
//for animation
|
//for animation
|
||||||
float r = 0.0f;
|
float r = 0.0f;
|
||||||
@@ -174,8 +85,8 @@ int main(void){
|
|||||||
/* Render here */
|
/* Render here */
|
||||||
GLCall(glClear(GL_COLOR_BUFFER_BIT));
|
GLCall(glClear(GL_COLOR_BUFFER_BIT));
|
||||||
|
|
||||||
GLCall(glUseProgram(shader));
|
shader.Bind();
|
||||||
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
|
shader.SetUniform4f("u_Color", r, 0.3f, 0.8f, 1.0f);
|
||||||
|
|
||||||
va.Bind();
|
va.Bind();
|
||||||
ib.Bind();
|
ib.Bind();
|
||||||
@@ -195,9 +106,8 @@ int main(void){
|
|||||||
/* Poll for and process events */
|
/* Poll for and process events */
|
||||||
GLCall(glfwPollEvents());
|
GLCall(glfwPollEvents());
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCall(glDeleteProgram(shader));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
122
Window_practice/src/Shader.cpp
Normal file
122
Window_practice/src/Shader.cpp
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
#include "Shader.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
Shader::Shader(const std::string& filepath)
|
||||||
|
:m_FilePath(filepath), m_RendererID(0)
|
||||||
|
{
|
||||||
|
ShaderProgramSource source = ParseShader(filepath);
|
||||||
|
m_RendererID = CreateShader(source.VertexSource, source.FragmentSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader()
|
||||||
|
{
|
||||||
|
GLCall(glDeleteProgram(m_RendererID));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
GLCall(glAttachShader(program, vs));
|
||||||
|
GLCall(glAttachShader(program, fs));
|
||||||
|
GLCall(glLinkProgram(program));
|
||||||
|
GLCall(glValidateProgram(program));
|
||||||
|
GLCall(glDeleteShader(vs));
|
||||||
|
GLCall(glDeleteShader(fs));
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Shader::CompileShader(unsigned int type, const std::string& source) {
|
||||||
|
unsigned int id = glCreateShader(type);
|
||||||
|
const char* src = source.c_str();
|
||||||
|
glShaderSource(id, 1, &src, nullptr);
|
||||||
|
glCompileShader(id);
|
||||||
|
|
||||||
|
//Error handling
|
||||||
|
int result;
|
||||||
|
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||||
|
|
||||||
|
if (result == GL_FALSE) {
|
||||||
|
int length;
|
||||||
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
||||||
|
char* message = (char*)_malloca(length * sizeof(char)); //_malloca is more secure than alloca
|
||||||
|
glGetShaderInfoLog(id, length, &length, message);
|
||||||
|
|
||||||
|
std::cout << "Failed to compile " <<
|
||||||
|
(type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader" << std::endl;
|
||||||
|
std::cout << message << std::endl;
|
||||||
|
|
||||||
|
glDeleteShader(id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//For reading in the shader from file
|
||||||
|
ShaderProgramSource Shader::ParseShader(const std::string& filepath) {
|
||||||
|
std::ifstream stream(filepath);
|
||||||
|
|
||||||
|
enum class ShaderType {
|
||||||
|
NONE = -1, VERTEX = 0, FRAGMENT = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
std::stringstream ss[2]; //one is the vertex other is the fragment shader
|
||||||
|
ShaderType type = ShaderType::NONE;
|
||||||
|
|
||||||
|
while (getline(stream, line)) {
|
||||||
|
if (line.find("#shader") != std::string::npos) {
|
||||||
|
if (line.find("vertex") != std::string::npos) {
|
||||||
|
//set mode to vertex
|
||||||
|
type = ShaderType::VERTEX;
|
||||||
|
}
|
||||||
|
else if (line.find("fragment") != std::string::npos) {
|
||||||
|
//set mode to fragment
|
||||||
|
type = ShaderType::FRAGMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ss[(int)type] << line << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ss[0].str(), ss[1].str() };
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::Bind() const
|
||||||
|
{
|
||||||
|
GLCall(glUseProgram(m_RendererID));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::Unbind() const
|
||||||
|
{
|
||||||
|
GLCall(glUseProgram(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3)
|
||||||
|
{
|
||||||
|
GLCall(glUniform4f(GetUniformLocation(name), v0, v1, v2, v3));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Shader::GetUniformLocation(const std::string& name)
|
||||||
|
{
|
||||||
|
if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
|
||||||
|
return m_UniformLocationCache[name];
|
||||||
|
|
||||||
|
GLCall(unsigned int location = glGetUniformLocation(m_RendererID, name.c_str()));
|
||||||
|
if (location == -1)
|
||||||
|
std::cout << "Warning: uniform '" << name << "' does not exist!" << std::endl;
|
||||||
|
|
||||||
|
m_UniformLocationCache[name] = location;
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
30
Window_practice/src/Shader.h
Normal file
30
Window_practice/src/Shader.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
struct ShaderProgramSource {
|
||||||
|
std::string VertexSource;
|
||||||
|
std::string FragmentSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
private:
|
||||||
|
std::string m_FilePath;
|
||||||
|
unsigned int m_RendererID;
|
||||||
|
std::unordered_map<std::string, unsigned int> m_UniformLocationCache;
|
||||||
|
public:
|
||||||
|
Shader(const std::string& filepath);
|
||||||
|
~Shader();
|
||||||
|
|
||||||
|
void Bind() const;
|
||||||
|
void Unbind() const;
|
||||||
|
|
||||||
|
//Set uniform
|
||||||
|
void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
|
||||||
|
private:
|
||||||
|
ShaderProgramSource ParseShader(const std::string& filepath);
|
||||||
|
unsigned int CompileShader(unsigned int type, const std::string& source);
|
||||||
|
unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader);
|
||||||
|
unsigned int GetUniformLocation(const std::string& name);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user