From 3bad7358dc55a969aec23bb5a5932c072d4beedd Mon Sep 17 00:00:00 2001 From: jvech Date: Fri, 19 Aug 2022 10:08:09 -0500 Subject: feat: vertex and fragment shader loader implemented --- src/main.c | 76 ++++++-------------------------------------- src/shader.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/shader.h | 5 +++ 3 files changed, 117 insertions(+), 66 deletions(-) create mode 100644 src/shader.c create mode 100644 src/shader.h (limited to 'src') diff --git a/src/main.c b/src/main.c index 2d296a8..af2c65a 100644 --- a/src/main.c +++ b/src/main.c @@ -6,24 +6,9 @@ #include #include +#include "shader.h" #include "main.h" -const char *vertexShaderSource = \ -"#version 330 core\n" -"layout (location = 0) in vec3 aPos;\n" -"void main()\n" -"{\n" -" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" -"}\0"; - -const char *fragmentShaderSource = \ -"#version 330 core\n" -"out vec4 FragColor;\n" -"void main()\n" -"{\n" -" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" -"}\0"; - float vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, @@ -34,7 +19,6 @@ float vertices[] = { static void userError(const char *msg, const char *detail); static void glfw_size_callback(GLFWwindow *window, int width, int height); static void processInput(GLFWwindow *window, struct Background *c); -static void checkGLSuccess(unsigned int compiledShader, unsigned int shaderStep); void userError(const char *msg, const char *detail) @@ -64,34 +48,6 @@ processInput(GLFWwindow *window, struct Background *c) } } -void -checkGLSuccess(unsigned int shaderBinary, unsigned int shaderStep) -{ - int success; - char infoLog[512]; - switch (shaderStep) { - case 0: - glGetShaderiv(shaderBinary, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(shaderBinary, 512, NULL, infoLog); - userError("glCompileShader() ERROR", infoLog); - } - break; - - case 1: - glGetProgramiv(shaderBinary, GL_LINK_STATUS, &success); - - if (!success) { - glGetProgramInfoLog(shaderBinary, 512, NULL, infoLog); - userError("glLinkProgram() ERROR", infoLog); - } - break; - - default: - break; - } -} - int main() { GLFWwindow *window; @@ -125,32 +81,18 @@ int main() glBindVertexArray(VAO); glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); - unsigned int vertexShader, fragmentShader, shaderProgram; - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); - glCompileShader(vertexShader); - checkGLSuccess(vertexShader, 0); - printf("Vertex Compiled\n"); - - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); - glCompileShader(fragmentShader); - checkGLSuccess(fragmentShader, 0); - printf("Fragment Compiled\n"); - - shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - glLinkProgram(shaderProgram); - checkGLSuccess(shaderProgram, 1); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); + unsigned int shaderProgram = shaderCreateProgram("shaders/vertex.vsh", + "shaders/fragment.vsh"); while (!glfwWindowShouldClose(window)) { processInput(window, &colors); @@ -160,12 +102,14 @@ int main() glUseProgram(shaderProgram); glBindVertexArray(VAO); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); } + int nattributes; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nattributes); + printf("%d\n", nattributes); glfwTerminate(); return 0; } diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..e21277f --- /dev/null +++ b/src/shader.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include "shader.h" + +static char *getShaderSource(const char *shaderPath); +static void checkShaderCompile(unsigned int shader, const char *shaderPath); +static void checkProgramLink(unsigned int shader); + +char +*getShaderSource(const char *shaderPath) +{ + long fileSize; + char *shaderSource; + FILE *shaderFile = fopen(shaderPath, "r"); + + if (!shaderFile) { + perror("getShaderSource() ERROR"); + exit(1); + } + + fseek(shaderFile, 0L, SEEK_END); + fileSize = ftell(shaderFile); + if (!fileSize) { + fprintf(stderr, "getShaderSource() ERROR: %s file is empty\n", shaderPath); + exit(1); + } + + rewind(shaderFile); + + shaderSource = malloc(fileSize * sizeof(char)); + if (!fscanf(shaderFile, "%[^\\]", shaderSource)) { + perror("getShaderSource() ERROR"); + exit(1); + } + + fclose(shaderFile); + return shaderSource; +} + +void +checkShaderCompile(unsigned int shader, const char *shaderPath) +{ + int success; + char infoLog[512]; + + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader, 512, NULL, infoLog); + fprintf(stderr, "shaderCompile() ERROR\n%s %s\n", shaderPath, infoLog); + exit(1); + } +} + +void +checkProgramLink(unsigned int shaderProgram) +{ + int success; + char infoLog[512]; + glLinkProgram(shaderProgram); + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + fprintf(stderr, "shaderProgramLink() ERROR\n%s\n", infoLog); + exit(1); + } +} + +unsigned int +shaderCreateProgram(const char *vertexShaderPath, const char *fragmentShaderPath) +{ + unsigned int vertexShader, fragmentShader, shaderProgram; + char *vertexShaderSource, *fragmentShaderSource; + + vertexShader = glCreateShader(GL_VERTEX_SHADER); + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + vertexShaderSource = getShaderSource(vertexShaderPath); + fragmentShaderSource = getShaderSource(fragmentShaderPath); + + glShaderSource(vertexShader, 1, (const char **)&vertexShaderSource, NULL); + glCompileShader(vertexShader); + checkShaderCompile(vertexShader, vertexShaderPath); + + glShaderSource(fragmentShader, 1, (const char **)&fragmentShaderSource, NULL); + glCompileShader(fragmentShader); + checkShaderCompile(fragmentShader, fragmentShaderPath); + + shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + checkProgramLink(shaderProgram); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + free(vertexShaderSource); + free(fragmentShaderSource); + + return shaderProgram; +} diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 0000000..5f1e315 --- /dev/null +++ b/src/shader.h @@ -0,0 +1,5 @@ +#ifndef __SHADER__ +#define __SHADER__ + +unsigned int shaderCreateProgram(const char *vertexShaderPath, const char *fragmentShaderPath); +#endif -- cgit v1.2.3-70-g09d2