forked from goliath/shadermeh
David Oberhollenzer
8c47f2726c
Texture channel 0 has a 512x2 texture with audio samples. For now, fill it with dummy data (ascending slope), so we can see some output. Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
188 lines
3.5 KiB
C
188 lines
3.5 KiB
C
/* SPDX-License-Identifier: ISC */
|
|
/*
|
|
* shader.c
|
|
*
|
|
* Copyright (C) 2022 David Oberhollenzer <goliath@infraroot.at>
|
|
*/
|
|
#include "shadermeh.h"
|
|
|
|
/* stub vertex shader */
|
|
static const char *vert_src =
|
|
"#version 140\n"
|
|
"\n"
|
|
"in vec4 V_POSITION;\n"
|
|
"in vec4 V_COLOR;\n"
|
|
"\n"
|
|
"void main()\n"
|
|
"{\n"
|
|
" gl_Position = V_POSITION;\n"
|
|
"}\n";
|
|
|
|
/* stub fragment shader */
|
|
static const char *frag_src_pre =
|
|
"#version 330\n"
|
|
"\n"
|
|
"uniform vec3 iResolution;\n"
|
|
"uniform float iTime;\n"
|
|
"uniform float iTimeDelta;\n"
|
|
"uniform float iFrame;\n"
|
|
"uniform float iChannelTime[4];\n"
|
|
"uniform vec4 iMouse;\n"
|
|
"uniform vec4 iDate;\n"
|
|
"uniform float iSampleRate;\n"
|
|
"uniform vec3 iChannelResolution[4];\n"
|
|
"uniform sampler2D iChannel0;"
|
|
"\n";
|
|
|
|
static const char *frag_src_post =
|
|
"\n"
|
|
"void main()\n"
|
|
"{\n"
|
|
" mainImage(gl_FragColor, gl_FragCoord.xy);\n"
|
|
"}\n"
|
|
"\n";
|
|
|
|
static char* load_file(const char *path)
|
|
{
|
|
size_t size, pre_len, post_len;
|
|
char *buffer;
|
|
FILE *f;
|
|
|
|
if (!path)
|
|
return NULL;
|
|
|
|
/* try to open the file */
|
|
f = fopen(path, "r");
|
|
if (!f) {
|
|
perror(path);
|
|
return NULL;
|
|
}
|
|
|
|
/* get file size */
|
|
fseek(f, 0, SEEK_END);
|
|
size = ftell(f);
|
|
fseek(f, 0, SEEK_SET);
|
|
|
|
pre_len = strlen(frag_src_pre);
|
|
post_len = strlen(frag_src_post);
|
|
|
|
/* try to allocate buffer for file contents */
|
|
buffer = calloc(1, pre_len + size + post_len + 1);
|
|
|
|
if (!buffer) {
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
|
|
/* read file contents into buffer */
|
|
memcpy(buffer, frag_src_pre, pre_len);
|
|
fread(buffer + pre_len, 1, size, f);
|
|
memcpy(buffer + pre_len + size, frag_src_post, post_len);
|
|
|
|
/* cleanup */
|
|
fclose(f);
|
|
return buffer;
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
GLuint shader_program_load(const char *fsrc)
|
|
{
|
|
GLuint vsh = 0, fsh = 0, prog = 0;
|
|
char *fs = NULL;
|
|
|
|
if (!fsrc)
|
|
return 0;
|
|
|
|
fs = load_file(fsrc);
|
|
|
|
if (!fs)
|
|
goto done;
|
|
|
|
vsh = glCreateShader(GL_VERTEX_SHADER);
|
|
fsh = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
if (!vsh || !fsh)
|
|
goto done;
|
|
|
|
prog = glCreateProgram();
|
|
if (!prog)
|
|
goto done;
|
|
|
|
glShaderSource(vsh, 1, (const GLchar **)&vert_src, NULL);
|
|
glShaderSource(fsh, 1, (const GLchar **)&fs, NULL);
|
|
|
|
glCompileShader(vsh);
|
|
glCompileShader(fsh);
|
|
|
|
glAttachShader(prog, vsh);
|
|
glAttachShader(prog, fsh);
|
|
|
|
glLinkProgram(prog);
|
|
done:
|
|
if (vsh)
|
|
glDeleteShader(vsh);
|
|
if (fsh)
|
|
glDeleteShader(fsh);
|
|
free(fs);
|
|
return prog;
|
|
}
|
|
|
|
int shader_program_get_build_status(GLuint prog)
|
|
{
|
|
GLuint shaders[3];
|
|
GLsizei i, count;
|
|
GLint v;
|
|
|
|
glGetProgramiv(prog, GL_LINK_STATUS, &v);
|
|
if (!v)
|
|
return 0;
|
|
|
|
glGetAttachedShaders(prog, 3, &count, shaders);
|
|
|
|
for (i = 0; i < count; ++i) {
|
|
glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &v);
|
|
if (!v)
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void shader_program_print_info_log(GLuint prog)
|
|
{
|
|
GLsizei i, count, len;
|
|
char *buffer = NULL;
|
|
int buffersize = 0;
|
|
GLuint shaders[3];
|
|
GLint v;
|
|
|
|
glGetAttachedShaders(prog, 3, &count, shaders);
|
|
|
|
for (i = 0; i < count; ++i) {
|
|
glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &v);
|
|
|
|
if ((v + 1) > buffersize) {
|
|
buffer = realloc(buffer, v + 1);
|
|
buffersize = v + 1;
|
|
}
|
|
|
|
glGetShaderInfoLog(shaders[i], buffersize,
|
|
&len, (GLchar *)buffer);
|
|
buffer[len] = '\0';
|
|
printf("-------------\n%s\n-------------\n", buffer);
|
|
}
|
|
|
|
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &v);
|
|
|
|
if ((v + 1) > buffersize) {
|
|
buffer = realloc(buffer, v + 1);
|
|
buffersize = v + 1;
|
|
}
|
|
|
|
glGetProgramInfoLog(prog, buffersize, &len, (GLchar *)buffer);
|
|
buffer[len] = '\0';
|
|
printf("-------------\n%s\n-------------\n", buffer);
|
|
|
|
free(buffer);
|
|
}
|