1
0
mirror of https://github.com/danog/Telegram.git synced 2025-01-06 04:58:56 +01:00
Telegram/thirdparty/RMIntro/core/shader.c
2014-07-10 18:11:09 +04:00

111 lines
3.1 KiB
C
Executable File

#include "shader.h"
#include "platform_gl.h"
#include "platform_log.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define TAG "shaders"
static void log_v_fixed_length(const GLchar* source, const GLint length) {
if (LOGGING_ON) {
char log_buffer[length + 1];
memcpy(log_buffer, source, length);
log_buffer[length] = '\0';
DEBUG_LOG_WRITE_V(TAG, log_buffer);
}
}
static void log_shader_info_log(GLuint shader_object_id) {
if (LOGGING_ON) {
GLint log_length;
glGetShaderiv(shader_object_id, GL_INFO_LOG_LENGTH, &log_length);
GLchar log_buffer[log_length];
glGetShaderInfoLog(shader_object_id, log_length, NULL, log_buffer);
DEBUG_LOG_WRITE_V(TAG, log_buffer);
}
}
static void log_program_info_log(GLuint program_object_id) {
if (LOGGING_ON) {
GLint log_length;
glGetProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &log_length);
GLchar log_buffer[log_length];
glGetProgramInfoLog(program_object_id, log_length, NULL, log_buffer);
DEBUG_LOG_WRITE_V(TAG, log_buffer);
}
}
GLuint compile_shader(const GLenum type, const GLchar* source, const GLint length) {
assert(source != NULL);
GLuint shader_object_id = glCreateShader(type);
GLint compile_status;
assert(shader_object_id != 0);
glShaderSource(shader_object_id, 1, (const GLchar **)&source, &length);
glCompileShader(shader_object_id);
glGetShaderiv(shader_object_id, GL_COMPILE_STATUS, &compile_status);
if (LOGGING_ON) {
DEBUG_LOG_WRITE_D(TAG, "Results of compiling shader source:");
log_v_fixed_length(source, length);
log_shader_info_log(shader_object_id);
}
assert(compile_status != 0);
return shader_object_id;
}
GLuint link_program(const GLuint vertex_shader, const GLuint fragment_shader) {
GLuint program_object_id = glCreateProgram();
GLint link_status;
assert(program_object_id != 0);
glAttachShader(program_object_id, vertex_shader);
glAttachShader(program_object_id, fragment_shader);
glLinkProgram(program_object_id);
glGetProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
if (LOGGING_ON) {
DEBUG_LOG_WRITE_D(TAG, "Results of linking program:");
log_program_info_log(program_object_id);
}
assert(link_status != 0);
return program_object_id;
}
GLuint build_program(
const GLchar * vertex_shader_source, const GLint vertex_shader_source_length,
const GLchar * fragment_shader_source, const GLint fragment_shader_source_length) {
assert(vertex_shader_source != NULL);
assert(fragment_shader_source != NULL);
GLuint vertex_shader = compile_shader(
GL_VERTEX_SHADER, vertex_shader_source, vertex_shader_source_length);
GLuint fragment_shader = compile_shader(
GL_FRAGMENT_SHADER, fragment_shader_source, fragment_shader_source_length);
return link_program(vertex_shader, fragment_shader);
}
GLint validate_program(const GLuint program) {
if (LOGGING_ON) {
int validate_status;
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &validate_status);
DEBUG_LOG_PRINT_D(TAG, "Results of validating program: %d", validate_status);
log_program_info_log(program);
return validate_status;
}
return 0;
}