jes-ruby/src/GLShader.cc
2014-07-22 18:51:38 -04:00

105 lines
2.3 KiB
C++

#include "GLShader.h"
typedef struct
{
GLuint id;
} GLShader;
static VALUE ruby_class;
static const char * get_shader_type_name(GLenum shader_type)
{
switch (shader_type)
{
case GL_VERTEX_SHADER:
return "vertex";
case GL_FRAGMENT_SHADER:
return "fragment";
default:
return "unknown";
}
}
static GLuint create_shader(GLenum shader_type, const char *source, size_t size)
{
GLuint id = glCreateShader(shader_type);
if (id > 0)
{
GLint status;
GLint length = size;
glShaderSource(id, 1, &source, &length);
glCompileShader(id);
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE)
{
return true;
}
GLint log_length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char log[log_length + 1];
glGetShaderInfoLog(id, log_length, &log_length, log);
log[log_length] = '\0';
glDeleteShader(id);
rb_raise(rb_eRuntimeError,
"Error compiling %s shader:\n%s\n%s\n%s\n",
get_shader_type_name(shader_type),
"--------------------",
log,
"--------------------");
}
else
{
glDeleteShader(id);
rb_raise(rb_eRuntimeError,
"Error compiling %s shader",
get_shader_type_name(shader_type));
}
}
return id;
}
static void GLShader_free(void * ptr)
{
GLShader * glshader = (GLShader *)ptr;
if (glshader->id > 0)
{
glDeleteShader(glshader->id);
}
delete glshader;
}
static VALUE GLShader_new(VALUE klass, VALUE type, VALUE source)
{
GLShader * glshader = new GLShader();
#if 0
/* TODO */
glshader->id = create_shader();
#endif
return Data_Wrap_Struct(klass, NULL, GLShader_free, glshader);
}
void GLShader_Init()
{
ruby_class = rb_define_class("GLShader", rb_cObject);
rb_define_singleton_method(ruby_class, "new", (VALUE(*)(...))GLShader_new, 2);
}
GLuint GLShader_id(VALUE shader)
{
GLShader * glshader;
Data_Get_Struct(shader, GLShader, glshader);
return glshader->id;
}