summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-05-08 17:25:06 +0200
committerkdx <kikoodx@paranoici.org>2023-05-08 17:25:06 +0200
commitc1fdc355c8d76d1d0f0e98161fe94db09ad5f093 (patch)
tree91fdfaa3bd4c2c4bf6ec7404c87e3321f0829cf7
parentb4489a653179aee3e902dc4f0a9b087ceac8957b (diff)
downloadlearnopengl-c1fdc355c8d76d1d0f0e98161fe94db09ad5f093.tar.gz
Shaders
-rw-r--r--Tupfile2
-rw-r--r--src/fragment.glsl5
-rw-r--r--src/main.c85
-rw-r--r--src/shader.c109
-rw-r--r--src/shader.h17
-rw-r--r--src/vertex.glsl6
6 files changed, 162 insertions, 62 deletions
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 <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
@@ -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 <stdio.h>
+
+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 <glad/glad.h>
+
+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);
}