195 lines
5.0 KiB
C
195 lines
5.0 KiB
C
|
|
#include "program.h"
|
|
|
|
unsigned int
|
|
program_use (int program)
|
|
{
|
|
glUseProgram (program);
|
|
return program;
|
|
}
|
|
|
|
void
|
|
shader_fail (int shader)
|
|
{
|
|
int info_len;
|
|
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &info_len);
|
|
int shader_type;
|
|
glGetShaderiv (shader, GL_SHADER_TYPE, &shader_type);
|
|
const char *type = shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment";
|
|
|
|
if (info_len > 1)
|
|
{
|
|
char *info = malloc (sizeof (char) * info_len);
|
|
glGetShaderInfoLog (shader, info_len, NULL, info);
|
|
WARN ("Compiling %s shader failed:\n%s", type, info);
|
|
free (info);
|
|
}
|
|
else
|
|
{
|
|
WARN ("Compiling %s shader failed without information.", type);
|
|
}
|
|
}
|
|
|
|
void
|
|
program_fail (int program)
|
|
{
|
|
int info_len;
|
|
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &info_len);
|
|
|
|
if (info_len > 1)
|
|
{
|
|
char *info = malloc (sizeof (char) * info_len);
|
|
glGetProgramInfoLog (program, info_len, NULL, info);
|
|
WARN ("Linking program failed:\n%s", info);
|
|
free (info);
|
|
}
|
|
else
|
|
{
|
|
WARN ("Linking program failed without information.");
|
|
}
|
|
}
|
|
|
|
unsigned int
|
|
program_create (const char *v_src, const char *f_src)
|
|
{
|
|
int success = 0;
|
|
|
|
int vertex = glCreateShader (GL_VERTEX_SHADER);
|
|
glShaderSource (vertex, 1, &v_src, NULL);
|
|
glCompileShader (vertex);
|
|
glGetShaderiv (vertex, GL_COMPILE_STATUS, &success);
|
|
if (!success) shader_fail (vertex);
|
|
|
|
int fragment = glCreateShader (GL_FRAGMENT_SHADER);
|
|
glShaderSource (fragment, 1, &f_src, NULL);
|
|
glCompileShader (fragment);
|
|
glGetShaderiv (fragment, GL_COMPILE_STATUS, &success);
|
|
if (!success) shader_fail (fragment);
|
|
|
|
int program = glCreateProgram ();
|
|
glAttachShader (program, vertex);
|
|
glAttachShader (program, fragment);
|
|
glLinkProgram (program);
|
|
glGetProgramiv (program, GL_LINK_STATUS, &success);
|
|
if (!success) program_fail (program);
|
|
else INFO ("Compiled shaders and linked program %d successfuly.", program);
|
|
|
|
glDeleteShader (vertex);
|
|
glDeleteShader (fragment);
|
|
|
|
return program;
|
|
}
|
|
|
|
void
|
|
program_set_vec3 (int program, const char *name, vec3 value)
|
|
{
|
|
glUniform3f (glGetUniformLocation (program, name), value[0], value[1], value[2]);
|
|
}
|
|
|
|
void
|
|
program_set_vec4 (int program, const char *name, vec4 value)
|
|
{
|
|
glUniform4f (glGetUniformLocation (program, name), value[0], value[1], value[2], value[3]);
|
|
}
|
|
|
|
void
|
|
program_set_vec3_ind (int program, const char *name, float x, float y, float z)
|
|
{
|
|
glUniform3f (glGetUniformLocation (program, name), x, y, z);
|
|
}
|
|
|
|
void
|
|
program_set_float (int program, const char *name, float value)
|
|
{
|
|
glUniform1f (glGetUniformLocation (program, name), value);
|
|
}
|
|
|
|
void
|
|
program_set_int_array (int program, const char *name, size_t count, int *value)
|
|
{
|
|
glUniform1iv (glGetUniformLocation (program, name), count, value);
|
|
}
|
|
|
|
void
|
|
program_set_mat3 (int program, const char *name, mat3 value)
|
|
{
|
|
glUniformMatrix3fv (glGetUniformLocation (program, name), 1, GL_FALSE, (float *) value);
|
|
}
|
|
|
|
void
|
|
program_set_mat4 (int program, const char *name, mat4 value)
|
|
{
|
|
glUniformMatrix4fv (glGetUniformLocation (program, name), 1, GL_FALSE, (float *) value);
|
|
}
|
|
|
|
static const char *
|
|
gl_type_to_string (GLenum type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case GL_FLOAT: return "float";
|
|
case GL_FLOAT_VEC3: return "vec3";
|
|
case GL_FLOAT_VEC4: return "vec4";
|
|
case GL_INT: return "int";
|
|
case GL_INT_VEC3: return "ivec3";
|
|
case GL_INT_VEC4: return "ivec4";
|
|
case GL_BOOL: return "bool";
|
|
case GL_FLOAT_MAT4: return "mat4";
|
|
case GL_SAMPLER_2D: return "sampler2D";
|
|
default: return "unknown type";
|
|
}
|
|
}
|
|
|
|
void
|
|
program_print (int program)
|
|
/* This function assumes that `program' is the active program. */
|
|
{
|
|
INFO ("== Program %d ==", program);
|
|
|
|
int attr_len;
|
|
glGetProgramiv (program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attr_len);
|
|
char attr[attr_len];
|
|
|
|
int attribute_no;
|
|
glGetProgramiv (program, GL_ACTIVE_ATTRIBUTES, &attribute_no);
|
|
|
|
GLenum type;
|
|
|
|
for (GLint i = 0; i < attribute_no; i++) {
|
|
glGetActiveAttrib (program, i, attr_len, NULL, NULL, &type, attr);
|
|
INFO ("Attribute #%d: %s %s", i, gl_type_to_string (type), attr);
|
|
}
|
|
|
|
int uniform_len;
|
|
glGetProgramiv (program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_len);
|
|
char uniform[uniform_len];
|
|
|
|
int uniform_no;
|
|
glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_no);
|
|
|
|
float *vec = malloc (sizeof (float) * 4);
|
|
|
|
for (GLint i = 0; i < uniform_no; i++) {
|
|
glGetActiveUniform (program, i, uniform_len, NULL, NULL, &type, uniform);
|
|
|
|
switch (type)
|
|
{
|
|
case GL_FLOAT_VEC3:
|
|
glGetUniformfv (program, glGetUniformLocation (program, uniform), vec);
|
|
INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type),
|
|
uniform, vec[0], vec[1], vec[2]);
|
|
break;
|
|
case GL_FLOAT_VEC4:
|
|
glGetUniformfv (program, glGetUniformLocation (program, uniform), vec);
|
|
INFO ("Uniform #%d: %s %s = (%5.1f,%5.1f,%5.1f,%5.1f)", i, gl_type_to_string (type),
|
|
uniform, vec[0], vec[1], vec[2], vec[3]);
|
|
break;
|
|
default:
|
|
INFO ("Uniform #%d: %s %s", i, gl_type_to_string (type), uniform);
|
|
break;
|
|
}
|
|
}
|
|
|
|
free (vec);
|
|
}
|