From c0a4cd2aa8dce443a7d54232cada0ee57cdec463 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 16 May 2024 17:03:33 +0200 Subject: WIP fragment shader demo --- draw.c | 6 ------ draw.h | 7 ------- hello.frag | 9 +++++++- hello.vert | 7 +++++++ main.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++--------------- makefile | 5 ++++- shader.c | 48 +++++++++++++++++++++++++++++++++++++++++++ shader.h | 13 ++++++++++++ 8 files changed, 133 insertions(+), 31 deletions(-) delete mode 100644 draw.c delete mode 100644 draw.h create mode 100644 shader.c create mode 100644 shader.h diff --git a/draw.c b/draw.c deleted file mode 100644 index 0dfa09c..0000000 --- a/draw.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "draw.h" - -void draw(GLFWwindow* window) { - glClearColor(1.f, 0.f, 1.f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} diff --git a/draw.h b/draw.h deleted file mode 100644 index 617569b..0000000 --- a/draw.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -/** @brief draw loop iteration, called once for every frame */ -void draw(GLFWwindow*); - diff --git a/hello.frag b/hello.frag index b88dc43..a804a77 100644 --- a/hello.frag +++ b/hello.frag @@ -1,6 +1,13 @@ #version 330 core +out vec4 FragColor; void main() { - gl_FragColor = vec4(gl_FragCoord.xy, 0, 1); + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } +// #version 330 core +// +// void main() { +// gl_FragColor = vec4(gl_FragCoord.xy, 0, 1); +// } +// diff --git a/hello.vert b/hello.vert index e69de29..4af0bdf 100644 --- a/hello.vert +++ b/hello.vert @@ -0,0 +1,7 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +void main() { + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); +} + diff --git a/main.c b/main.c index ab5f97b..8ac0ca2 100644 --- a/main.c +++ b/main.c @@ -1,40 +1,77 @@ #include +#include #include -#include "draw.h" +#include "shader.h" #include "die.h" -void resize_handler(GLFWwindow* window, int width, int height) { - glViewport(0, 0, width, height); +#include "hello_vert.h" +#include "hello_frag.h" + +void prepare_tri(GLuint* VBO, GLuint* VAO) { + const float vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f, + }; + + // initialize vertex {buffer,attribute} object buffers + glGenBuffers(1, VBO); + glBindBuffer(GL_ARRAY_BUFFER, *VBO); + glGenBuffers(1, VAO); + glBindVertexArray(*VAO); + + // copy vertex data into VBO + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // set VAO pointers + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); } int main(int argc, char** argv) { glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - int width = 800, height = 600; - GLFWwindow* window = glfwCreateWindow(width, height, "vis", NULL, NULL); + // force floating window w/ i3 + glfwWindowHint(GLFW_FLOATING, GL_TRUE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - if (window == NULL) { - glfwTerminate(); + // initialize window + GLFWwindow* window = glfwCreateWindow(800, 600, "vis", NULL, NULL); + if (window == NULL) die("error: could not create window\n"); - } - glfwMakeContextCurrent(window); - glfwSetFramebufferSizeCallback(window, resize_handler); - resize_handler(window, width, height); + // initialize GLEW + glewInit(); + + // create single triangle + GLuint VBO, VAO; + prepare_tri(&VBO, &VAO); + + // prepare shaders + GLuint shader = link_shaders( + vert_shader(hello_vert, hello_vert_size), + frag_shader(hello_frag, hello_frag_size) + ); + + // main draw loop while (!glfwWindowShouldClose(window)) { - draw(window); - glfwSwapBuffers(window); glfwPollEvents(); + + glClearColor(1.f, 0.f, 1.f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(shader); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); } - glfwTerminate(); return EXIT_SUCCESS; } diff --git a/makefile b/makefile index 539ac68..42f4e1a 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,8 @@ LDFLAGS += -lglfw LDFLAGS += -lOpenGL +LDFLAGS += -lGLEW + +CFLAGS += -g .PHONY: FORCE @@ -7,7 +10,7 @@ all: main FORCE main: main.o main: die.o -main: draw.o +main: shader.o main: hello_frag.o main: hello_vert.o diff --git a/shader.c b/shader.c new file mode 100644 index 0000000..df17d5d --- /dev/null +++ b/shader.c @@ -0,0 +1,48 @@ +#include "shader.h" + +#include "die.h" + +void check_shader(GLuint shader) { + int success; + char debug[LOG_MAX]; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (success) return; + glGetShaderInfoLog(shader, LOG_MAX, NULL, debug); + die("error: shader compilation failed:\n%s\n", debug); +} + +void check_program(GLuint program) { + int success; + char debug[LOG_MAX]; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (success) return; + glGetProgramInfoLog(program, LOG_MAX, NULL, debug); + die("error: shader linking failed:\n%s\n", debug); +} + +GLuint load_shader(GLenum type, const char* const src, size_t src_size) { + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &src, (const int*) &src_size); + glCompileShader(shader); + check_shader(shader); + return shader; +} + +GLuint frag_shader(const char* const src, size_t src_size) { + return load_shader(GL_FRAGMENT_SHADER, src, src_size); +} +GLuint vert_shader(const char* const src, size_t src_size) { + return load_shader(GL_VERTEX_SHADER, src, src_size); +} + +GLuint link_shaders(GLuint vert, GLuint frag) { + GLuint shader = glCreateProgram(); + glAttachShader(shader, vert); + glAttachShader(shader, frag); + glLinkProgram(shader); + check_program(shader); + glDeleteShader(vert); + glDeleteShader(frag); + return shader; +} + diff --git a/shader.h b/shader.h new file mode 100644 index 0000000..6a4739e --- /dev/null +++ b/shader.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include +#include + +#define LOG_MAX 512 + +GLuint frag_shader(const char* const src, size_t src_size); +GLuint vert_shader(const char* const src, size_t src_size); +GLuint link_shaders(GLuint vert, GLuint frag); + -- cgit v1.2.3