commit 8c00582f63ca3ceadb30223d73b89d3666265fe7
parent 9abd4e462aeb3c2e6cbf6270f29ba8baef016e54
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Thu, 1 Aug 2024 11:35:27 -0300
factored out functions from `main`
Diffstat:
M | main.c | | | 207 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
M | main.frag | | | 4 | ++-- |
2 files changed, 121 insertions(+), 90 deletions(-)
diff --git a/main.c b/main.c
@@ -2,35 +2,22 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <stdbool.h>
#include "glad.h"
#include <GLFW/glfw3.h>
#define WINDOW_TITLE "OpenGL Example"
-#define LOG_INFO(str) do { \
- printf("[LOG]: %s\n", str); \
+#define LOG_INFO(str) do { \
+ printf("[LOG]: %s\n", str); \
} while (0)
-#define LOG_ERROR(str) do { \
- fprintf(stderr, "[ERROR]: %s\n", str); \
+#define LOG_ERROR(str) do { \
+ fprintf(stderr, "[ERROR]: "); \
+ fprintf(stderr, "%s\n", str); \
} while (0)
-static void key_handler(GLFWwindow *window,
- int key, int scancode, int action, int mods) {
-
- if(action == GLFW_PRESS) {
- switch(key) {
- case GLFW_KEY_ESCAPE:
- case GLFW_KEY_Q:
- glfwSetWindowShouldClose(window, GLFW_TRUE);
- break;
- default:
- break;
- }
- }
-}
-
float min(float a, float b) {
return (a < b) ? a : b;
}
@@ -74,36 +61,130 @@ char *load_file(const char *file_path) {
return new_str;
}
-int main (void) {
+bool new_shader_from_file_path(GLenum type, GLuint *shader, const char *file_path) {
+ const char *shader_source = load_file(file_path);
+
+ if(shader_source == NULL) {
+ return false;
+ }
+
+ *shader = glCreateShader(type);
+
+ int return_value;
+ char compile_log[512];
+
+ glShaderSource(*shader, 1, &shader_source, NULL);
+ LOG_INFO("Compiling shader");
+ glCompileShader(*shader);
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &return_value);
+ if(return_value == GL_FALSE) {
+ glGetShaderInfoLog(*shader, 512, NULL, compile_log);
+ *shader = 0;
+ LOG_ERROR("Compilation of shader failed");
+ // LOG_ERROR(strstr(compile_log, "error:") + 7);
+ fprintf(stderr, "%s", compile_log);
+ return false;
+ }
+
+ return true;
+}
+
+
+bool new_program_from_shaders(GLuint *shader_program,
+ GLuint *vertex_shader, GLuint *fragment_shader) {
+
+ int return_value;
+ char link_log[512];
+
+ // link both vertex and fragment shaders
+ *shader_program = glCreateProgram();
+
+ glAttachShader(*shader_program, *vertex_shader);
+ glAttachShader(*shader_program, *fragment_shader);
+ LOG_INFO("Linking `vertex_shader` and `fragment_shader`");
+ glLinkProgram(*shader_program);
+ glGetProgramiv(*shader_program, GL_LINK_STATUS, &return_value);
+ if(return_value == GL_FALSE) {
+ glGetProgramInfoLog(*shader_program, 512, NULL, link_log);
+ LOG_ERROR("Linking `vertex_shader` and `fragment_shader` failed");
+ LOG_ERROR(link_log + 7); // remove the `error: ` prefix of message
+ }
+}
+
+bool new_program_from_shaders_source(GLuint *shader_program,
+ const char *vert_shader_file_path, const char *frag_shader_file_path) {
+
+ GLuint vertex_shader, fragment_shader;
+
+ if(!new_shader_from_file_path(GL_VERTEX_SHADER,
+ &vertex_shader, vert_shader_file_path)) {
+
+ return false;
+ }
+
+ if(!new_shader_from_file_path(GL_FRAGMENT_SHADER,
+ &fragment_shader, frag_shader_file_path)) {
+
+ return false;
+ }
+
+ if(!new_program_from_shaders(shader_program, &vertex_shader, &fragment_shader)) {
+ return false;
+ }
+
+ // program with shaders compiled and linked properly
+ return true;
+}
+
+// https://www.glfw.org/docs/3.3/group__keys.html
+static void key_handler(GLFWwindow *window,
+ int key, int scancode, int action, int mods) {
+
+ if(action == GLFW_PRESS) {
+ switch(key) {
+ case GLFW_KEY_ESCAPE:
+ case GLFW_KEY_Q:
+ glfwSetWindowShouldClose(window, GLFW_TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+bool setup_glfw(GLFWwindow **window) {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- GLFWwindow *window = glfwCreateWindow(800, 800, WINDOW_TITLE, NULL, NULL);
- if (window == NULL) {
+ *window = glfwCreateWindow(800, 800, WINDOW_TITLE, NULL, NULL);
+ if (*window == NULL) {
LOG_ERROR("Failed to create GLFW window");
glfwTerminate();
- return -1;
+ return false;
}
- glfwMakeContextCurrent(window);
+ glfwMakeContextCurrent(*window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
LOG_ERROR("Failed to initialize GLAD");
glfwTerminate();
- return -1;
+ return false;
}
// bind key_hadler
- glfwSetKeyCallback(window, key_handler);
+ glfwSetKeyCallback(*window, key_handler);
// bind the callback whiech sets the rendering context size on window resize
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+ glfwSetFramebufferSizeCallback(*window, framebuffer_size_callback);
+ return true;
+}
- const char *vertex_shader_source, *fragment_shader_source;
- unsigned int vertex_shader, fragment_shader, shader_program;
- int return_value;
- char infoLog[512];
+int main (void) {
+ GLuint shader_program;
+ GLuint VBO, VAO; // Vertex Buffer Objects, Vertex Array Object
+ GLFWwindow *window;
float vertices[] = {
-0.50f, -0.400f, 0.00f,
@@ -111,7 +192,8 @@ int main (void) {
0.00f, 0.466f, 0.00f
};
- unsigned int VBO, VAO; // Vertex Buffer Objects, Vertex Array Object
+ setup_glfw(&window);
+
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
@@ -119,63 +201,12 @@ int main (void) {
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
- // fragment shader load and compile
- vertex_shader_source = load_file("main.vert");
- if(vertex_shader_source == NULL) {
- return -1;
- }
-
- // puts(vertex_shader_source);
-
- vertex_shader = glCreateShader(GL_VERTEX_SHADER);
-
- glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
- LOG_INFO("Compiling `vertex_shader`");
- glCompileShader(vertex_shader);
-
- glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &return_value);
-
- if(return_value == GL_FALSE) {
- glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
- LOG_ERROR("Compilation of `vertex_shader` failed");
- LOG_ERROR(infoLog);
- }
-
- // fragment shader load and compile
- fragment_shader_source = load_file("main.frag");
- if(fragment_shader_source == NULL) {
+ if(!new_program_from_shaders_source(&shader_program, "main.vert", "main.frag")) {
+ glfwDestroyWindow(window);
+ glfwTerminate();
return -1;
}
- // puts(fragment_shader_source);
-
- fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
-
- glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
- LOG_INFO("Compiling `fragment_shader`");
- glCompileShader(fragment_shader);
- glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &return_value);
- if(return_value == GL_FALSE) {
- glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog);
- LOG_ERROR("Compilation of `fragment_shader` failed");
- LOG_ERROR(infoLog);
- }
-
- // link both vertex and fragment shaders
- shader_program = glCreateProgram();
-
- glAttachShader(shader_program, vertex_shader);
- glAttachShader(shader_program, fragment_shader);
- LOG_INFO("Linking `vertex_shader` and `fragment_shader`");
- glLinkProgram(shader_program);
-
- glGetProgramiv(shader_program, GL_LINK_STATUS, &return_value);
- if(return_value == GL_FALSE) {
- glGetProgramInfoLog(shader_program, 512, NULL, infoLog);
- LOG_ERROR("Linking `vertex_shader` and `fragment_shader` failed");
- LOG_ERROR(infoLog + 7); // remove the `error: ` prefix of message
- }
-
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glUseProgram(shader_program);
@@ -189,8 +220,8 @@ int main (void) {
glfwPollEvents();
}
- glDeleteShader(vertex_shader);
- glDeleteShader(fragment_shader);
+ LOG_INFO("Freeing resources");
+ glDeleteProgram(shader_program);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
diff --git a/main.frag b/main.frag
@@ -1,7 +1,7 @@
#version 330 core
-out vec4 FragColor;
+// out vec4 fragColor;
void main() {
- FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+ gl_FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}