wip extract to files

This commit is contained in:
2025-09-13 14:30:23 +02:00
parent 2fa6c42799
commit 530d868364
11 changed files with 187 additions and 143 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ clean:
build: build:
@mkdir -p build @mkdir -p build
gcc -v -Wall -Wextra src/*.c src/*.h -Iinclude -lglfw -lGL -lm -ldl -o build/$(TARGET) gcc -Wall -Wextra src/*.h src/*.c -Iinclude -lglfw -lGL -lm -o build/$(TARGET)
run: build run: build
./build/forge --hot-reload --frag=./shaders/frag.glsl ./build/forge --hot-reload --frag=./shaders/frag.glsl
+1 -1
View File
@@ -72,7 +72,7 @@ $EDITOR configure.ac
# make full build # make full build
make -f Makefile.dev release make -f Makefile.dev release
# update PKGBUILD with new version and sha256 sum # update PKGBUILD with new version and sha256 sum
sha256sum forge-x.y.z.tar.gz sha256sum build/forge-x.y.z.tar.gzx
$EDITOR PKGBUILD $EDITOR PKGBUILD
# push to repo # push to repo
git commit -am "forge vX.Y.Z" git commit -am "forge vX.Y.Z"
+1
View File
@@ -4,6 +4,7 @@ AC_PROG_CC
AC_CHECK_HEADERS([stdio.h]) AC_CHECK_HEADERS([stdio.h])
AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([stdlib.h])
AC_CHECK_HEADERS([stdbool.h]) AC_CHECK_HEADERS([stdbool.h])
AC_CHECK_HEADERS([stddef.h])
AC_CHECK_HEADERS([string.h]) AC_CHECK_HEADERS([string.h])
AC_CHECK_HEADERS([time.h]) AC_CHECK_HEADERS([time.h])
AC_CHECK_HEADERS([sys/stat.h]) AC_CHECK_HEADERS([sys/stat.h])
+6 -1
View File
@@ -1,5 +1,8 @@
#include "types.h" #include "types.h"
#ifndef CONSTANTS_H
#define CONSTANTS_H
static const char *vertex_shader_text = static const char *vertex_shader_text =
"#version 330\n" "#version 330\n"
"uniform mat4 mvp;\n" "uniform mat4 mvp;\n"
@@ -13,4 +16,6 @@ static const char *vertex_shader_text =
static const Vertex vertices[6] = {{{0.0f, 0.0f}}, {{0.0f, 1.0f}}, static const Vertex vertices[6] = {{{0.0f, 0.0f}}, {{0.0f, 1.0f}},
{{1.0f, 1.0f}}, {{0.0f, 0.0f}}, {{1.0f, 1.0f}}, {{0.0f, 0.0f}},
{{1.0f, 1.0f}}, {{1.0f, 0.0f}}}; {{1.0f, 1.0f}}, {{1.0f, 0.0f}}};
#endif
+10 -139
View File
@@ -2,16 +2,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "config.h"
#include "constants.h"
#include "file.h" #include "file.h"
#include "glfw.h"
#include "shaders.h"
#include "types.h" #include "types.h"
#include "window.h"
#include <linmath.h>
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
void error_callback(int error, const char *description) { void error_callback(int error, const char *description) {
fprintf(stderr, "Error %d: %s\n", error, description); fprintf(stderr, "Error %d: %s\n", error, description);
@@ -19,7 +14,7 @@ void error_callback(int error, const char *description) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static void key_callback(GLFWwindow *window, int key, static void key_callback(Window *window, int key,
__attribute__((unused)) int scancode, int action, __attribute__((unused)) int scancode, int action,
int mods) { int mods) {
// close window on escape key // close window on escape key
@@ -28,134 +23,9 @@ static void key_callback(GLFWwindow *window, int key,
} }
} }
// TODO extract to window file void loop(Window *window, ShaderProgram program) {
// TODO split into smaller functions // TODO remove GLFW references
void *init_window(GLFWwindow **window, Parameters params) { // TODO split into smaller functions
// set errors handler
glfwSetErrorCallback(error_callback);
// print current GLFW version
fprintf(stdout, "[GLFW] %s\n", glfwGetVersionString());
// init GLFW
if (!glfwInit()) {
fprintf(stderr, "[GLFW] Initialization failed\n");
exit(EXIT_FAILURE);
}
// add context to window before creation
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DECORATED, 0);
// detect monitors
int count;
GLFWmonitor **monitors = glfwGetMonitors(&count);
// check selected monitor availability
if (params.screen >= count) {
fprintf(stderr, "Screen %d is out of range [0-%d]\n", params.screen,
count - 1);
glfwTerminate();
exit(EXIT_FAILURE);
}
// create fullscreen window in selected monitor
(*window) = glfwCreateWindow(1, 1, PACKAGE " " VERSION,
monitors[params.screen], NULL);
// handle window creation fail
if (!(*window)) {
fprintf(stderr, "[GLFW] Window or context creation failed\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
// use current window
glfwMakeContextCurrent((*window));
// link GLAD and GLFW window
gladLoadGL(glfwGetProcAddress);
// set keyboard handler
glfwSetKeyCallback((*window), key_callback);
// hide cursor
glfwSetInputMode((*window), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
// vsync
glfwSwapInterval(1);
return window;
}
// TODO extract to "shaders" file
// TODO split into smaller functions
ShaderProgram init_program(File fragment_shader) {
ShaderProgram program = {};
GLint status_params;
glGenBuffers(1, &program.vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, program.vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
program.vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(program.vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(program.vertex_shader);
glGetShaderiv(program.vertex_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
program.error = true;
// TODO use glGetShaderInfoLog( GLuint shader, GLsizei
// maxLength, GLsizei *length, GLchar *infoLog);
}
program.fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(program.fragment_shader, 1,
(const GLchar *const *)&fragment_shader.content, NULL);
glCompileShader(program.fragment_shader);
glGetShaderiv(program.fragment_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
program.error = true;
}
if (program.error) {
return program;
}
program.program = glCreateProgram();
glAttachShader(program.program, program.vertex_shader);
glAttachShader(program.program, program.fragment_shader);
glLinkProgram(program.program);
program.mvp_location = glGetUniformLocation(program.program, "mvp");
program.itime_location = glGetUniformLocation(program.program, "iTime");
program.ires_location = glGetUniformLocation(program.program, "iResolution");
program.vpos_location = glGetAttribLocation(program.program, "vPos");
glGenVertexArrays(1, &program.vertex_array);
glBindVertexArray(program.vertex_array);
glEnableVertexAttribArray(program.vpos_location);
glVertexAttribPointer(program.vpos_location, 2, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void *)offsetof(Vertex, pos));
return program;
}
// TODO extract to "shaders" file
void update_program(ShaderProgram program, File fragment_shader) {
GLint status_params;
glShaderSource(program.fragment_shader, 1,
(const GLchar *const *)&fragment_shader.content, NULL);
glCompileShader(program.fragment_shader);
glGetShaderiv(program.fragment_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
fprintf(stderr, "Failed to compile shaders\n"); // TODO add info
return;
}
glLinkProgram(program.program);
}
void loop(GLFWwindow *window, ShaderProgram program) {
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
vec2 resolution = {(float)width, (float)height}; vec2 resolution = {(float)width, (float)height};
@@ -180,7 +50,8 @@ void loop(GLFWwindow *window, ShaderProgram program) {
} }
void forge_run(Parameters params) { void forge_run(Parameters params) {
GLFWwindow *window; // TODO remove GLFW references
Window *window;
File fragment_shader = read_file(params.frag_path); File fragment_shader = read_file(params.frag_path);
@@ -189,7 +60,7 @@ void forge_run(Parameters params) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
init_window(&window, params); init_window(&window, params, error_callback, key_callback);
ShaderProgram program = init_program(fragment_shader); ShaderProgram program = init_program(fragment_shader);
+10
View File
@@ -0,0 +1,10 @@
#ifndef GLFW_H
#define GLFW_H
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#endif
+74
View File
@@ -0,0 +1,74 @@
#include <stddef.h>
#include <linmath.h>
#include "constants.h"
#include "glfw.h"
#include "types.h"
// TODO split into smaller functions
ShaderProgram init_program(File fragment_shader) {
ShaderProgram program = {};
GLint status_params;
glGenBuffers(1, &program.vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, program.vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
program.vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(program.vertex_shader, 1, &vertex_shader_text, NULL);
glCompileShader(program.vertex_shader);
glGetShaderiv(program.vertex_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
program.error = true;
// TODO use glGetShaderInfoLog( GLuint shader, GLsizei
// maxLength, GLsizei *length, GLchar *infoLog);
}
program.fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(program.fragment_shader, 1,
(const GLchar *const *)&fragment_shader.content, NULL);
glCompileShader(program.fragment_shader);
glGetShaderiv(program.fragment_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
program.error = true;
}
if (program.error) {
return program;
}
program.program = glCreateProgram();
glAttachShader(program.program, program.vertex_shader);
glAttachShader(program.program, program.fragment_shader);
glLinkProgram(program.program);
program.mvp_location = glGetUniformLocation(program.program, "mvp");
program.itime_location = glGetUniformLocation(program.program, "iTime");
program.ires_location = glGetUniformLocation(program.program, "iResolution");
program.vpos_location = glGetAttribLocation(program.program, "vPos");
glGenVertexArrays(1, &program.vertex_array);
glBindVertexArray(program.vertex_array);
glEnableVertexAttribArray(program.vpos_location);
glVertexAttribPointer(program.vpos_location, 2, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (void *)offsetof(Vertex, pos));
return program;
}
void update_program(ShaderProgram program, File fragment_shader) {
GLint status_params;
glShaderSource(program.fragment_shader, 1,
(const GLchar *const *)&fragment_shader.content, NULL);
glCompileShader(program.fragment_shader);
glGetShaderiv(program.fragment_shader, GL_COMPILE_STATUS, &status_params);
if (status_params == GL_FALSE) {
fprintf(stderr, "Failed to compile shaders\n"); // TODO add info
return;
}
glLinkProgram(program.program);
}
+6
View File
@@ -1,4 +1,10 @@
#include "types.h"
#ifndef SHADERS_H #ifndef SHADERS_H
#define SHADERS_H #define SHADERS_H
ShaderProgram init_program(File fragment_shader);
void update_program(ShaderProgram program, File fragment_shader);
#endif #endif
+4 -1
View File
@@ -1,9 +1,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <time.h> #include <time.h>
#include <glad/gl.h>
#include <linmath.h> #include <linmath.h>
#include "glfw.h"
#ifndef TYPES_H #ifndef TYPES_H
#define TYPES_H #define TYPES_H
@@ -42,4 +43,6 @@ typedef struct ShaderProgram {
bool error; bool error;
} ShaderProgram; } ShaderProgram;
typedef GLFWwindow Window;
#endif #endif
+68
View File
@@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <linmath.h>
#include "config.h"
#include "glfw.h"
#include "types.h"
// TODO split into smaller functions
// TODO custom struct to remove glfw in signature
void *init_window(Window **window, Parameters params,
void (*error_callback)(int, const char *),
void (*key_callback)(Window *, int, int, int, int)) {
// set errors handler
glfwSetErrorCallback(error_callback);
// print current GLFW version
fprintf(stdout, "[GLFW] %s\n", glfwGetVersionString());
// init GLFW
if (!glfwInit()) {
fprintf(stderr, "[GLFW] Initialization failed\n");
exit(EXIT_FAILURE);
}
// add context to window before creation
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DECORATED, 0);
// detect monitors
int count;
GLFWmonitor **monitors = glfwGetMonitors(&count);
// check selected monitor availability
if (params.screen >= count) {
fprintf(stderr, "Screen %d is out of range [0-%d]\n", params.screen,
count - 1);
glfwTerminate();
exit(EXIT_FAILURE);
}
// create fullscreen window in selected monitor
(*window) = glfwCreateWindow(1, 1, PACKAGE " " VERSION,
monitors[params.screen], NULL);
// handle window creation fail
if (!(*window)) {
fprintf(stderr, "[GLFW] Window or context creation failed\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
// use current window
glfwMakeContextCurrent((*window));
// link GLAD and GLFW window
gladLoadGL(glfwGetProcAddress);
// set keyboard handler
glfwSetKeyCallback((*window), key_callback);
// hide cursor
glfwSetInputMode((*window), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
// vsync
glfwSwapInterval(1);
return window;
}
+6
View File
@@ -1,4 +1,10 @@
#include "types.h"
#ifndef WINDOW_H #ifndef WINDOW_H
#define WINDOW_H #define WINDOW_H
void *init_window(Window **window, Parameters params,
void (*error_callback)(int, const char *),
void (*key_callback)(Window *, int, int, int, int));
#endif #endif