Add basic Shader class
This commit is contained in:
parent
579d8c3b1a
commit
1c4587cd35
155
src/main.cc
155
src/main.cc
@ -39,7 +39,18 @@ enum exit_codes : int {
|
|||||||
EXIT_CODE_GLAD_LOADER_FAILED,
|
EXIT_CODE_GLAD_LOADER_FAILED,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string load_shader(const std::string &filepath);
|
class Shader {
|
||||||
|
public:
|
||||||
|
Shader(const std::string &vert_file, const std::string &frag_file);
|
||||||
|
~Shader();
|
||||||
|
void activate();
|
||||||
|
private:
|
||||||
|
GLuint program;
|
||||||
|
void link_program(GLuint vert, GLuint frag);
|
||||||
|
GLuint load_and_compile_shader(const std::string &filepath, GLenum shader_type);
|
||||||
|
std::string load_shader_from_file(const std::string &filepath);
|
||||||
|
static const char *get_shader_type_string(GLenum shader_type);
|
||||||
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
@ -105,52 +116,7 @@ int main() {
|
|||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
glDisableVertexAttribArray(1);
|
glDisableVertexAttribArray(1);
|
||||||
|
|
||||||
std::string vs_shader = load_shader("shaders/vert.glsl");
|
Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"};
|
||||||
const char *vs_source = vs_shader.c_str();
|
|
||||||
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vs, 1, &vs_source, NULL);
|
|
||||||
glCompileShader(vs);
|
|
||||||
GLint vs_compiled;
|
|
||||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &vs_compiled);
|
|
||||||
if (vs_compiled != GL_TRUE)
|
|
||||||
{
|
|
||||||
GLsizei log_length = 0;
|
|
||||||
GLchar message[1024];
|
|
||||||
glGetShaderInfoLog(vs, 1024, &log_length, message);
|
|
||||||
printf("Failed to compile vertex shader: %s\n", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fs_shader = load_shader("shaders/frag.glsl");
|
|
||||||
const char *fs_source = fs_shader.c_str();
|
|
||||||
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(fs, 1, &fs_source, NULL);
|
|
||||||
glCompileShader(fs);
|
|
||||||
GLint fs_compiled;
|
|
||||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &fs_compiled);
|
|
||||||
if (fs_compiled != GL_TRUE)
|
|
||||||
{
|
|
||||||
GLsizei log_length = 0;
|
|
||||||
GLchar message[1024];
|
|
||||||
glGetShaderInfoLog(fs, 1024, &log_length, message);
|
|
||||||
printf("Failed to compile fragment shader: %s\n", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
|
||||||
glAttachShader(program, vs);
|
|
||||||
glAttachShader(program, fs);
|
|
||||||
glLinkProgram(program);
|
|
||||||
GLint program_linked;
|
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &program_linked);
|
|
||||||
if (program_linked != GL_TRUE)
|
|
||||||
{
|
|
||||||
GLsizei log_length = 0;
|
|
||||||
GLchar message[1024];
|
|
||||||
glGetProgramInfoLog(program, 1024, &log_length, message);
|
|
||||||
printf("Failed to link program: %s\n", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDeleteShader(vs);
|
|
||||||
glDeleteShader(fs);
|
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
SDL_Event event = {};
|
SDL_Event event = {};
|
||||||
@ -182,7 +148,7 @@ int main() {
|
|||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(program);
|
main_shader.activate();
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL);
|
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL);
|
||||||
|
|
||||||
@ -196,7 +162,68 @@ int main() {
|
|||||||
return EXIT_CODE_SUCCESS;
|
return EXIT_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string load_shader(const std::string &filepath) {
|
|
||||||
|
Shader::Shader(const std::string &vert_file, const std::string &frag_file) {
|
||||||
|
GLuint vert = load_and_compile_shader(vert_file, GL_VERTEX_SHADER);
|
||||||
|
GLuint frag = load_and_compile_shader(frag_file, GL_FRAGMENT_SHADER);
|
||||||
|
link_program(vert, frag);
|
||||||
|
glDeleteShader(vert);
|
||||||
|
glDeleteShader(frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader() {
|
||||||
|
if (program > 0) {
|
||||||
|
glDeleteProgram(program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::activate() {
|
||||||
|
if (program > 0) {
|
||||||
|
glUseProgram(program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::link_program(GLuint vert, GLuint frag) {
|
||||||
|
program = glCreateProgram();
|
||||||
|
glAttachShader(program, vert);
|
||||||
|
glAttachShader(program, frag);
|
||||||
|
|
||||||
|
glLinkProgram(program);
|
||||||
|
GLint program_linked;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &program_linked);
|
||||||
|
if (program_linked != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetProgramInfoLog(program, 1024, &log_length, message);
|
||||||
|
printf("Failed to link program: %s\n", message);
|
||||||
|
program = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Shader::load_and_compile_shader(const std::string &filepath, GLenum shader_type) {
|
||||||
|
std::string src = load_shader_from_file(filepath);
|
||||||
|
const char *shader_src = src.c_str();
|
||||||
|
|
||||||
|
GLuint shader = glCreateShader(shader_type);
|
||||||
|
glShaderSource(shader, 1, &shader_src, NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint shader_compiled;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_compiled);
|
||||||
|
if (shader_compiled != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetShaderInfoLog(shader, 1024, &log_length, message);
|
||||||
|
printf("Failed to compile %s shader: %s\n", get_shader_type_string(shader_type), message);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Shader::load_shader_from_file(const std::string &filepath) {
|
||||||
FILE *fp = fopen(filepath.c_str(), "r");
|
FILE *fp = fopen(filepath.c_str(), "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
return "";
|
return "";
|
||||||
@ -211,3 +238,33 @@ std::string load_shader(const std::string &filepath) {
|
|||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *Shader::get_shader_type_string(GLenum shader_type) {
|
||||||
|
const char *output;
|
||||||
|
|
||||||
|
switch (shader_type) {
|
||||||
|
case GL_COMPUTE_SHADER:
|
||||||
|
output = "compute";
|
||||||
|
break;
|
||||||
|
case GL_VERTEX_SHADER:
|
||||||
|
output = "vertex";
|
||||||
|
break;
|
||||||
|
case GL_TESS_CONTROL_SHADER:
|
||||||
|
output = "tess_control";
|
||||||
|
break;
|
||||||
|
case GL_TESS_EVALUATION_SHADER:
|
||||||
|
output = "tess_evaluation";
|
||||||
|
break;
|
||||||
|
case GL_GEOMETRY_SHADER:
|
||||||
|
output = "geometry";
|
||||||
|
break;
|
||||||
|
case GL_FRAGMENT_SHADER:
|
||||||
|
output = "fragment";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output = "UNKNOWN";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user