freetype2gl3/GLProgram.cc

100 lines
2.4 KiB
C++

#include "GLProgram.h"
#include <stdint.h>
#include <iostream>
using namespace std;
GLProgram::GLProgram()
{
m_id = 0;
}
GLProgram::~GLProgram()
{
if (m_id > 0)
{
glDeleteProgram(m_id);
}
}
bool GLProgram::create(const char *v_source, const char *f_source, ...)
{
va_list va;
va_start(va, f_source);
bool rv = createv(v_source, f_source, va);
va_end(va);
return rv;
}
bool GLProgram::create(const uint8_t *v_source, const uint8_t *f_source, ...)
{
va_list va;
va_start(va, f_source);
bool rv = createv((const char *) v_source, (const char *) f_source, va);
va_end(va);
return rv;
}
bool GLProgram::createv(const char *v_source, const char *f_source, va_list va)
{
if (v_source == NULL || f_source == NULL)
return false;
if (!m_v_shader.create(GL_VERTEX_SHADER, v_source))
{
cerr << "Failed vertex shader source:" << endl << v_source << endl;
return false;
}
if (!m_f_shader.create(GL_FRAGMENT_SHADER, f_source))
{
cerr << "Failed fragment shader source:" << endl << f_source << endl;
return false;
}
m_id = glCreateProgram();
if (m_id <= 0)
{
cerr << "Error allocating GL program object" << endl;
return false;
}
glAttachShader(m_id, m_v_shader.get_id());
glAttachShader(m_id, m_f_shader.get_id());
for (;;)
{
const char *attribute_name = va_arg(va, const char *);
if (attribute_name == NULL)
break;
GLuint attribute_index = va_arg(va, uint32_t);
glBindAttribLocation(m_id, attribute_index, attribute_name);
}
glLinkProgram(m_id);
GLint link_status;
glGetProgramiv(m_id, GL_LINK_STATUS, &link_status);
if (link_status != GL_TRUE)
{
GLint log_length;
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char *log = new char[log_length];
glGetProgramInfoLog(m_id, log_length, &log_length, log);
cerr << "Program log:" << endl << log << endl;
delete[] log;
}
return false;
}
for (;;)
{
const char *uniform_name = va_arg(va, const char *);
if (uniform_name == NULL)
break;
GLint loc = glGetUniformLocation(m_id, uniform_name);
m_uniform_locations.push_back(loc);
m_uniform_location_names[uniform_name] = loc;
}
return true;
}