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