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
|
bin_PROGRAMS = forge
|
||||||
forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c
|
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
|
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] Create GLSL Window
|
||||||
- [x] Load static fragment shader into GLSL
|
- [x] Load static fragment shader into GLSL
|
||||||
- [x] Add default uniforms
|
- [x] Add default uniforms
|
||||||
- [ ] Read fragment shader from file
|
- [x] Read fragment shader from file
|
||||||
- [ ] Handle compilation errors
|
- [ ] Handle compilation errors
|
||||||
- [ ] Minimal working fragment sample
|
- [x] Minimal working fragment sample
|
||||||
- [ ] Hot-reload fragment shader
|
- [x] Hot-reload fragment shader
|
||||||
|
- [ ] Specify fragment shader path
|
||||||
- [x] Force fullscreen
|
- [x] Force fullscreen
|
||||||
- [x] Select screen as argument / config
|
- [x] Select screen as argument / config
|
||||||
- [ ] Midi
|
- [ ] 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 <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
void print_help(int status_code) {
|
void print_help(int status_code) {
|
||||||
puts(PACKAGE
|
puts(PACKAGE
|
||||||
" " VERSION "\n\n"
|
" " 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}}};
|
||||||
+5
-1
@@ -23,7 +23,9 @@ bool should_update_file(File *file) {
|
|||||||
|
|
||||||
void update_file(File *file) {
|
void update_file(File *file) {
|
||||||
// free remaining data
|
// free remaining data
|
||||||
|
if (file->content != 0) {
|
||||||
free(file->content);
|
free(file->content);
|
||||||
|
}
|
||||||
// init empty file
|
// init empty file
|
||||||
file->content = 0;
|
file->content = 0;
|
||||||
file->error = false;
|
file->error = false;
|
||||||
@@ -56,7 +58,9 @@ void update_file(File *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
File read_file(char *path) {
|
File read_file(char *path) {
|
||||||
File file = {path, 0, 0, 0};
|
File file = {path, 0, false, 0};
|
||||||
update_file(&file);
|
update_file(&file);
|
||||||
return 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 update_file(File *file);
|
||||||
|
|
||||||
|
void free_file(File *file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+64
-37
@@ -1,47 +1,18 @@
|
|||||||
#include "config.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#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) {
|
void error_callback(int error, const char *description) {
|
||||||
fprintf(stderr, "Error %d: %s\n", error, description);
|
fprintf(stderr, "Error %d: %s\n", error, description);
|
||||||
glfwTerminate();
|
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) {
|
void *init_window(GLFWwindow **window, Parameters params) {
|
||||||
// set errors handler
|
// set errors handler
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
@@ -112,8 +85,11 @@ void *init_window(GLFWwindow **window, Parameters params) {
|
|||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderProgram init_program() {
|
// TODO extract to "shaders" file
|
||||||
|
// TODO split into smaller functions
|
||||||
|
ShaderProgram init_program(File fragment_shader) {
|
||||||
ShaderProgram program = {};
|
ShaderProgram program = {};
|
||||||
|
GLint status_params;
|
||||||
|
|
||||||
glGenBuffers(1, &program.vertex_buffer);
|
glGenBuffers(1, &program.vertex_buffer);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 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);
|
glShaderSource(program.vertex_shader, 1, &vertex_shader_text, NULL);
|
||||||
glCompileShader(program.vertex_shader);
|
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);
|
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);
|
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();
|
program.program = glCreateProgram();
|
||||||
glAttachShader(program.program, program.vertex_shader);
|
glAttachShader(program.program, program.vertex_shader);
|
||||||
glAttachShader(program.program, program.fragment_shader);
|
glAttachShader(program.program, program.fragment_shader);
|
||||||
@@ -146,6 +139,21 @@ ShaderProgram init_program() {
|
|||||||
return 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) {
|
void loop(GLFWwindow *window, ShaderProgram program) {
|
||||||
int width, height;
|
int width, height;
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
@@ -173,13 +181,32 @@ void loop(GLFWwindow *window, ShaderProgram program) {
|
|||||||
void forge_run(Parameters params) {
|
void forge_run(Parameters params) {
|
||||||
GLFWwindow *window;
|
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);
|
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)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
|
if (should_update_file(&fragment_shader)) {
|
||||||
|
update_file(&fragment_shader);
|
||||||
|
update_program(program, fragment_shader);
|
||||||
|
}
|
||||||
loop(window, program);
|
loop(window, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
free_file(&fragment_shader);
|
||||||
}
|
}
|
||||||
+4
-3
@@ -1,10 +1,11 @@
|
|||||||
#include "args.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "forge.h"
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "forge.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Parameters params;
|
Parameters params;
|
||||||
params = parse_args(argc, argv);
|
params = parse_args(argc, argv);
|
||||||
|
|||||||
+5
-2
@@ -1,8 +1,9 @@
|
|||||||
#include <glad/gl.h>
|
|
||||||
#include <linmath.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <glad/gl.h>
|
||||||
|
#include <linmath.h>
|
||||||
|
|
||||||
#ifndef TYPES_H
|
#ifndef TYPES_H
|
||||||
#define TYPES_H
|
#define TYPES_H
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ typedef struct ShaderProgram {
|
|||||||
GLuint ires_location;
|
GLuint ires_location;
|
||||||
|
|
||||||
GLuint vertex_array;
|
GLuint vertex_array;
|
||||||
|
|
||||||
|
bool error;
|
||||||
} ShaderProgram;
|
} ShaderProgram;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user