class RubyGL::Shader

Public Class Methods

new(vert_src, frag_src) click to toggle source
# File lib/rubygl/shader.rb, line 6
def initialize(vert_src, frag_src)
    @v_shader_id = Native.glCreateShader(Native::GL_VERTEX_SHADER)
    @f_shader_id = Native.glCreateShader(Native::GL_FRAGMENT_SHADER)
    @attrib_locs, @uniform_locs = {}, {}
    
    # Pointer Used To Point To The String Of Our Source Code
    shader_src_ptr = FFI::MemoryPointer.new(:pointer)
    shader_src_len = FFI::MemoryPointer.new(:int)
    
    v_shader_ptr = FFI::MemoryPointer.from_string(vert_src)
    f_shader_ptr = FFI::MemoryPointer.from_string(frag_src)
    
    shader_src_ptr.write_pointer(v_shader_ptr.address)
    shader_src_len.write_int(vert_src.size)
    Native.glShaderSource(@v_shader_id, 1, shader_src_ptr, shader_src_len)
    
    shader_src_ptr.write_pointer(f_shader_ptr.address)
    shader_src_len.write_int(frag_src.size)
    Native.glShaderSource(@f_shader_id, 1, shader_src_ptr, shader_src_len)
    
    Native.glCompileShader(@v_shader_id)
    Native.glCompileShader(@f_shader_id)
    
    # Throw Exception With Compile Error If Compilation Failed
    Shader.compile_status(@v_shader_id)
    Shader.compile_status(@f_shader_id)
    
    @program_id = Native.glCreateProgram()
    
    Native.glAttachShader(@program_id, @v_shader_id)
    Native.glAttachShader(@program_id, @f_shader_id)
    
    Native.glLinkProgram(@program_id)
    
    Shader.link_status(@program_id)
end

Private Class Methods

compile_status(shader_id) click to toggle source
# File lib/rubygl/shader.rb, line 72
def self.compile_status(shader_id)
    result = FFI::MemoryPointer.new(:int)
    Native.glGetShaderiv(shader_id, Native::GL_COMPILE_STATUS, result)
    
    if (result.get_int(0) != Native::GL_TRUE) then
        Native.glGetShaderiv(shader_id, Native::GL_INFO_LOG_LENGTH, result)
        
        compile_log = FFI::MemoryPointer.new(:char, result.get_int(0))
        
        Native.glGetShaderInfoLog(shader_id, compile_log.total, FFI::MemoryPointer::NULL, compile_log)
        
        raise compile_log.read_string_to_null()
    end
end

Public Instance Methods

attrib_location(var_name) click to toggle source
# File lib/rubygl/shader.rb, line 63
def attrib_location(var_name)
    Native.glGetAttribLocation(@program_id, var_name)
end
send_uniform(method_sym, var_name, data = nil, *args) click to toggle source

Splat Operator Aggregates Incoming Parameters And Expands Outgoing Parameters If method_sym Does Not Accept A Pointer To The Data, Pass nil For data And Pass In The Normal Parameters Required For The Specific Method.

# File lib/rubygl/shader.rb, line 50
def send_uniform(method_sym, var_name, data = nil, *args)
    loc = @uniform_locs[var_name] ||= uniform_location(var_name)
    
    if data != nil then
        data_ptr = FFI::MemoryPointer.new(:float, data.size)
        data_ptr.write_array_of_float(data)
        
        RubyGL::Native.send(method_sym, loc, *args, data_ptr)
    else
        RubyGL::Native.send(method_sym, loc, *args)
    end
end
use_program() click to toggle source
# File lib/rubygl/shader.rb, line 43
def use_program()
    Native.glUseProgram(@program_id)
end

Private Instance Methods

uniform_location(var_name) click to toggle source
# File lib/rubygl/shader.rb, line 68
def uniform_location(var_name)
    Native.glGetUniformLocation(@program_id, var_name)
end