read fragment shader from file
This commit is contained in:
+1
-1
@@ -2,4 +2,4 @@ AUTOMAKE_OPTIONS = foreign subdir-objects -Wall
|
||||
bin_PROGRAMS = forge
|
||||
forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c
|
||||
forge_CFLAGS = -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp
|
||||
include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h include/linmath.h include/glad/gl.h
|
||||
include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h include/linmath.h include/glad/gl.h
|
||||
@@ -86,10 +86,11 @@ make -f Makefile.dev release-arch
|
||||
- [x] Create GLSL Window
|
||||
- [x] Load static fragment shader into GLSL
|
||||
- [x] Add default uniforms
|
||||
- [ ] Read fragment shader from file
|
||||
- [x] Read fragment shader from file
|
||||
- [ ] Handle compilation errors
|
||||
- [ ] Minimal working fragment sample
|
||||
- [ ] Hot-reload fragment shader
|
||||
- [x] Minimal working fragment sample
|
||||
- [x] Hot-reload fragment shader
|
||||
- [ ] Specify fragment shader path
|
||||
- [x] Force fullscreen
|
||||
- [x] Select screen as argument / config
|
||||
- [ ] Midi
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#version 330
|
||||
|
||||
uniform float iTime;
|
||||
uniform vec2 iResolution;
|
||||
in vec2 vUV;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 uv0 = vUV.st;
|
||||
float ratio = iResolution.x / iResolution.y;
|
||||
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1);
|
||||
vec3 color = vec3(vUV, sin(iTime * 0.5) * 0.5 + 0.5);
|
||||
color *= 1 - step(cos(iTime) * 0.1 + 0.5,length(uv1));
|
||||
fragColor = vec4(color, 1.0);
|
||||
}
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
#include "args.h"
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "args.h"
|
||||
#include "config.h"
|
||||
|
||||
void print_help(int status_code) {
|
||||
puts(PACKAGE
|
||||
" " VERSION "\n\n"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "types.h"
|
||||
|
||||
static const char *vertex_shader_text =
|
||||
"#version 330\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec2 vPos;\n"
|
||||
"out vec2 vUV;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = mvp * vec4(vPos, 0.0, 1.0);\n"
|
||||
" vUV = vPos;\n"
|
||||
"}\n";
|
||||
|
||||
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}}, {{1.0f, 0.0f}}};
|
||||
+7
-3
@@ -23,7 +23,9 @@ bool should_update_file(File *file) {
|
||||
|
||||
void update_file(File *file) {
|
||||
// free remaining data
|
||||
free(file->content);
|
||||
if (file->content != 0) {
|
||||
free(file->content);
|
||||
}
|
||||
// init empty file
|
||||
file->content = 0;
|
||||
file->error = false;
|
||||
@@ -56,7 +58,9 @@ void update_file(File *file) {
|
||||
}
|
||||
|
||||
File read_file(char *path) {
|
||||
File file = {path, 0, 0, 0};
|
||||
File file = {path, 0, false, 0};
|
||||
update_file(&file);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
void free_file(File *file) { free(file->content); }
|
||||
@@ -9,4 +9,6 @@ bool should_update_file(File *file);
|
||||
|
||||
void update_file(File *file);
|
||||
|
||||
void free_file(File *file);
|
||||
|
||||
#endif
|
||||
+64
-37
@@ -1,47 +1,18 @@
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <linmath.h>
|
||||
#include "config.h"
|
||||
#include "constants.h"
|
||||
#include "file.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <linmath.h>
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
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}}, {{1.0f, 0.0f}}};
|
||||
|
||||
static const char *vertex_shader_text =
|
||||
"#version 330\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec2 vPos;\n"
|
||||
"out vec2 vUV;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = mvp * vec4(vPos, 0.0, 1.0);\n"
|
||||
" vUV = vPos;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragment_shader_text =
|
||||
"#version 330\n"
|
||||
"uniform float iTime;\n"
|
||||
"uniform vec2 iResolution;\n"
|
||||
"in vec2 vUV;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 uv0 = vUV.st;\n"
|
||||
" float ratio = iResolution.x / iResolution.y;\n"
|
||||
" vec2 uv1 = (uv0 - .5) * vec2(ratio, 1);\n"
|
||||
" vec3 color = vec3(vUV, sin(iTime * 0.5) * 0.5 + 0.5);\n"
|
||||
" color *= 1 - step(cos(iTime) * 0.5 + 0.5,length(uv1));\n"
|
||||
" fragColor = vec4(color, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
void error_callback(int error, const char *description) {
|
||||
fprintf(stderr, "Error %d: %s\n", error, description);
|
||||
glfwTerminate();
|
||||
@@ -56,6 +27,8 @@ static void key_callback(GLFWwindow *window, int key, int scancode, int action,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO extract to window file
|
||||
// TODO split into smaller functions
|
||||
void *init_window(GLFWwindow **window, Parameters params) {
|
||||
// set errors handler
|
||||
glfwSetErrorCallback(error_callback);
|
||||
@@ -112,8 +85,11 @@ void *init_window(GLFWwindow **window, Parameters params) {
|
||||
return window;
|
||||
}
|
||||
|
||||
ShaderProgram init_program() {
|
||||
// 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);
|
||||
@@ -123,10 +99,27 @@ ShaderProgram init_program() {
|
||||
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, &fragment_shader_text, NULL);
|
||||
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);
|
||||
@@ -146,6 +139,21 @@ ShaderProgram init_program() {
|
||||
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;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
@@ -173,13 +181,32 @@ void loop(GLFWwindow *window, ShaderProgram program) {
|
||||
void forge_run(Parameters params) {
|
||||
GLFWwindow *window;
|
||||
|
||||
File fragment_shader = read_file("shaders/tmp.glsl");
|
||||
|
||||
if (fragment_shader.error) {
|
||||
fprintf(stderr, "Cannot read file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
init_window(&window, params);
|
||||
|
||||
ShaderProgram program = init_program();
|
||||
ShaderProgram program = init_program(fragment_shader);
|
||||
|
||||
if (program.error) {
|
||||
fprintf(stderr, "Failed to compile shaders\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
if (should_update_file(&fragment_shader)) {
|
||||
update_file(&fragment_shader);
|
||||
update_program(program, fragment_shader);
|
||||
}
|
||||
loop(window, program);
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
|
||||
free_file(&fragment_shader);
|
||||
}
|
||||
+4
-3
@@ -1,10 +1,11 @@
|
||||
#include "args.h"
|
||||
#include "config.h"
|
||||
#include "forge.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "args.h"
|
||||
#include "config.h"
|
||||
#include "forge.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Parameters params;
|
||||
params = parse_args(argc, argv);
|
||||
|
||||
+5
-2
@@ -1,8 +1,9 @@
|
||||
#include <glad/gl.h>
|
||||
#include <linmath.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <glad/gl.h>
|
||||
#include <linmath.h>
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
@@ -35,6 +36,8 @@ typedef struct ShaderProgram {
|
||||
GLuint ires_location;
|
||||
|
||||
GLuint vertex_array;
|
||||
|
||||
bool error;
|
||||
} ShaderProgram;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user