From 5f4389d9f97f0643746d33e53d219700fbec36cd Mon Sep 17 00:00:00 2001 From: Quinn Date: Thu, 5 Jun 2025 00:14:44 +0200 Subject: [PATCH] provide a better method of embedding shaders within the source code --- .clang-format | 8 +++- makefile | 10 ++++- res/default.frag.glsl | 6 +++ res/default.vert.glsl | 6 +++ src/io/render.c | 65 +++++++++++++++++++++++++++++++++ src/io/render.h | 10 +++++ src/io/shader.c | 38 +++++++++++++++++++ src/io/shader.h | 10 +++++ src/io/window.c | 85 +++---------------------------------------- src/main.c | 4 ++ 10 files changed, 160 insertions(+), 82 deletions(-) create mode 100644 res/default.frag.glsl create mode 100644 res/default.vert.glsl create mode 100644 src/io/render.c create mode 100644 src/io/render.h create mode 100644 src/io/shader.c create mode 100644 src/io/shader.h diff --git a/.clang-format b/.clang-format index 891f5ce..998cb09 100644 --- a/.clang-format +++ b/.clang-format @@ -95,14 +95,18 @@ IncludeIsMainSourceRegex: '' # only [*.{c,cc,cpp,c++,cxx, IncludeIsMainRegex: '([-_](test|unittest))?$' # regex used for identifying an include as "main", to assign catagory 0 IncludeBlocks: Regroup # (Preserve,Merge,Regroup) IncludeCategories: - - Regex: '^<.*\.h>' # system headers + - Regex: '^' # always include glad before system headers Priority: 1 SortPriority: 0 CaseSensitive: true - - Regex: '^".*' # custom headers + - Regex: '^<.*\.h>' # system headers Priority: 2 SortPriority: 0 CaseSensitive: true + - Regex: '^".*' # custom headers + Priority: 3 + SortPriority: 0 + CaseSensitive: true # --------------------------- # macro and language-specific settings diff --git a/makefile b/makefile index de0064e..6c51643 100644 --- a/makefile +++ b/makefile @@ -2,6 +2,7 @@ # - make # - C compiler # - glfw3 (install glfw3:x64-mingw-dynamic via vcpkg for cross compilation) +# - xxd (tinyxxd recommended; faster) # - (windows) git bash (recommended) # build configuration, information about the current build process @@ -9,6 +10,7 @@ NAME := mcaselector-lite VERSION := 0.0.0 DEBUG ?= 0 CC ?= cc +LD ?= ld CFLAGS += -c -std=gnu99 -Wall -Wextra -Wpedantic -Ilib -MMD -MP LDFLAGS += MARCH ?= $(shell uname -m) @@ -69,10 +71,11 @@ else SRC := $(filter-out src/main.c, $(shell find test/ src/ -name '*.c')) CFLAGS += -DGLFW_DLL endif +RES := $(shell find res/ -type f) # output files BIN := $(DIR_BIN)/$(NAME) -OBJ := $(SRC:%.c=$(DIR_OBJ)/%.o) +OBJ := $(SRC:%.c=$(DIR_OBJ)/%.o) $(RES:%=$(DIR_OBJ)/%.o) DEP := $(OBJ:.o=.d) COMPILE_COMMANDS := $(DIR_OBJ)/compile_commands.json @@ -91,6 +94,11 @@ $(DIR_OBJ)/%.o: %.c @mkdir -p $(@D) $(CC) $(CFLAGS) -o $@ $< +# use linker to embed the resources into the final binary +$(DIR_OBJ)/res/%.o: res/% + @mkdir -p $(@D) + $(LD) -r -b binary -o $@ $< + .PHONY .NOTPARALLEL: clean: rm -rf obj bin compile_commands.json diff --git a/res/default.frag.glsl b/res/default.frag.glsl new file mode 100644 index 0000000..4ec98bb --- /dev/null +++ b/res/default.frag.glsl @@ -0,0 +1,6 @@ +#version 330 core +out vec4 colour; + +void main() { + colour = vec4(1.0F, 0.5F, 0.0F, 1.0F); +} diff --git a/res/default.vert.glsl b/res/default.vert.glsl new file mode 100644 index 0000000..2cabf28 --- /dev/null +++ b/res/default.vert.glsl @@ -0,0 +1,6 @@ +#version 330 core +layout(location = 0) in vec2 pos; + +void main() { + gl_Position = vec4(pos.x, pos.y, 0.0F, 1.0F); +} diff --git a/src/io/render.c b/src/io/render.c new file mode 100644 index 0000000..d1d2240 --- /dev/null +++ b/src/io/render.c @@ -0,0 +1,65 @@ +// Copyright (c) 2025 Quinn +// Licensed under the MIT Licence. See LICENSE for details +#include "render.h" + +#include + +#include +#include +#include + +#include "../util/vec/float2.h" +#include "shader.h" + +#define VERTC 6 +GLuint pipe; +float2 verts[VERTC] = { + {-1, -1 }, // pnt A + {1, -1 }, // pnt B + {1, -0.9F}, // pnt C + + {-1, -0.9F}, // pnt D + {1, -0.9F}, // pnt C + {-1, -1 }, // pnt A +}; +GLuint vbo; // vertex buffer object +GLuint vao; // vertex array object + +int render_init(void) { + pipe = glCreateProgram(); + shader_init(pipe); // initialise and include the shaders + glLinkProgram(pipe); // link the application + glValidateProgram(pipe); // validate that what we've done is correct + + // init the VBO + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); + + // init the VAO + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + // set VBO info + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float2), NULL); + + glBindVertexArray(0); + return 0; +} + +void render_update(GLFWwindow* win) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + int w, h; + glfwGetWindowSize(win, &w, &h); + glViewport(0, 0, w, h); + glClearColor(0.1F, 0.1F, 0.1F, 1.0F); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glUseProgram(pipe); + + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, VERTC); +} diff --git a/src/io/render.h b/src/io/render.h new file mode 100644 index 0000000..0da1475 --- /dev/null +++ b/src/io/render.h @@ -0,0 +1,10 @@ +// Copyright (c) 2025 Quinn +// Licensed under the MIT Licence. See LICENSE for details +#pragma once + +#include + +#include + +int render_init(void); +void render_update(GLFWwindow* win); diff --git a/src/io/shader.c b/src/io/shader.c new file mode 100644 index 0000000..2935116 --- /dev/null +++ b/src/io/shader.c @@ -0,0 +1,38 @@ +// Copyright (c) 2025 Quinn +// Licensed under the MIT Licence. See LICENSE for details +#include "shader.h" + +#include +#include + +#define NAM_S(name) _binary_res_##name##_start // name of a start variable +#define NAM_E(name) _binary_res_##name##_end // name of an end variable + +// NOTE: we are currently just sucking up the memory costs for ease. We can either include the source files themselves. Or use compression, where I'd prefer the latter for ease of installation. +// NOLINTBEGIN (bugprone-reserved-identifier) +extern char const NAM_S(default_vert_glsl)[]; +extern char const NAM_E(default_vert_glsl)[]; +extern char const NAM_S(default_frag_glsl)[]; +extern char const NAM_E(default_frag_glsl)[]; +// NOLINTEND + +/* compile a shader */ +static GLuint shader_compile(GLenum type, char const* src, size_t len) { + int ilen = len; + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &src, &ilen); + glCompileShader(shader); + return shader; +} + +#define COMPILE_NAME(_type, _name) shader_compile(_type, NAM_S(_name), NAM_E(_name) - NAM_S(_name)) +int shader_init(GLuint pipe) { + GLuint vs = COMPILE_NAME(GL_VERTEX_SHADER, default_vert_glsl); + GLuint fs = COMPILE_NAME(GL_FRAGMENT_SHADER, default_frag_glsl); + + glAttachShader(pipe, vs); + glAttachShader(pipe, fs); + glDeleteShader(vs); + glDeleteShader(fs); + return 1; +} diff --git a/src/io/shader.h b/src/io/shader.h new file mode 100644 index 0000000..f55f42c --- /dev/null +++ b/src/io/shader.h @@ -0,0 +1,10 @@ +// Copyright (c) 2025 Quinn +// Licensed under the MIT Licence. See LICENSE for details +#pragma once + +#include + +#include +#include + +int shader_init(GLuint pipe); diff --git a/src/io/window.c b/src/io/window.c index 70da13b..2f1561c 100644 --- a/src/io/window.c +++ b/src/io/window.c @@ -1,22 +1,16 @@ // Copyright (c) 2025 Quinn // Licensed under the MIT Licence. See LICENSE for details -#define GLAD_GL_IMPLEMENTATION #include "window.h" #include -#include -#include -#include "../error.h" -#include "../util/vec/float2.h" - -// include system libraries #include #include -#include #include +#include "../error.h" #include "input.h" +#include "render.h" // macros for ease of access #define WIN_NAME "MCA Selector Lite" @@ -43,13 +37,13 @@ int window_init(void) { win = glfwCreateWindow(WIN_DEFAULT_WIDTH, WIN_DEFAULT_HEIGHT, WIN_NAME, NULL, NULL); if (!win) return 1; - // setup OpenGL + // setup OpenGL for the window glfwMakeContextCurrent(win); if (!gladLoadGL(glfwGetProcAddress)) return 1; + glfwSwapInterval(1); // wait 1 screen update for a redraw a.k.a. "vsync". (not really applicable in this case but eh) // configure callbacks glfwSetKeyCallback(win, key_callback); - glfwSwapInterval(1); // wait 1 screen update for a redraw a.k.a. "vsync". (not really applicable in this case but eh) // print the OpenGL version information debug("version info:"); @@ -61,81 +55,14 @@ int window_init(void) { return 0; } -/* initialize a shader */ -static uint32_t init_shader(GLenum type, char const* src) { - uint32_t shader = glCreateShader(type); - glShaderSource(shader, 1, &src, NULL); - glCompileShader(shader); - return shader; -} - -/* initialize the graphics pipeline */ -static uint32_t init_pipe(void) { - // create the graphics pipeline context - uint32_t pipe = glCreateProgram(); - - uint32_t vs = init_shader(GL_VERTEX_SHADER, "#version 330 core\nin vec4 pos; void main() { gl_Position = vec4(pos.x, pos.y, pos.z, pos.w); }"); - uint32_t fs = init_shader(GL_FRAGMENT_SHADER, "#version 330 core\nout vec4 colour; void main() { colour = vec4(1.0F, 0.5F, 0.0F, 0.1F); }"); - - glAttachShader(pipe, vs); - glAttachShader(pipe, fs); - glLinkProgram(pipe); - - glDeleteShader(vs); - glDeleteShader(fs); - - glValidateProgram(pipe); - - return pipe; -} - void window_loop(void) { assert(win != NULL); - uint32_t pipe = init_pipe(); - - unsigned vertc = 6; - float2 vert[] = { - {-1, -1 }, - {1, -1 }, - {1, -0.9F}, - - {-1, -0.9F}, - {1, -0.9F}, - {-1, -1 }, - }; - - uint32_t vbo; // vertex buffer object - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vert), vert, GL_STATIC_DRAW); - - GLuint vao; // vertex array object - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float2), NULL); - - glBindVertexArray(0); - + render_init(); while (!glfwWindowShouldClose(win)) { glfwWaitEvents(); // wait till an update has been given - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - - int w, h; - glfwGetWindowSize(win, &w, &h); - glViewport(0, 0, w, h); - glClearColor(0.1F, 0.1F, 0.1F, 1.0F); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glUseProgram(pipe); - - glBindVertexArray(vao); - glDrawArrays(GL_TRIANGLES, 0, vertc); - + render_update(win); glfwSwapBuffers(win); } diff --git a/src/main.c b/src/main.c index 82812ec..1b39332 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,9 @@ // Copyright (c) 2025 Quinn // Licensed under the MIT Licence. See LICENSE for details +#define GLAD_GL_IMPLEMENTATION +#include +#undef GLAD_GL_IMPLEMENTATION + #include #include "error.h"