Riyyi
5 years ago
4 changed files with 202 additions and 0 deletions
@ -0,0 +1,10 @@
|
||||
#version 450 core |
||||
|
||||
layout(location = 0) out vec4 color; |
||||
|
||||
in vec3 position; |
||||
|
||||
void main() |
||||
{ |
||||
color = vec4(position * 0.5f + 0.5f, 1.0f); |
||||
} |
@ -0,0 +1,11 @@
|
||||
#version 450 core |
||||
|
||||
layout(location = 0) in vec3 a_position; |
||||
|
||||
out vec3 position; |
||||
|
||||
void main() |
||||
{ |
||||
position = a_position; |
||||
gl_Position = vec4(a_position, 1.0f); |
||||
} |
@ -0,0 +1,140 @@
|
||||
#include <vector> // std::vector |
||||
|
||||
#include <glad/glad.h> |
||||
|
||||
#include "inferno/core.h" |
||||
#include "inferno/file.h" |
||||
#include "inferno/log.h" |
||||
#include "inferno/render/shader.h" |
||||
|
||||
namespace Inferno { |
||||
|
||||
Shader::Shader(const std::string &vertexSource, const std::string &fragmentSource) : |
||||
m_program(0) |
||||
{ |
||||
// Get file contents
|
||||
std::string vertexSrc = File::read(vertexSource); |
||||
std::string fragmentSrc = File::read(fragmentSource); |
||||
|
||||
// Compile shaders
|
||||
uint32_t vertexID = compileShader(GL_VERTEX_SHADER, vertexSrc.c_str()); |
||||
uint32_t fragmentID = compileShader(GL_FRAGMENT_SHADER, fragmentSrc.c_str()); |
||||
|
||||
// Link shaders
|
||||
if (vertexID > 0 && fragmentID > 0) { |
||||
m_program = linkShader(vertexID, fragmentID); |
||||
} |
||||
// Clear resources
|
||||
else if (vertexID > 0) glDeleteShader(vertexID); |
||||
else if (fragmentID > 0) glDeleteShader(fragmentID); |
||||
} |
||||
|
||||
Shader::~Shader() |
||||
{ |
||||
if (m_program > 0) { |
||||
glDeleteProgram(m_program); |
||||
m_program = 0; |
||||
} |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void Shader::bind() const |
||||
{ |
||||
glUseProgram(m_program); |
||||
} |
||||
|
||||
void Shader::unbind() const |
||||
{ |
||||
glUseProgram(0); |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
uint32_t Shader::getProgram() const |
||||
{ |
||||
return m_program; |
||||
} |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
uint32_t Shader::compileShader(int32_t type, const char* source) const |
||||
{ |
||||
// Create new shader
|
||||
uint32_t shader = 0; |
||||
shader = glCreateShader(type); |
||||
// Attach shader source to shader object
|
||||
glShaderSource(shader, 1, &source, nullptr); |
||||
// Compile shader
|
||||
glCompileShader(shader); |
||||
|
||||
// Check compilation status
|
||||
if (checkStatus(shader) == GL_TRUE) { |
||||
return shader; |
||||
} |
||||
|
||||
// On fail
|
||||
glDeleteShader(shader); |
||||
return 0; |
||||
} |
||||
|
||||
uint32_t Shader::linkShader(uint32_t vertex, uint32_t fragment) const |
||||
{ |
||||
// Create new shader program
|
||||
uint32_t shaderProgram = 0; |
||||
shaderProgram = glCreateProgram(); |
||||
// Attach both shaders to the shader program
|
||||
glAttachShader(shaderProgram, vertex); |
||||
glAttachShader(shaderProgram, fragment); |
||||
// Setup vertex attributes
|
||||
glBindAttribLocation(shaderProgram, 0, "a_position"); |
||||
// Link the shaders
|
||||
glLinkProgram(shaderProgram); |
||||
// Clear resources
|
||||
glDeleteShader(vertex); |
||||
glDeleteShader(fragment); |
||||
|
||||
// Check linking status
|
||||
if (checkStatus(shaderProgram, true) == GL_TRUE) { |
||||
return shaderProgram; |
||||
} |
||||
|
||||
// On fail
|
||||
glDeleteProgram(shaderProgram); |
||||
return 0; |
||||
} |
||||
|
||||
int32_t Shader::checkStatus(uint32_t check, bool isProgram) const |
||||
{ |
||||
int32_t success; |
||||
int32_t maxLength = 0; |
||||
std::vector<char> infoLog; |
||||
|
||||
// Get the compilation/linking status
|
||||
!isProgram |
||||
? glGetShaderiv(check, GL_COMPILE_STATUS, &success) |
||||
: glGetProgramiv(check, GL_LINK_STATUS, &success); |
||||
|
||||
if (success != GL_TRUE) { |
||||
// Get max length of the log including \0 terminator
|
||||
!isProgram |
||||
? glGetShaderiv(check, GL_INFO_LOG_LENGTH, &maxLength) |
||||
: glGetProgramiv(check, GL_INFO_LOG_LENGTH, &maxLength); |
||||
|
||||
// Reserve data for the log
|
||||
infoLog.reserve(maxLength); |
||||
|
||||
// Retrieve the error message
|
||||
!isProgram |
||||
? glGetShaderInfoLog(check, maxLength, nullptr, &infoLog[0]) |
||||
: glGetProgramInfoLog(check, maxLength, nullptr, &infoLog[0]); |
||||
|
||||
NF_CORE_WARN("Shader %s", infoLog.data()); |
||||
} |
||||
|
||||
NF_CORE_ASSERT(success == GL_TRUE, "Shader program creation failed!") |
||||
|
||||
return success; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,41 @@
|
||||
#ifndef SHADER_H |
||||
#define SHADER_H |
||||
|
||||
#define INFO_LOG_SIZE 512 |
||||
|
||||
#include <cstdint> // std::int32_t, std::uint32_t |
||||
#include <string> // std::string |
||||
|
||||
#include <glm/glm.hpp> |
||||
|
||||
namespace Inferno { |
||||
|
||||
class Shader { |
||||
public: |
||||
Shader(const std::string &vertexSource, const std::string &fragmentSource); |
||||
~Shader(); |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
void bind() const; |
||||
void unbind() const; |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
uint32_t getProgram() const; |
||||
|
||||
// -----------------------------------------
|
||||
|
||||
protected: |
||||
uint32_t compileShader(int32_t type, const char* shaderSource) const; |
||||
uint32_t linkShader(uint32_t vertex, uint32_t fragment) const; |
||||
int32_t checkStatus(uint32_t check, bool isProgram = false) const; |
||||
|
||||
private: |
||||
uint32_t m_program; |
||||
}; |
||||
|
||||
} |
||||
|
||||
|
||||
#endif // SHADER_H
|
Loading…
Reference in new issue