Files
wschod/game/src/gl/program.c
T

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);
}