From 4f871d12bc5ac161fa44441a773eff436956c254 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 16 Oct 2023 22:55:02 +0700 Subject: [PATCH] Finish Shaders with exercises --- Makefile | 4 +- lib.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++ main.c | 92 ++++++++----------------------------- shaders/main.frag | 11 +++++ shaders/main.vert | 12 +++++ 5 files changed, 159 insertions(+), 74 deletions(-) create mode 100644 lib.h create mode 100644 shaders/main.frag create mode 100644 shaders/main.vert diff --git a/Makefile b/Makefile index 0b15675..753818e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ P=opengl -OBJECTS= +OBJECTS=libs/glad/glad.o CFLAGS=-g -Wall -Wextra -O0 -LDLIBS=-lglfw -lOpenGL +LDLIBS=-lglfw -lOpenGL -lm INCLUDES=-I./libs/glad/include/ CC=gcc RM=rm -vf diff --git a/lib.h b/lib.h new file mode 100644 index 0000000..1dfff99 --- /dev/null +++ b/lib.h @@ -0,0 +1,114 @@ +#pragma once + +#include + +void checkCode(int code, char* errorMsg) { + if (code < 0) { + fprintf(stderr, "Application Error %i: %s\n", code, errorMsg); + exit(1); + } +} + +void* checkPtr(void *ptr, char* errorMsg) { + if (ptr == NULL) { + fprintf(stderr, "Application Error: %s\n", errorMsg); + exit(1); + } + return ptr; +} + +void checkShader(unsigned int shader, int statusFlag, char* actionName) { + int success; + glGetShaderiv(shader, statusFlag, &success); + if (success < 0) { + fprintf(stderr, "%s Error %i\n", actionName, success); + exit(1); + } +} + +char* loadText(char* path) { + char* buffer = NULL; + long length; + FILE* f = fopen(path, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + length = ftell(f); + fseek(f, 0, SEEK_SET); + buffer = calloc(length, sizeof(char)); + if (buffer) { + fread(buffer, 1, length, f); + } + fclose(f); + } + return buffer; +} + +void checkCompileErrors(unsigned int object, char* type) +{ + int success; + char infoLog[1024]; + if (strcmp("PROGRAM", type)) + { + glGetShaderiv(object, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(object, 1024, NULL, infoLog); + fprintf(stderr, "| ERROR::SHADER: Compile-time error: Type: %s \n %s\n", type, infoLog); + } + } + else + { + glGetProgramiv(object, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(object, 1024, NULL, infoLog); + fprintf(stderr, "| ERROR::Shader: Link-time error: Type: %s \n %s\n", type, infoLog); + } + } +} + +unsigned int compileShaderProgram(char* vertSrcPath, char* fragSrcPath, char* geoSrcPath) { + unsigned int vertShader, fragShader, geoShader; + + char* vertSrc = checkPtr(loadText(vertSrcPath), "Error loading source file"); + vertShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertShader, 1, (const GLchar* const*)&vertSrc, NULL); + glCompileShader(vertShader); + checkCompileErrors(vertShader, "VERTEX"); + + char* fragSrc = checkPtr(loadText(fragSrcPath), "Error loading source file"); + + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragShader, 1, (const GLchar* const*)&fragSrc, NULL); + glCompileShader(fragShader); + checkCompileErrors(fragShader, "FRAGMENT"); + + char* geoSrc = NULL; + if (geoSrcPath != NULL) { + geoSrc = checkPtr(loadText(geoSrcPath), "Error loading source file"); + geoShader = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(geoShader, 1, (const GLchar* const*)&geoSrc, NULL); + glCompileShader(geoShader); + checkCompileErrors(geoShader, "GEOMETRY"); + } + + unsigned int program = glCreateProgram(); + glAttachShader(program, vertShader); + glAttachShader(program, fragShader); + if (geoSrcPath != NULL) { + glAttachShader(program, geoShader); + } + + glLinkProgram(program); + checkCompileErrors(program, "PROGRAM"); + + glDeleteShader(vertShader); + glDeleteShader(fragShader); + free(vertSrc); + free(fragSrc); + if (geoSrc != NULL) { + free(geoSrc); + } + + return program; +} diff --git a/main.c b/main.c index 67b8698..410ed55 100644 --- a/main.c +++ b/main.c @@ -1,27 +1,14 @@ #include #include #include +#include #include "glad/glad.h" #include +#include "lib.h" int SCREEN_WIDTH = 1024; int SCREEN_HEIGHT = 768; -void checkCode(int code, char* errorMsg) { - if (code < 0) { - fprintf(stderr, "Application Error %i: %s\n", code, errorMsg); - exit(1); - } -} - -void* checkPtr(void *ptr, char* errorMsg) { - if (ptr == NULL) { - fprintf(stderr, "Application Error: %s\n", errorMsg); - exit(1); - } - return ptr; -} - void framebuffer_size_callback(GLFWwindow* window, int width, int height) { (void)window; @@ -36,46 +23,6 @@ void processInput(GLFWwindow *window) glfwSetWindowShouldClose(window, true); } -const char* vertSrc = - "#version 330 core\n" - "layout (location = 0) in vec3 aPos;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" - "}\n"; - -unsigned int compileVertShader() { - unsigned int vertexShader; - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vertSrc, NULL); - glCompileShader(vertexShader); - int success; - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); - checkCode(success, "Failed to compile vertex shader"); - return vertexShader; -} - -const char* fragSrc = - "#version 330 core\n" - "out vec4 FragColor;\n" - "\n" - "void main()\n" - "{\n" - " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" - "}\n"; - -unsigned int compileFragShader() { - unsigned int fragmentShader; - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fragSrc, NULL); - glCompileShader(fragmentShader); - int success; - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); - checkCode(success, "Failed to compile fragment shader"); - return fragmentShader; -} - int main(void) { glfwInit(); @@ -96,18 +43,8 @@ int main(void) { glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - unsigned int vertexShader = compileVertShader(); - unsigned int fragmentShader = compileFragShader(); - unsigned int shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - glLinkProgram(shaderProgram); - int success = 0; - glGetShaderiv(shaderProgram, GL_LINK_STATUS, &success); - checkCode(success, "Failed to link shader program"); - - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); + GLuint shaderProgram = + compileShaderProgram("shaders/main.vert", "shaders/main.frag", NULL); // float vertices[] = { // 0.5f, 0.5f, 0.0f, // top right @@ -127,9 +64,9 @@ int main(void) { // }; float v1[] = { - -1.0f, -0.5f, 0.0f, // -0.5, -0.5 - 0.0f, -0.5f, 0.0f,// 0.5, -0.5 - -0.5f, 0.5f, 0.0f// 0.0, 0.5 + -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, }; float v2[] = { @@ -140,7 +77,8 @@ int main(void) { GLuint vaos[2]; GLuint vbos[2]; - unsigned int VBO1, VBO2, EBO; + unsigned int VBO1, VBO2; + // unsigned int EBO; glGenVertexArrays(2, vaos); // glGenBuffers(1, &EBO); glGenBuffers(2, vbos); @@ -148,8 +86,10 @@ int main(void) { glBindVertexArray(vaos[0]); glBindBuffer(GL_ARRAY_BUFFER, vbos[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(v1), v1, GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float))); + glEnableVertexAttribArray(1); glBindVertexArray(vaos[1]); glBindBuffer(GL_ARRAY_BUFFER, vbos[1]); @@ -168,9 +108,17 @@ int main(void) { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); + float timeValue = glfwGetTime(); + float green = (sin(timeValue) / 2.0f) + 0.5f; glUseProgram(shaderProgram); + int ourColorLoc = glGetUniformLocation(shaderProgram, "ourColor"); + glUniform4f(ourColorLoc, 0.0f, green, 0.0f, 1.0f); + int offsetLoc = glGetUniformLocation(shaderProgram, "offset"); + glUniform1f(offsetLoc, 0.5f); + glBindVertexArray(vaos[0]); glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(vaos[1]); glDrawArrays(GL_TRIANGLES, 0, 3); // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); diff --git a/shaders/main.frag b/shaders/main.frag new file mode 100644 index 0000000..c076e98 --- /dev/null +++ b/shaders/main.frag @@ -0,0 +1,11 @@ +#version 330 core +in vec3 vertexPos; +in vec3 vertexColor; + +out vec4 FragColor; + +// uniform vec4 ourColor; + +void main() { + FragColor = vec4(vertexPos, 1); +} diff --git a/shaders/main.vert b/shaders/main.vert new file mode 100644 index 0000000..b23dbf2 --- /dev/null +++ b/shaders/main.vert @@ -0,0 +1,12 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aColor; + +out vec3 vertexPos; +out vec3 vertexColor; +uniform float offset; + +void main() { + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + vertexPos = vec3(abs(aPos.x), abs(aPos.y), abs(aPos.z)); +}