Class: Engine::Shader

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(vertex_shader, fragment_shader) ⇒ Shader

Returns a new instance of Shader.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/engine/shader.rb', line 31

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

Class Method Details

.defaultObject



3
4
5
# File 'lib/engine/shader.rb', line 3

def self.default
  @default ||= Shader.new('./shaders/mesh_vertex.glsl', './shaders/mesh_frag.glsl')
end

.skyboxObject



11
12
13
# File 'lib/engine/shader.rb', line 11

def self.skybox
  @skybox ||= Shader.new('./shaders/skybox_vert.glsl', './shaders/skybox_frag.glsl')
end

.spriteObject



15
16
17
# File 'lib/engine/shader.rb', line 15

def self.sprite
  @sprite ||= Engine::Shader.new('./shaders/sprite_vertex.glsl', './shaders/sprite_frag.glsl')
end

.textObject



19
20
21
# File 'lib/engine/shader.rb', line 19

def self.text
  @text ||= Engine::Shader.new('./shaders/text_vertex.glsl', './shaders/text_frag.glsl')
end

.ui_spriteObject



27
28
29
# File 'lib/engine/shader.rb', line 27

def self.ui_sprite
  @ui_sprite ||= Engine::Shader.new('./shaders/ui_sprite_vertex.glsl', './shaders/ui_sprite_frag.glsl')
end

.ui_textObject



23
24
25
# File 'lib/engine/shader.rb', line 23

def self.ui_text
  @ui_text ||= Engine::Shader.new('./shaders/text_vertex.glsl', './shaders/text_frag.glsl')
end

.vertex_litObject



7
8
9
# File 'lib/engine/shader.rb', line 7

def self.vertex_lit
  @vertex_lit ||= Engine::Shader.new('./shaders/vertex_lit_vertex.glsl', './shaders/vertex_lit_frag.glsl')
end

Instance Method Details

#compile_shader(shader, type) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/engine/shader.rb', line 58

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



107
108
109
110
111
# File 'lib/engine/shader.rb', line 107

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



101
102
103
104
105
# File 'lib/engine/shader.rb', line 101

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



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/engine/shader.rb', line 89

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



72
73
74
75
76
77
78
79
80
81
# File 'lib/engine/shader.rb', line 72

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



83
84
85
86
87
# File 'lib/engine/shader.rb', line 83

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



68
69
70
# File 'lib/engine/shader.rb', line 68

def use
  GL.UseProgram(@program)
end