Class: Engine::Shader

Inherits:
Object
  • Object
show all
Defined in:
lib/engine/shader.rb

Instance Method Summary collapse

Constructor Details

#initialize(vertex_shader, fragment_shader) ⇒ Shader

Returns a new instance of Shader.



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/engine/shader.rb', line 3

def initialize(vertex_shader, fragment_shader)
  @vertex_shader = compile_shader(vertex_shader, GL::VERTEX_SHADER)
  @fragment_shader = compile_shader(fragment_shader, GL::FRAGMENT_SHADER)
  @program = GL.CreateProgram
  GL.AttachShader(@program, @vertex_shader)
  GL.AttachShader(@program, @fragment_shader)
  GL.LinkProgram(@program)

  linked_buf = ' ' * 4
  GL.GetProgramiv(@program, GL::LINK_STATUS, linked_buf)
  linked = linked_buf.unpack('L')[0]
  if linked == 0
    compile_log = ' ' * 1024
    GL.GetProgramInfoLog(@program, 1023, nil, compile_log)
    vertex_log = ' ' * 1024
    GL.GetShaderInfoLog(@vertex_shader, 1023, nil, vertex_log)
    fragment_log = ' ' * 1024
    GL.GetShaderInfoLog(@fragment_shader, 1023, nil, fragment_log)
    puts "Shader program failed to link"
    puts compile_log.strip
    puts vertex_log.strip
    puts fragment_log.strip
  end
  @uniform_cache = {}
  @uniform_locations = {}
end

Instance Method Details

#compile_shader(shader, type) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/engine/shader.rb', line 30

def compile_shader(shader, type)
  handle = GL.CreateShader(type)
  path = File.join(File.dirname(__FILE__), shader)
  s_srcs = [File.read(path)].pack('p')
  s_lens = [File.size(path)].pack('I')
  GL.ShaderSource(handle, 1, s_srcs, s_lens)
  GL.CompileShader(handle)
  handle
end

#set_float(name, float) ⇒ Object



79
80
81
82
83
# File 'lib/engine/shader.rb', line 79

def set_float(name, float)
  return if @uniform_cache[name] == float
  @uniform_cache[name] = float
  GL.Uniform1f(uniform_location(name), float)
end

#set_int(name, int) ⇒ Object



73
74
75
76
77
# File 'lib/engine/shader.rb', line 73

def set_int(name, int)
  return if @uniform_cache[name] == int
  @uniform_cache[name] = int
  GL.Uniform1i(uniform_location(name), int)
end

#set_mat4(name, mat) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/engine/shader.rb', line 61

def set_mat4(name, mat)
  return if @uniform_cache[name] == mat
  @uniform_cache[name] = mat
  mat_array = [
    mat[0, 0], mat[0, 1], mat[0, 2], mat[0, 3],
    mat[1, 0], mat[1, 1], mat[1, 2], mat[1, 3],
    mat[2, 0], mat[2, 1], mat[2, 2], mat[2, 3],
    mat[3, 0], mat[3, 1], mat[3, 2], mat[3, 3]
  ]
  GL.UniformMatrix4fv(uniform_location(name), 1, GL::FALSE, mat_array.pack('F*'))
end

#set_vec3(name, vec) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/engine/shader.rb', line 44

def set_vec3(name, vec)
  return if @uniform_cache[name] == vec
  @uniform_cache[name] = vec
  vector = if vec.is_a?(Vector)
             vec
           else
             Vector[vec[:r], vec[:g], vec[:b]]
           end
  GL.Uniform3f(uniform_location(name), vector[0], vector[1], vector[2])
end

#set_vec4(name, vec) ⇒ Object



55
56
57
58
59
# File 'lib/engine/shader.rb', line 55

def set_vec4(name, vec)
  return if @uniform_cache[name] == vec
  @uniform_cache[name] = vec
  GL.Uniform4f(uniform_location(name), vec[0], vec[1], vec[2], vec[3])
end

#useObject



40
41
42
# File 'lib/engine/shader.rb', line 40

def use
  GL.UseProgram(@program)
end