out and monitor in defined shaders
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
// OUT
|
||||
// ---
|
||||
|
||||
in vec2 vUV;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(tex0, vUV);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// MONITOR
|
||||
// ---
|
||||
|
||||
in vec2 vUV;
|
||||
out vec4 fragColor;
|
||||
|
||||
float s(vec2 uv, float x0, float y0) {
|
||||
return step(x0, uv.x) * step(-x0 - 1, -uv.x) * step(y0, uv.y) *
|
||||
step(-y0 - 1, -uv.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = vUV * 3;
|
||||
fragColor = vec4(0);
|
||||
fragColor += s(uv,0,2) * texture(tex1, uv);
|
||||
fragColor += s(uv,1,2) * texture(tex2, uv);
|
||||
fragColor += s(uv,2,2) * texture(tex3, uv);
|
||||
fragColor += s(uv,0,1) * texture(tex4, uv);
|
||||
fragColor += s(uv,1,1) * texture(tex5, uv);
|
||||
fragColor += s(uv,2,1) * texture(tex6, uv);
|
||||
fragColor += s(uv,0.5,0) * texture(tex7, uv-vec2(0.5,0));
|
||||
fragColor += s(uv,1.5,0) * texture(tex0, uv-vec2(0.5,0));
|
||||
}
|
||||
+3
-1
@@ -3,7 +3,9 @@ UNIFORM_TEMPO=iTempo
|
||||
UNIFORM_FPS=iFPS
|
||||
UNIFORM_RESOLUTION=iResolution
|
||||
|
||||
FRAG_COUNT=6
|
||||
FRAG_COUNT=8
|
||||
FRAG_OUT=7
|
||||
FRAG_MONITOR=8
|
||||
|
||||
SUB_TYPE_COUNT=3
|
||||
SUB_1_PREFIX=src_
|
||||
|
||||
@@ -13,45 +13,6 @@ static char *vertex_shader_text =
|
||||
"{\n"
|
||||
" gl_Position = mvp * vec4(vPos, 0.0, 1.0);\n"
|
||||
" vUV = vPos;\n"
|
||||
"}\n";
|
||||
|
||||
static char *output_shader_text = "#version 460\n"
|
||||
"in vec2 vUV;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" fragColor = texture(tex0, vUV);\n"
|
||||
"}";
|
||||
|
||||
// TODO monitor should have special shader to use full capacity
|
||||
static char *monitor_shader_text =
|
||||
"#version 460\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"uniform sampler2D tex1;\n"
|
||||
"uniform sampler2D tex2;\n"
|
||||
"uniform sampler2D tex3;\n"
|
||||
"uniform sampler2D tex4;\n"
|
||||
"uniform sampler2D tex5;\n"
|
||||
"uniform sampler2D tex6;\n"
|
||||
"uniform sampler2D tex7;\n"
|
||||
"in vec2 vUV;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"float s(vec2 uv, float x0, float y0) {\n"
|
||||
" return step(x0, uv.x) * step(-x0 - 1, -uv.x) * step(y0, uv.y) * "
|
||||
"step(-y0 - 1, -uv.y);\n"
|
||||
"}\n"
|
||||
"void main() {\n"
|
||||
" vec2 uv = vUV * 3;\n"
|
||||
" fragColor = vec4(0);\n"
|
||||
" fragColor += s(uv,0,2) * texture(tex1, uv);\n"
|
||||
" fragColor += s(uv,1,2) * texture(tex2, uv);\n"
|
||||
" fragColor += s(uv,2,2) * texture(tex3, uv);\n"
|
||||
" fragColor += s(uv,0,1) * texture(tex4, uv);\n"
|
||||
" fragColor += s(uv,1,1) * texture(tex5, uv);\n"
|
||||
" fragColor += s(uv,2,1) * texture(tex6, uv);\n"
|
||||
" fragColor += s(uv,0.5,0) * texture(tex7, uv-vec2(0.5,0));\n"
|
||||
" fragColor += s(uv,1.5,0) * texture(tex0, uv-vec2(0.5,0));\n"
|
||||
"}";
|
||||
|
||||
static const Vertex vertices[6] = {{{0.0f, 0.0f}}, {{0.0f, 1.0f}},
|
||||
|
||||
+54
-65
@@ -62,11 +62,11 @@ static void init_textures(ShaderProgram *program, Context context) {
|
||||
static void init_framebuffers(ShaderProgram *program) {
|
||||
unsigned int i, j;
|
||||
|
||||
program->frame_buffers = malloc(program->frag_count * sizeof(GLuint));
|
||||
program->frame_buffers = malloc(program->framebuffer_count * sizeof(GLuint));
|
||||
|
||||
glGenFramebuffers(program->frag_count, program->frame_buffers);
|
||||
glGenFramebuffers(program->framebuffer_count, program->frame_buffers);
|
||||
|
||||
for (i = 0; i < program->frag_count; i++) {
|
||||
for (i = 0; i < program->framebuffer_count; i++) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, program->frame_buffers[i]);
|
||||
|
||||
for (j = 0; j < TEX_COUNT; j++) {
|
||||
@@ -111,18 +111,6 @@ static void init_shaders(ShaderProgram *program, File *fragment_shaders) {
|
||||
program->error |= !compile_shader(
|
||||
program->vertex_shader, "internal vertex shader", vertex_shader_text);
|
||||
|
||||
// compile output fragment shader
|
||||
program->output_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
program->error |=
|
||||
!compile_shader(program->output_shader,
|
||||
"internal fragment shader (output)", output_shader_text);
|
||||
|
||||
// compile output fragment shader
|
||||
program->monitor_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
program->error |= !compile_shader(program->monitor_shader,
|
||||
"internal fragment shader (monitor)",
|
||||
monitor_shader_text);
|
||||
|
||||
program->fragment_shaders = malloc(program->frag_count * sizeof(GLuint));
|
||||
|
||||
// compile fragment shaders
|
||||
@@ -139,49 +127,42 @@ static void init_shaders(ShaderProgram *program, File *fragment_shaders) {
|
||||
}
|
||||
|
||||
static void init_single_program(ShaderProgram *program, unsigned int i,
|
||||
ConfigFile shader_config, bool output) {
|
||||
ConfigFile shader_config) {
|
||||
unsigned int j;
|
||||
char name[32];
|
||||
|
||||
program->programs[i] = glCreateProgram();
|
||||
|
||||
glAttachShader(program->programs[i], program->vertex_shader);
|
||||
|
||||
if (output) {
|
||||
glAttachShader(program->programs[i], program->monitor_shader); // TODO tmp
|
||||
} else {
|
||||
glAttachShader(program->programs[i], program->fragment_shaders[i]);
|
||||
}
|
||||
glAttachShader(program->programs[i], program->fragment_shaders[i]);
|
||||
glLinkProgram(program->programs[i]);
|
||||
|
||||
// create uniforms pointers
|
||||
if (!output) {
|
||||
program->itime_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_TIME", "iTime"));
|
||||
program->itempo_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_TEMPO", "iTempo"));
|
||||
program->ifps_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_FPS", "iFPS"));
|
||||
program->ires_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_RESOLUTION",
|
||||
"iResolution"));
|
||||
program->itime_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_TIME", "iTime"));
|
||||
program->itempo_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_TEMPO", "iTempo"));
|
||||
program->ifps_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_FPS", "iFPS"));
|
||||
program->ires_locations[i] = glGetUniformLocation(
|
||||
program->programs[i],
|
||||
config_file_get_str(shader_config, "UNIFORM_RESOLUTION", "iResolution"));
|
||||
|
||||
for (j = 0; j < SUB_COUNT; j++) {
|
||||
sprintf(name, "src_%d", j + 1);
|
||||
program->sub_src_indexes[i][j] =
|
||||
// TODO sub substitution
|
||||
for (j = 0; j < SUB_COUNT; j++) {
|
||||
sprintf(name, "src_%d", j + 1);
|
||||
program->sub_src_indexes[i][j] =
|
||||
glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name);
|
||||
sprintf(name, "fx_%d", j + 1);
|
||||
program->sub_fx_indexes[i][j] =
|
||||
glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name);
|
||||
if (j < 2) {
|
||||
sprintf(name, "mix_%d", j + 1);
|
||||
program->sub_mix_indexes[i][j] =
|
||||
glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name);
|
||||
sprintf(name, "fx_%d", j + 1);
|
||||
program->sub_fx_indexes[i][j] =
|
||||
glGetSubroutineIndex(program->programs[i], GL_FRAGMENT_SHADER, name);
|
||||
if (j < 2) {
|
||||
sprintf(name, "mix_%d", j + 1);
|
||||
program->sub_mix_indexes[i][j] = glGetSubroutineIndex(
|
||||
program->programs[i], GL_FRAGMENT_SHADER, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,8 +201,8 @@ static void init_programs(ShaderProgram *program, ConfigFile shader_config) {
|
||||
malloc(program->frag_count * sizeof(GLuint));
|
||||
}
|
||||
|
||||
for (i = 0; i < program->frag_count + 1; i++) {
|
||||
init_single_program(program, i, shader_config, i == program->frag_count);
|
||||
for (i = 0; i < program->frag_count; i++) {
|
||||
init_single_program(program, i, shader_config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,6 +222,11 @@ ShaderProgram shaders_init(File *fragment_shaders, ConfigFile shader_config,
|
||||
program.last_width = context.width;
|
||||
program.last_height = context.height;
|
||||
program.frag_count = config_file_get_int(shader_config, "FRAG_COUNT", 6);
|
||||
program.framebuffer_count = program.frag_count - 2;
|
||||
program.frag_output_index =
|
||||
config_file_get_int(shader_config, "FRAG_OUT", 0) - 1;
|
||||
program.frag_monitor_index =
|
||||
config_file_get_int(shader_config, "FRAG_MONITOR", 0) - 1;
|
||||
|
||||
init_textures(&program, context);
|
||||
|
||||
@@ -313,22 +299,21 @@ static void use_program(ShaderProgram program, int i, bool output,
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
} else {
|
||||
// use memory framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[0]);
|
||||
|
||||
// set fragment uniforms
|
||||
glUniform1f(program.itime_locations[i], (const GLfloat)context.time);
|
||||
glUniform1f(program.itempo_locations[i],
|
||||
(const GLfloat)120.0f); // TODO TMP
|
||||
glUniform1i(program.ifps_locations[i], (const GLint)context.fps);
|
||||
glUniform2fv(program.ires_locations[i], 1, (const GLfloat *)&resolution);
|
||||
|
||||
// TODO tmp
|
||||
subroutines[0] = program.sub_src_indexes[i][i == 0 ? 1 : 2];
|
||||
subroutines[1] = program.sub_fx_indexes[i][0];
|
||||
subroutines[2] = program.sub_mix_indexes[i][0];
|
||||
|
||||
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 3, subroutines);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]);
|
||||
}
|
||||
// set fragment uniforms
|
||||
glUniform1f(program.itime_locations[i], (const GLfloat)context.time);
|
||||
glUniform1f(program.itempo_locations[i],
|
||||
(const GLfloat)120.0f); // TODO TMP
|
||||
glUniform1i(program.ifps_locations[i], (const GLint)context.fps);
|
||||
glUniform2fv(program.ires_locations[i], 1, (const GLfloat *)&resolution);
|
||||
|
||||
// TODO tmp
|
||||
subroutines[0] = program.sub_src_indexes[i][i == 0 ? 1 : 2];
|
||||
subroutines[1] = program.sub_fx_indexes[i][0];
|
||||
subroutines[2] = program.sub_mix_indexes[i][0];
|
||||
|
||||
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 3, subroutines);
|
||||
|
||||
// set GL_TEXTURE(X) to uniform sampler2D texX
|
||||
for (j = 0; j < TEX_COUNT; j++) {
|
||||
@@ -347,6 +332,10 @@ void shaders_apply(ShaderProgram program, Context context) {
|
||||
update_viewport(program, context);
|
||||
|
||||
for (i = 0; i < program.frag_count + 1; i++) {
|
||||
use_program(program, i, i == program.frag_count, context);
|
||||
if (i != program.frag_output_index && i != program.frag_monitor_index) {
|
||||
use_program(program, i, false, context);
|
||||
}
|
||||
}
|
||||
|
||||
use_program(program, program.frag_output_index, true, context);
|
||||
}
|
||||
|
||||
+7
-5
@@ -36,12 +36,14 @@ typedef struct ShaderProgram {
|
||||
int last_height;
|
||||
|
||||
unsigned int frag_count;
|
||||
unsigned int frag_output_index;
|
||||
unsigned int frag_monitor_index;
|
||||
|
||||
unsigned int framebuffer_count;
|
||||
|
||||
GLuint *programs;
|
||||
|
||||
GLuint vertex_shader;
|
||||
GLuint output_shader;
|
||||
GLuint monitor_shader;
|
||||
|
||||
GLuint *fragment_shaders;
|
||||
|
||||
@@ -52,9 +54,9 @@ typedef struct ShaderProgram {
|
||||
|
||||
GLuint *textures_locations[TEX_COUNT];
|
||||
|
||||
GLuint sub_src_indexes[6][SUB_COUNT]; // TODO change
|
||||
GLuint sub_fx_indexes[6][SUB_COUNT];
|
||||
GLuint sub_mix_indexes[6][2];
|
||||
GLuint sub_src_indexes[8][SUB_COUNT]; // TODO change
|
||||
GLuint sub_fx_indexes[8][SUB_COUNT];
|
||||
GLuint sub_mix_indexes[8][2];
|
||||
|
||||
GLuint *vpos_locations;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user