From c1fdc355c8d76d1d0f0e98161fe94db09ad5f093 Mon Sep 17 00:00:00 2001 From: kdx Date: Mon, 8 May 2023 17:25:06 +0200 Subject: Shaders --- Tupfile | 2 +- src/fragment.glsl | 5 ++- src/main.c | 85 +++++++++++++----------------------------- src/shader.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/shader.h | 17 +++++++++ src/vertex.glsl | 6 ++- 6 files changed, 162 insertions(+), 62 deletions(-) create mode 100644 src/shader.c create mode 100644 src/shader.h diff --git a/Tupfile b/Tupfile index 3ade1a2..d3f0469 100644 --- a/Tupfile +++ b/Tupfile @@ -1,6 +1,6 @@ CC = gcc LD = $(CC) -fuse-ld=mold -CFLAGS = -std=c99 -Wall -Wextra -Iglad +CFLAGS = -std=c99 -Wall -Wextra -Iglad -Isrc LDFLAGS = -lGL -lglfw .gitignore diff --git a/src/fragment.glsl b/src/fragment.glsl index ca4fb1f..d2dad75 100644 --- a/src/fragment.glsl +++ b/src/fragment.glsl @@ -1,8 +1,11 @@ #version 330 core out vec4 FragColor; +uniform vec4 ourColor; +in vec4 vertexColor; + void main() { - FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); + FragColor = vertexColor * ourColor; } diff --git a/src/main.c b/src/main.c index 4add491..4dfe6b6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include "shader.h" #include #include #include @@ -40,10 +41,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); static const float verts[] = { - 0.5f, 0.5f, 0.0f, // top right - 0.5f, -0.5f, 0.0f, // bottom right - -0.5f, -0.5f, 0.0f, // bottom left - -0.5f, 0.5f, 0.0f // top left + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, // top right + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom left + -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f // top left }; static const GLuint indices[] = { 0, 1, 3, // first triangle @@ -52,57 +53,6 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) GLuint VBO; glGenBuffers(1, &VBO); - const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); - if (vertex_shader == 0) { - fprintf(stderr, "glCreateShader failed\n"); - return 1; - } - const char *const vertex_source = (const char*)src_vertex_glsl; - glShaderSource(vertex_shader, 1, &vertex_source, NULL); - glCompileShader(vertex_shader); - int success; - glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); - if (!success) { - char info_log[512]; - glGetShaderInfoLog(vertex_shader, 512, NULL, info_log); - fprintf(stderr, "glCompileShader failed:\n%s\n", info_log); - return 1; - } - - const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - if (fragment_shader == 0) { - fprintf(stderr, "glCreateShader failed\n"); - return 1; - } - const char *const fragment_source = (const char*)src_fragment_glsl; - glShaderSource(fragment_shader, 1, &fragment_source, NULL); - glCompileShader(fragment_shader); - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); - if (!success) { - char info_log[512]; - glGetShaderInfoLog(fragment_shader, 512, NULL, info_log); - fprintf(stderr, "glCompileShader failed:\n%s\n", info_log); - return 1; - } - - const GLuint shader_program = glCreateProgram(); - if (shader_program == 0) { - fprintf(stderr, "glCreateProgram failed\n"); - return 1; - } - glAttachShader(shader_program, vertex_shader); - glAttachShader(shader_program, fragment_shader); - glLinkProgram(shader_program); - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - glGetProgramiv(shader_program, GL_LINK_STATUS, &success); - if (!success) { - char info_log[512]; - glGetProgramInfoLog(shader_program, 512, NULL, info_log); - fprintf(stderr, "glLinkProgram failed:\n%s\n", info_log); - return 1; - } - GLuint EBO; glGenBuffers(1, &EBO); @@ -112,13 +62,30 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) / 2, indices, GL_STATIC_DRAW); + 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); + + Shader shader; + if (shader_init(&shader, + (const char *)src_vertex_glsl, + (const char *)src_fragment_glsl)) + { + fprintf(stderr, "shader_init failed\n"); + return 1; + } + + const GLint vertex_color_location = + shader_uniform_location(&shader, "ourColor"); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while (!glfwWindowShouldClose(window)) { - glUseProgram(shader_program); + shader_use(&shader); + const int r = 0;//rand(); + glUniform4f(vertex_color_location, + !(r&1), !(r&2), !(r&4), !(r&8)); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..d6f1e37 --- /dev/null +++ b/src/shader.c @@ -0,0 +1,109 @@ +#include "shader.h" +#include + +static GLuint create_shader(GLenum shader_type, const char *src); +static GLuint create_program(GLuint vertex_shader, GLuint fragment_shader); + +int +shader_init(Shader *s, const char *vertex_src, const char *fragment_src) +{ + const GLuint vertex_shader = create_shader(GL_VERTEX_SHADER, vertex_src); + if (vertex_shader == 0) { + fprintf(stderr, "create_shader vertex failed\n"); + return -1; + } + + const GLuint fragment_shader = create_shader(GL_FRAGMENT_SHADER, fragment_src); + if (fragment_shader == 0) { + fprintf(stderr, "create_shader fragment failed\n"); + glDeleteShader(vertex_shader); + return -1; + } + + const GLuint program = create_program(vertex_shader, fragment_shader); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + if (program == 0) { + fprintf(stderr, "create_program failed\n"); + return -1; + } + + s->id = program; + return 0; +} + +void +shader_deinit(Shader *s) +{ + if (s->id) { + glDeleteProgram(s->id); + s->id = 0; + } +} + +void +shader_use(const Shader *s) +{ + glUseProgram(s->id); +} + +int +shader_uniform_location(const Shader *s, const char *name) +{ + const GLint location = glGetUniformLocation(s->id, name); + if (location < -1) { + fprintf(stderr, "glGetUniformLocation failed with '%s'\n", name); + return -1; + } + return location; +} + +static GLuint +create_shader(GLenum shader_type, const char *src) +{ + const GLuint shader = glCreateShader(shader_type); + if (shader == 0) { + fprintf(stderr, "glCreateShader failed\n"); + return 0; + } + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + + int success; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + char info_log[512]; + glGetShaderInfoLog(shader, 512, NULL, info_log); + fprintf(stderr, "glCompileShader failed:\n%s\n", info_log); + glDeleteShader(shader_type); + return 0; + } + + return shader; +} + +static GLuint +create_program(GLuint vertex_shader, GLuint fragment_shader) +{ + const GLuint program = glCreateProgram(); + if (program == 0) { + fprintf(stderr, "glCreateProgram failed\n"); + return 0; + } + + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + int success; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + char info_log[512]; + glGetProgramInfoLog(program, 512, NULL, info_log); + fprintf(stderr, "glLinkProgram failed:\n%s\n", info_log); + glDeleteProgram(program); + return 0; + } + + return program; +} diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 0000000..cd44e80 --- /dev/null +++ b/src/shader.h @@ -0,0 +1,17 @@ +#pragma once +#include + +typedef struct { + GLuint id; +} Shader; + +[[nodiscard]] +/* Return -1 on error. */ +int shader_init(Shader *s, const char *vertex_src, const char *fragment_src); + +void shader_deinit(Shader *s); + +void shader_use(const Shader *s); + +/* Return -1 on error. */ +GLint shader_uniform_location(const Shader *s, const char *name); diff --git a/src/vertex.glsl b/src/vertex.glsl index 2ad10d2..bce2ec6 100644 --- a/src/vertex.glsl +++ b/src/vertex.glsl @@ -1,8 +1,12 @@ #version 330 core layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aColor; + +out vec4 vertexColor; void main() { - gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + gl_Position = vec4(aPos, 1.0); + vertexColor = vec4(aColor, 1.0); } -- cgit v1.2.3