Class: Glslkit::WebGL::Program

Inherits:
Object
  • Object
show all
Defined in:
lib/glslkit/webgl/program.rb

Constant Summary collapse

LOG_LINE_PATTERNS =
[
  /(?:ERROR|WARNING):\s*\d+:(\d+):\s*(.*)/,
  /\b\d+\((\d+)\)\s*:\s*(?:error|warning)?\s*(.*)/i
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gl, manifest_program, vertex:, fragment:, source_maps: {}, state: nil) ⇒ Program

Returns a new instance of Program.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/glslkit/webgl/program.rb', line 13

def initialize(gl, manifest_program, vertex:, fragment:, source_maps: {}, state: nil)
  @gl = gl
  @state = state || {program: nil}
  @manifest_program = manifest_program
  @source_maps = source_maps
  @handle = build(vertex, fragment)
  @uniform_indices = {}
  @uniform_locations = []
  @uniform_setters = []
  @uniform_matrix = []
  @uniform_lengths = []
  @uniform_buffers = []
  prepare_uniforms
  prepare_attributes
end

Instance Attribute Details

#attribute_locationsObject (readonly)

Returns the value of attribute attribute_locations.



11
12
13
# File 'lib/glslkit/webgl/program.rb', line 11

def attribute_locations
  @attribute_locations
end

#handleObject (readonly)

Returns the value of attribute handle.



11
12
13
# File 'lib/glslkit/webgl/program.rb', line 11

def handle
  @handle
end

Instance Method Details

#restore_uniforms_from(old_program) ⇒ Object

reload後、旧Program(old_program)が持っていたuniform値を自分自身に 復元する。名前・type・element_countがすべて一致するものだけを復元し、 一致しないものは戻り値に集めて呼び出し側(Context)に返す。R4には 反しない(初期化時1回の書き込みであり、毎フレームの再確保ではない)。



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/glslkit/webgl/program.rb', line 78

def restore_uniforms_from(old_program)
  new_snapshot = uniform_snapshot
  discarded = []

  old_program.uniform_snapshot.each do |name, old_entry|
    new_entry = new_snapshot[name]
    if new_entry.nil?
      discarded << {name: name, reason: :removed}
    elsif new_entry[:type] != old_entry[:type] || new_entry[:element_count] != old_entry[:element_count]
      discarded << {name: name, reason: :type_changed, from: old_entry[:type], to: new_entry[:type]}
    else
      set(name, old_entry[:values])
    end
  end

  discarded
end

#set(name, value) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/glslkit/webgl/program.rb', line 37

def set(name, value)
  index = @uniform_indices[name.to_sym]
  raise UnknownUniformError, "uniform not found in manifest: #{name}" unless index

  location = @uniform_locations[index]
  return self if null_location?(location)

  use
  buffer = @uniform_buffers[index]
  expected = @uniform_lengths[index]
  copy_value(buffer, value, expected, name)
  setter = @uniform_setters[index]
  if @uniform_matrix[index]
    @gl.call(setter, location, false, buffer)
  else
    @gl.call(setter, location, buffer)
  end
  self
end

#uniform_snapshotObject

M11d: reload時にuniform値を引き継ぐため(SPEC-livereload.md §4.3)の、 名前ごとの現在値スナップショット。=> {type:, element_count:, values:}。 typeは互換性判定にのみ使う(値そのものには使わない)。



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/glslkit/webgl/program.rb', line 60

def uniform_snapshot
  @manifest_program.fetch("uniforms").each_with_object({}) do |uniform, snapshot|
    name = uniform.fetch("name").to_sym
    index = @uniform_indices.fetch(name)
    count = @uniform_lengths[index]
    buffer = @uniform_buffers[index]
    snapshot[name] = {
      type: uniform.fetch("type"),
      element_count: count,
      values: Array.new(count) { |i| buffer[i].to_f }
    }
  end
end

#useObject



29
30
31
32
33
34
35
# File 'lib/glslkit/webgl/program.rb', line 29

def use
  unless @state[:program].equal?(@handle)
    @gl.call(:useProgram, @handle)
    @state[:program] = @handle
  end
  self
end