opengl-core 1.3.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +22 -0
- data/README.md +124 -0
- data/lib/opengl-core.rb +20 -8
- data/lib/opengl-core/gl-commands.rb +6892 -0
- data/lib/opengl-core/{gl_enums.rb → gl-enums.rb} +48 -6
- data/lib/opengl-core/gl-sym.rb +74 -0
- data/lib/opengl-core/gl-sym/fiddle-symbol-loader.rb +130 -0
- metadata +17 -25
- data/ext/opengl-core/extconf.rb +0 -3
- data/ext/opengl-core/opengl_stub.c +0 -56
- data/lib/opengl-core/aux.rb +0 -7
- data/lib/opengl-core/aux/buffer.rb +0 -44
- data/lib/opengl-core/aux/gl.rb +0 -238
- data/lib/opengl-core/aux/marked.rb +0 -66
- data/lib/opengl-core/aux/program.rb +0 -122
- data/lib/opengl-core/aux/shader.rb +0 -49
- data/lib/opengl-core/aux/texture.rb +0 -45
- data/lib/opengl-core/aux/vertex_array.rb +0 -43
- data/lib/opengl-core/gl_commands.rb +0 -8587
- data/lib/opengl-core/gl_sym.rb +0 -51
data/lib/opengl-core/aux.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require 'opengl-core/aux/gl'
|
2
|
-
require 'opengl-core/aux/marked'
|
3
|
-
|
4
|
-
class Gl::Buffer < Gl::GlInternalMarked
|
5
|
-
|
6
|
-
attr_reader :name
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
def initialize(target, name = nil)
|
10
|
-
super()
|
11
|
-
@name = (name != 0 && name) || 0
|
12
|
-
@target = target
|
13
|
-
__mark__ if @name != 0
|
14
|
-
end
|
15
|
-
|
16
|
-
def delete
|
17
|
-
if @name != 0
|
18
|
-
Gl.glDeleteBuffers(@name)
|
19
|
-
@name = 0
|
20
|
-
super
|
21
|
-
end
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
def bind(target = nil)
|
26
|
-
if @name == 0
|
27
|
-
@name = Gl.glGenBuffers(1)[0]
|
28
|
-
__mark__
|
29
|
-
end
|
30
|
-
Gl.glBindBuffer(target || @target, @name)
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.unbind(target)
|
35
|
-
Gl.glBindBuffer(target, 0)
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
def unbind(target = nil)
|
40
|
-
self.class.unbind(target || @target)
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
data/lib/opengl-core/aux/gl.rb
DELETED
@@ -1,238 +0,0 @@
|
|
1
|
-
require 'opengl-core'
|
2
|
-
|
3
|
-
module Gl
|
4
|
-
|
5
|
-
# @api private
|
6
|
-
UINT_BASE = { :packed => [0].pack('I!').freeze, :unpack => 'I!*' }
|
7
|
-
UINT16_BASE = { :packed => [0].pack('S').freeze, :unpack => 'S*' }
|
8
|
-
UINT32_BASE = { :packed => [0].pack('L').freeze, :unpack => 'L*' }
|
9
|
-
UINT64_BASE = { :packed => [0].pack('Q').freeze, :unpack => 'Q*' }
|
10
|
-
INT_BASE = { :packed => [0].pack('i!').freeze, :unpack => 'i!*' }
|
11
|
-
INT16_BASE = { :packed => [0].pack('s').freeze, :unpack => 's*' }
|
12
|
-
INT32_BASE = { :packed => [0].pack('l').freeze, :unpack => 'l*' }
|
13
|
-
INT64_BASE = { :packed => [0].pack('q').freeze, :unpack => 'q*' }
|
14
|
-
USHORT_BASE = { :packed => [0].pack('S!').freeze, :unpack => 'S!*' }
|
15
|
-
SHORT_BASE = { :packed => [0].pack('s!').freeze, :unpack => 's!*' }
|
16
|
-
FLOAT_BASE = { :packed => [0.0].pack('F').freeze, :unpack => 'F*' }
|
17
|
-
DOUBLE_BASE = { :packed => [0.0].pack('D').freeze, :unpack => 'D*' }
|
18
|
-
POINTER_BASE = case Fiddle::SIZEOF_VOIDP
|
19
|
-
when 2 then { :packed => [0.0].pack('S').freeze, :unpack => 'S*' }
|
20
|
-
when 4 then { :packed => [0.0].pack('L').freeze, :unpack => 'L*' }
|
21
|
-
when 8 then { :packed => [0.0].pack('Q').freeze, :unpack => 'Q*' }
|
22
|
-
else raise "Pointer size is incompatible with opengl-core"
|
23
|
-
end
|
24
|
-
|
25
|
-
# @api private
|
26
|
-
def self.__define_gl_gen_object_method__(name, type_base)
|
27
|
-
pack_string = type_base[:packed]
|
28
|
-
unpack_kind = type_base[:unpack]
|
29
|
-
|
30
|
-
self.module_exec(name, :"#{name}__", pack_string, unpack_kind) {
|
31
|
-
|func_name, raw_name, buffer_elem, pack_as|
|
32
|
-
define_method(func_name) {
|
33
|
-
|count|
|
34
|
-
output_buffer = buffer_elem * count
|
35
|
-
send(raw_name, count, output_buffer)
|
36
|
-
output_buffer.unpack(pack_as)
|
37
|
-
}
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
# @api private
|
42
|
-
def self.__define_gl_delete_object_method__(name, type_base)
|
43
|
-
unpack_kind = type_base[:unpack]
|
44
|
-
|
45
|
-
self.module_exec(name, :"#{name}__", unpack_kind) {
|
46
|
-
|func_name, raw_name, pack_as|
|
47
|
-
define_method(func_name) {
|
48
|
-
|objects|
|
49
|
-
objects = [objects] unless objects.kind_of?(Array)
|
50
|
-
input_buffer = objects.pack(pack_as)
|
51
|
-
send(raw_name, objects.length, input_buffer)
|
52
|
-
}
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
# @api private
|
57
|
-
def self.__define_gl_get_method__(name, type_base)
|
58
|
-
pack_string = type_base[:packed]
|
59
|
-
unpack_kind = type_base[:unpack]
|
60
|
-
|
61
|
-
self.module_exec(name, :"#{name}v__", pack_string, unpack_kind) {
|
62
|
-
|func_name, raw_name, buffer_elem, pack_as|
|
63
|
-
define_method(func_name) {
|
64
|
-
|pname|
|
65
|
-
output_buffer = String.new(buffer_elem)
|
66
|
-
send(raw_name, pname, output_buffer)
|
67
|
-
output_buffer.unpack(pack_as)[0]
|
68
|
-
}
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
# @!method self.glGenTextures(count)
|
74
|
-
# Returns an array of generated texture names.
|
75
|
-
__define_gl_gen_object_method__ :glGenTextures, UINT_BASE
|
76
|
-
# @!method self.glDeleteTextures(count, objects)
|
77
|
-
__define_gl_delete_object_method__ :glDeleteTextures, UINT_BASE
|
78
|
-
|
79
|
-
# @!method self.glGenVertexArrays(count)
|
80
|
-
# Returns an array of generated vertex array object names.
|
81
|
-
__define_gl_gen_object_method__ :glGenVertexArrays, UINT_BASE
|
82
|
-
# @!method self.glDeleteVertexArrays(count, objects)
|
83
|
-
__define_gl_delete_object_method__ :glDeleteVertexArrays, UINT_BASE
|
84
|
-
|
85
|
-
# @!method self.glGenBuffers(count)
|
86
|
-
# Returns an array of generated buffer object names.
|
87
|
-
__define_gl_gen_object_method__ :glGenBuffers, UINT_BASE
|
88
|
-
# @!method self.glDeleteBuffers(count, objects)
|
89
|
-
__define_gl_delete_object_method__ :glDeleteBuffers, UINT_BASE
|
90
|
-
|
91
|
-
# @!method self.glGenQueries(count)
|
92
|
-
# Returns an array of generated query object names.
|
93
|
-
__define_gl_gen_object_method__ :glGenQueries, UINT_BASE
|
94
|
-
# @!method self.glDeleteQueries(count, objects)
|
95
|
-
__define_gl_delete_object_method__ :glDeleteQueries, UINT_BASE
|
96
|
-
|
97
|
-
# @!method self.glGenSamplers(count)
|
98
|
-
# Returns an array of generated sampler object names.
|
99
|
-
__define_gl_gen_object_method__ :glGenSamplers, UINT_BASE
|
100
|
-
# @!method self.glDeleteSamplers(count, objects)
|
101
|
-
__define_gl_delete_object_method__ :glDeleteSamplers, UINT_BASE
|
102
|
-
|
103
|
-
# @!method self.glGenFramebuffers(count)
|
104
|
-
# Returns an array of generated framebuffer object names.
|
105
|
-
__define_gl_gen_object_method__ :glGenFramebuffers, UINT_BASE
|
106
|
-
# @!method self.glDeleteFramebuffers(count, objects)
|
107
|
-
__define_gl_delete_object_method__ :glDeleteFramebuffers, UINT_BASE
|
108
|
-
|
109
|
-
# @!method self.glGenRenderbuffers(count)
|
110
|
-
# Returns an array of generated renderbuffer object names.
|
111
|
-
__define_gl_gen_object_method__ :glGenRenderbuffers, UINT_BASE
|
112
|
-
# @!method self.glDeleteRenderbuffers(count, objects)
|
113
|
-
__define_gl_delete_object_method__ :glDeleteRenderbuffers, UINT_BASE
|
114
|
-
|
115
|
-
# @!method self.glGenRenderbuffersProgramPipelines(count)
|
116
|
-
# Returns an array of generated program pipeline object names.
|
117
|
-
__define_gl_gen_object_method__ :glGenProgramPipelines, UINT_BASE
|
118
|
-
# @!method self.glDeleteRenderbuffersProgramPipelines(count, objects)
|
119
|
-
__define_gl_delete_object_method__ :glDeleteProgramPipelines, UINT_BASE
|
120
|
-
|
121
|
-
# @!method self.glGenRenderbuffersTrasnformFeedbacks(count)
|
122
|
-
# Returns an array of generated transform feedback objects
|
123
|
-
__define_gl_gen_object_method__ :glGenTransformFeedbacks, UINT_BASE
|
124
|
-
# @!method self.glDeleteRenderbuffersTrasnformFeedbacks(count, objects)
|
125
|
-
__define_gl_delete_object_method__ :glDeleteTransformFeedbacks, UINT_BASE
|
126
|
-
|
127
|
-
__define_gl_get_method__ :glGetInteger, UINT_BASE
|
128
|
-
__define_gl_get_method__ :glGetInteger64, INT64_BASE
|
129
|
-
__define_gl_get_method__ :glGetFloat, FLOAT_BASE
|
130
|
-
__define_gl_get_method__ :glGetDouble, DOUBLE_BASE
|
131
|
-
|
132
|
-
# @return [Boolean] Returns the boolean value of the given parameter name.
|
133
|
-
def glGetBoolean(pname)
|
134
|
-
buffer = '0'
|
135
|
-
glGetBooleanv(pname, buffer)
|
136
|
-
!!buffer.unpack('C')[0]
|
137
|
-
end
|
138
|
-
|
139
|
-
# @return [String] Returns the string value of the given parameter name.
|
140
|
-
def glGetString(name)
|
141
|
-
glGetString__(name).to_s
|
142
|
-
end
|
143
|
-
|
144
|
-
# @return [String] Returns the string value of a parameter name at a given index.
|
145
|
-
def glGetStringi(name, index)
|
146
|
-
glGetStringi__(name, index).to_s
|
147
|
-
end
|
148
|
-
|
149
|
-
def glVertexAttribPointer(index, size, type, normalized, stride, offset)
|
150
|
-
offset = case offset
|
151
|
-
when Fiddle::Pointer then offset
|
152
|
-
when Numeric then Fiddle::Pointer.new(offset)
|
153
|
-
else offset
|
154
|
-
end
|
155
|
-
glVertexAttribPointer__ index, size, type, normalized, stride, offset
|
156
|
-
end
|
157
|
-
|
158
|
-
def glShaderSource(shader, sources)
|
159
|
-
sources = [sources] unless sources.kind_of?(Array)
|
160
|
-
source_lengths = sources.map { |s| s.bytesize }.pack('i*')
|
161
|
-
source_pointers = sources.pack('p')
|
162
|
-
glShaderSource__(shader, sources.length, source_pointers, source_lengths)
|
163
|
-
end
|
164
|
-
|
165
|
-
# Returns the version or release number. Calls glGetString.
|
166
|
-
def gl_version()
|
167
|
-
glGetString(GL_VERSION)
|
168
|
-
end
|
169
|
-
|
170
|
-
# Returns the implementation vendor. Calls glGetString.
|
171
|
-
def gl_vendor()
|
172
|
-
glGetString(GL_VENDOR)
|
173
|
-
end
|
174
|
-
|
175
|
-
# Returns the renderer. Calls glGetString.
|
176
|
-
def gl_renderer()
|
177
|
-
glGetString(GL_RENDERER)
|
178
|
-
end
|
179
|
-
|
180
|
-
# Returns the shading language version. Calls glGetString.
|
181
|
-
def gl_shading_language_version()
|
182
|
-
glGetString(GL_SHADING_LANGUAGE_VERSION)
|
183
|
-
end
|
184
|
-
|
185
|
-
# Gets an array of GL extensions. This calls glGetIntegerv and glGetStringi,
|
186
|
-
# so be aware that you should probably cache the results.
|
187
|
-
def gl_extensions()
|
188
|
-
(0 ... glGetInteger(GL_NUM_EXTENSIONS)).map { |index| glGetStringi(GL_EXTENSIONS, index) }
|
189
|
-
end
|
190
|
-
|
191
|
-
def glGetShader(shader, pname)
|
192
|
-
base = String.new(INT_BASE[:packed])
|
193
|
-
glGetShaderiv__(shader, pname, base)
|
194
|
-
base.unpack(INT_BASE[:unpack])[0]
|
195
|
-
end
|
196
|
-
|
197
|
-
def glGetShaderInfoLog(shader)
|
198
|
-
length = glGetShader(shader, GL_INFO_LOG_LENGTH)
|
199
|
-
return '' if length == 0
|
200
|
-
output = ' ' * length
|
201
|
-
glGetShaderInfoLog__(shader, output.bytesize, 0, output)
|
202
|
-
output
|
203
|
-
end
|
204
|
-
|
205
|
-
def glGetShaderSource(shader)
|
206
|
-
length = glGetShader(shader, GL_SHADER_SOURCE_LENGTH)
|
207
|
-
return '' if length == 0
|
208
|
-
output = ' ' * length
|
209
|
-
glGetShaderInfoLog__(shader, output.bytesize, 0, output)
|
210
|
-
output
|
211
|
-
end
|
212
|
-
|
213
|
-
def glGetProgram(program, pname)
|
214
|
-
base = String.new(INT_BASE[:packed])
|
215
|
-
glGetProgramiv__(program, pname, base)
|
216
|
-
base.unpack(INT_BASE[:unpack])[0]
|
217
|
-
end
|
218
|
-
|
219
|
-
def glGetProgramInfoLog(program)
|
220
|
-
length = glGetProgram(program, GL_INFO_LOG_LENGTH)
|
221
|
-
return '' if length == 0
|
222
|
-
output = ' ' * length
|
223
|
-
glGetProgramInfoLog__(program, output.bytesize, 0, output)
|
224
|
-
output
|
225
|
-
end
|
226
|
-
|
227
|
-
def glGetProgramBinary(program)
|
228
|
-
binary_length = glGetProgram(program, GL_PROGRAM_BINARY_LENGTH)
|
229
|
-
return [nil, nil] if binary_length == 0
|
230
|
-
format_buffer = String.new(UINT_BASE[:packed])
|
231
|
-
binary_buffer = ' ' * binary_length
|
232
|
-
glGetProgramBinary(program, binary_buffer.bytesize, 0, format_buffer, binary_buffer)
|
233
|
-
[format_buffer.unpack(UINT_BASE[:unpack])[0], binary_buffer]
|
234
|
-
end
|
235
|
-
|
236
|
-
extend self
|
237
|
-
|
238
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module Gl ; end
|
2
|
-
|
3
|
-
class Gl::GlInternalMarked
|
4
|
-
|
5
|
-
@@allocated__ = {}
|
6
|
-
|
7
|
-
def ==(other)
|
8
|
-
(self.kind_of?(other.class) || other.kind_of?(self.class)) && (self.name == other.name)
|
9
|
-
end
|
10
|
-
|
11
|
-
# Should be overridden by subclasses to handle freeing resources when marked.
|
12
|
-
# If unmarked, should be a no-op.
|
13
|
-
def delete
|
14
|
-
__unmark__
|
15
|
-
self
|
16
|
-
end
|
17
|
-
|
18
|
-
# Deletes all objects of the given type. Should be used carefully if at all.
|
19
|
-
def self.delete_all
|
20
|
-
__marked_allocated__.keys.each { |marked| marked.delete }
|
21
|
-
end
|
22
|
-
|
23
|
-
# Clears all marked objects. If deletion is already guaranteed for all marked
|
24
|
-
# objects, you may use this to let all marked objects of this type get GC'd.
|
25
|
-
def self.clear_all
|
26
|
-
__marked_allocated__.clear
|
27
|
-
end
|
28
|
-
|
29
|
-
# @api private
|
30
|
-
# Marks the class to prevent it from being garbage collected.
|
31
|
-
def __mark__
|
32
|
-
self.class.__marked_allocated__[self] = true
|
33
|
-
end
|
34
|
-
|
35
|
-
# @api private
|
36
|
-
# Unmarks the class and allows it to be garbage collected.
|
37
|
-
def __unmark__
|
38
|
-
self.class.__marked_allocated__.delete(self)
|
39
|
-
end
|
40
|
-
|
41
|
-
# @api private
|
42
|
-
# Returns whether the object is currently marked to keep it from being GC'd.
|
43
|
-
def marked?
|
44
|
-
self.class.__marked_allocated__.include?(self)
|
45
|
-
end
|
46
|
-
|
47
|
-
# @api private
|
48
|
-
# Allocates a hash for the subclass. This will be done regardless of whether
|
49
|
-
# this function is called.
|
50
|
-
def self.inherited(subclass)
|
51
|
-
@@allocated__[subclass] = @@allocated__[subclass] || {}
|
52
|
-
end
|
53
|
-
|
54
|
-
# @api private
|
55
|
-
# Returns a Hash of marked objects.
|
56
|
-
def self.__marked_allocated__
|
57
|
-
(@@allocated__[self.class] || (@@allocated__[self.class] = {}))
|
58
|
-
end
|
59
|
-
|
60
|
-
# @api private
|
61
|
-
# Returns all allocated marked objects for this class.
|
62
|
-
def self.allocated
|
63
|
-
__marked_allocated__.keys
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
@@ -1,122 +0,0 @@
|
|
1
|
-
require 'opengl-core/aux/gl'
|
2
|
-
require 'opengl-core/aux/marked'
|
3
|
-
|
4
|
-
# Needed even if the class isn't actually used
|
5
|
-
class Gl::Shader ; end
|
6
|
-
|
7
|
-
class Gl::Program < Gl::GlInternalMarked
|
8
|
-
|
9
|
-
attr_reader :name
|
10
|
-
|
11
|
-
def initialize(name = nil)
|
12
|
-
super()
|
13
|
-
@name = (name != 0 && name) || Gl.glCreateProgram()
|
14
|
-
|
15
|
-
@validate_status = nil
|
16
|
-
@link_status = nil
|
17
|
-
@uniform_locations = {}
|
18
|
-
__mark__
|
19
|
-
end
|
20
|
-
|
21
|
-
def load_binary(binary_format, binary_string)
|
22
|
-
Gl.glProgramBinary(@name, binary_format, binary_string, binary_string.bytesize)
|
23
|
-
@link_status = nil
|
24
|
-
__reload_uniforms__ if (link_successful = linked?)
|
25
|
-
link_successful
|
26
|
-
end
|
27
|
-
|
28
|
-
def binary
|
29
|
-
Gl.glGetProgramBinary(@name)
|
30
|
-
end
|
31
|
-
|
32
|
-
def delete
|
33
|
-
if @name != 0
|
34
|
-
Gl.glDeleteProgram(@name)
|
35
|
-
@name = 0
|
36
|
-
super
|
37
|
-
end
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
def __reload_uniforms__
|
42
|
-
@uniform_locations.keys.each {
|
43
|
-
|key|
|
44
|
-
@uniform_locations[key] = Gl.glGetUniformLocation(@name, key.to_s)
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
def link
|
49
|
-
Gl.glLinkProgram(@name)
|
50
|
-
@link_status = nil
|
51
|
-
__reload_uniforms__ if (link_successful = linked?)
|
52
|
-
link_successful
|
53
|
-
end
|
54
|
-
|
55
|
-
def linked?
|
56
|
-
@link_status = (!@link_status.nil? && @link_status) ||
|
57
|
-
Gl.glGetProgram(@name, Gl::GL_LINK_STATUS) == GL_TRUE
|
58
|
-
end
|
59
|
-
|
60
|
-
def validate
|
61
|
-
Gl.glValidateProgram(@name)
|
62
|
-
@validate_status = nil
|
63
|
-
valid?
|
64
|
-
end
|
65
|
-
|
66
|
-
def valid?
|
67
|
-
@validate_status = (!@validate_status.nil? && @validate_status) ||
|
68
|
-
Gl.glGetProgram(@name, Gl::GL_VALIDATE_STATUS) == GL_TRUE
|
69
|
-
end
|
70
|
-
|
71
|
-
def info_log
|
72
|
-
Gl.glGetProgramInfoLog(@name)
|
73
|
-
end
|
74
|
-
|
75
|
-
def use
|
76
|
-
Gl.glUseProgram(@name)
|
77
|
-
self
|
78
|
-
end
|
79
|
-
|
80
|
-
def attach_shader(shader)
|
81
|
-
case shader
|
82
|
-
when ::Gl::Shader then Gl.glAttachShader(@name, shader.name)
|
83
|
-
else Gl.glAttachShader(@name, shader)
|
84
|
-
end
|
85
|
-
self
|
86
|
-
end
|
87
|
-
|
88
|
-
def hint_uniform(uniform_name)
|
89
|
-
uniform_name = uniform_name.to_sym
|
90
|
-
@uniform_locations[uniform_name] ||= -1
|
91
|
-
self
|
92
|
-
end
|
93
|
-
|
94
|
-
# Implicitly hints that a uniform exists.
|
95
|
-
def uniform_location(uniform_name)
|
96
|
-
uniform_sym = uniform_name.to_sym
|
97
|
-
@uniform_locations[uniform_sym] ||=
|
98
|
-
Gl.glGetUniformLocation(@name, uniform_name.to_s)
|
99
|
-
end
|
100
|
-
alias_method :[], :uniform_location
|
101
|
-
|
102
|
-
def each_hinted_uniform(&block)
|
103
|
-
return @uniform_locations.each_key unless block_given?
|
104
|
-
@uniform_locations.each_key(&block)
|
105
|
-
self
|
106
|
-
end
|
107
|
-
|
108
|
-
def subroutine_uniform_location(shader_kind, uniform_name)
|
109
|
-
Gl.glGetSubroutineUniformLocation(@name, shader_kind, uniform_name)
|
110
|
-
end
|
111
|
-
|
112
|
-
def bind_attrib_location(attrib_index, attrib_name)
|
113
|
-
Gl.glBindAttribLocation(@name, attrib_index, attrib_name.to_s)
|
114
|
-
self
|
115
|
-
end
|
116
|
-
|
117
|
-
def bind_frag_data_location(color_number, frag_data_name)
|
118
|
-
Gl.glBindFragDataLocation(@name, color_number, frag_data_name.to_s)
|
119
|
-
self
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|