opengl-aux 1.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/opengl-aux/buffer.rb +100 -0
- data/lib/opengl-aux/error.rb +57 -0
- data/lib/opengl-aux/gl.rb +372 -0
- data/lib/opengl-aux/program.rb +161 -0
- data/lib/opengl-aux/shader.rb +64 -0
- data/lib/opengl-aux/texture.rb +115 -0
- data/lib/opengl-aux/version.rb +12 -0
- data/lib/opengl-aux/vertex_array.rb +73 -0
- data/lib/opengl-aux.rb +16 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4d62d50a90a153ae31c7313cd71317c99edab993
|
4
|
+
data.tar.gz: 39a962d7c4c6fa4e9397f9268036637e9eddf676
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e6d810e70fcf3063e81fef2e45ddc8bbc80012d5ead1ddac9236c2d078459a6095c72b84203f023db843f8e3c870a12878daeb0ce36731e46443729dd53c99a7
|
7
|
+
data.tar.gz: 55e6b6a8992d9ba097cfe9998ea7ec527f66fcedcf6a4986577da24473c738deb41d57c8cfea0b35b2db6eeb74330119db2cf1ff48f32ef69c30840e6ccdd400
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# buffer.rb
|
7
|
+
# GL buffer object wrapper.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
require 'opengl-aux/error'
|
12
|
+
|
13
|
+
|
14
|
+
class GL::Buffer
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
attr_accessor :__buffer_target_getters__
|
19
|
+
|
20
|
+
def current_binding(target)
|
21
|
+
GL.glGetInteger(__buffer_target_getters__[target])
|
22
|
+
end
|
23
|
+
|
24
|
+
def preserve_binding(target)
|
25
|
+
current = bound_name(target)
|
26
|
+
begin
|
27
|
+
yield
|
28
|
+
ensure
|
29
|
+
GL.glBindBuffer(target, current)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end # singleton_class
|
34
|
+
|
35
|
+
|
36
|
+
self.__buffer_target_getters__ = {
|
37
|
+
GL::GL_ARRAY_BUFFER => GL::GL_ARRAY_BUFFER_BINDING,
|
38
|
+
GL::GL_ATOMIC_COUNTER_BUFFER => GL::GL_ATOMIC_COUNTER_BUFFER_BINDING,
|
39
|
+
GL::GL_DISPATCH_INDIRECT_BUFFER => GL::GL_DISPATCH_INDIRECT_BUFFER_BINDING,
|
40
|
+
GL::GL_DRAW_INDIRECT_BUFFER => GL::GL_DRAW_INDIRECT_BUFFER_BINDING,
|
41
|
+
GL::GL_ELEMENT_ARRAY_BUFFER => GL::GL_ELEMENT_ARRAY_BUFFER_BINDING,
|
42
|
+
GL::GL_PIXEL_PACK_BUFFER => GL::GL_PIXEL_PACK_BUFFER_BINDING,
|
43
|
+
GL::GL_PIXEL_UNPACK_BUFFER => GL::GL_PIXEL_UNPACK_BUFFER_BINDING,
|
44
|
+
GL::GL_QUERY_BUFFER => GL::GL_QUERY_BUFFER_BINDING,
|
45
|
+
GL::GL_SHADER_STORAGE_BUFFER => GL::GL_SHADER_STORAGE_BUFFER_BINDING,
|
46
|
+
GL::GL_SHADER_STORAGE_BUFFER => GL::GL_SHADER_STORAGE_BUFFER_BINDING,
|
47
|
+
GL::GL_TEXTURE_BUFFER => GL::GL_TEXTURE_BUFFER_BINDING,
|
48
|
+
GL::GL_TRANSFORM_FEEDBACK_BUFFER => GL::GL_TRANSFORM_FEEDBACK_BUFFER_BINDING,
|
49
|
+
GL::GL_UNIFORM_BUFFER => GL::GL_UNIFORM_BUFFER_BINDING,
|
50
|
+
}
|
51
|
+
|
52
|
+
__buffer_target_getters__.default_proc = -> (hash, key) do
|
53
|
+
raise ArgumentError, "No queryable buffer binding target for #{key}"
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
attr_reader :name
|
58
|
+
attr_accessor :target
|
59
|
+
|
60
|
+
def initialize(target = nil, name = nil)
|
61
|
+
@name = (name != 0 && name) || 0
|
62
|
+
@target = target
|
63
|
+
yield self if block_given?
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_buffer?
|
67
|
+
GL::glIsBuffer(@name) != GL::GL_FALSE
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete
|
71
|
+
if @name != 0
|
72
|
+
GL.glDeleteBuffers(@name)
|
73
|
+
@name = 0
|
74
|
+
end
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def bind(target = nil)
|
79
|
+
target ||= (@target || GL_ARRAY_BUFFER)
|
80
|
+
@target ||= target
|
81
|
+
raise ArgumentError, "No target given and no previous target" unless target
|
82
|
+
|
83
|
+
if block_given?
|
84
|
+
preserve_binding(target) do
|
85
|
+
yield self
|
86
|
+
end
|
87
|
+
else
|
88
|
+
if @name == 0
|
89
|
+
@name = GL.glGenBuffers(1)
|
90
|
+
if @name == 0
|
91
|
+
raise GL::GLCreateError, "Unable to allocate buffer object"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
GL.glBindBuffer(target, @name)
|
96
|
+
self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end # GL::Buffer
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# error.rb
|
7
|
+
# Error types used by opengl-aux.
|
8
|
+
|
9
|
+
|
10
|
+
module GL
|
11
|
+
|
12
|
+
# Generic error that should probably be subclassed for more specific errors.
|
13
|
+
# Can be used as a catch-all for GL-specific errors.
|
14
|
+
class GLError < StandardError ; end
|
15
|
+
|
16
|
+
# An error that should be raised if a call to a glGen* or glCreate* function
|
17
|
+
# fails.
|
18
|
+
class GLCreateError < GLError ; end
|
19
|
+
|
20
|
+
# State error raised for errors returned by glGetError.
|
21
|
+
class GLStateError < GLError
|
22
|
+
attr_reader :code
|
23
|
+
|
24
|
+
def self.exception(msg = nil, code = GL::GL_NO_ERROR)
|
25
|
+
new(code, msg)
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(code, msg = nil)
|
29
|
+
@code = code
|
30
|
+
super(msg)
|
31
|
+
end
|
32
|
+
|
33
|
+
def exception(msg = nil)
|
34
|
+
if msg
|
35
|
+
self.class.exception(msg, code)
|
36
|
+
else
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
code_str =
|
43
|
+
case self.code
|
44
|
+
when GL::GL_NO_ERROR then 'NO_ERROR'
|
45
|
+
when GL::GL_INVALID_ENUM then 'INVALID_ENUM'
|
46
|
+
when GL::GL_INVALID_VALUE then 'INVALID_VALUE'
|
47
|
+
when GL::GL_INVALID_OPERATION then 'INVALID_OPERATION'
|
48
|
+
when GL::GL_INVALID_FRAMEBUFFER_OPERATION then 'INVALID_FRAMEBUFFER_OPERATION'
|
49
|
+
when GL::GL_OUT_OF_MEMORY then 'OUT_OF_MEMORY'
|
50
|
+
when GL::GL_STACK_UNDERFLOW then 'STACK_UNDERFLOW'
|
51
|
+
when GL::GL_STACK_OVERFLOW then 'STACK_OVERFLOW'
|
52
|
+
end
|
53
|
+
"#{code_str}: #{super}"
|
54
|
+
end
|
55
|
+
end # GLStateError
|
56
|
+
|
57
|
+
end # GL
|
@@ -0,0 +1,372 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# gl.rb
|
7
|
+
# Basic GL functions and typedefs for snow-data.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-core'
|
11
|
+
require 'snow-data'
|
12
|
+
require 'opengl-aux/error'
|
13
|
+
|
14
|
+
|
15
|
+
# Extensions to the opengl-core Gl module.
|
16
|
+
module GL
|
17
|
+
|
18
|
+
# Define snow-data typedefs for OpenGL
|
19
|
+
Snow::CStruct.alias_type(:gl_short, :short)
|
20
|
+
Snow::CStruct.alias_type(:gl_ushort, :unsigned_short)
|
21
|
+
Snow::CStruct.alias_type(:gl_half, :unsigned_short)
|
22
|
+
Snow::CStruct.alias_type(:gl_enum, :unsigned_int)
|
23
|
+
Snow::CStruct.alias_type(:gl_uint, :unsigned_int)
|
24
|
+
Snow::CStruct.alias_type(:gl_int, :int)
|
25
|
+
Snow::CStruct.alias_type(:gl_fixed, :int)
|
26
|
+
Snow::CStruct.alias_type(:gl_uint64, :uint64_t)
|
27
|
+
Snow::CStruct.alias_type(:gl_int64, :int64_t)
|
28
|
+
Snow::CStruct.alias_type(:gl_sizei, :int)
|
29
|
+
Snow::CStruct.alias_type(:gl_float, :float)
|
30
|
+
Snow::CStruct.alias_type(:gl_clampf, :float)
|
31
|
+
Snow::CStruct.alias_type(:gl_double, :double)
|
32
|
+
Snow::CStruct.alias_type(:gl_clampd, :double)
|
33
|
+
|
34
|
+
GLObject = Snow::CStruct.new { gl_uint :name }
|
35
|
+
|
36
|
+
def assert_no_gl_error(msg = nil)
|
37
|
+
error = glGetError
|
38
|
+
|
39
|
+
if error != GL_NO_ERROR
|
40
|
+
raise GLStateError.new(error), msg
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
attr_accessor :__box_types__
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
#
|
51
|
+
# Temporarily allocates the given type, yields it to a block, and releases
|
52
|
+
# the allocated memory. Uses alloca if available. Any additional arguments
|
53
|
+
# to this function are forwarded to the type's allocator.
|
54
|
+
#
|
55
|
+
def __temp_alloc__(type, *args, &block)
|
56
|
+
result = nil
|
57
|
+
|
58
|
+
if type.respond_to?(:alloca)
|
59
|
+
result = type.alloca(*args, &block)
|
60
|
+
else
|
61
|
+
type.new(*args) do |p|
|
62
|
+
begin
|
63
|
+
result = yield[p]
|
64
|
+
ensure
|
65
|
+
p.free!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
73
|
+
# @api private
|
74
|
+
#
|
75
|
+
# Returns a boxed type for the given typename. All boxed types contain a
|
76
|
+
# single member, 'name', which is of the boxed type. Boxed types are created
|
77
|
+
# on demand and cached.
|
78
|
+
#
|
79
|
+
def __boxed_type__(typename, &block)
|
80
|
+
box_types = (__box_types__ ||= Hash.new do |hash, type|
|
81
|
+
hash[type] = Snow::CStruct.new { __send__(type, :name) }
|
82
|
+
end)
|
83
|
+
|
84
|
+
box_types[typename]
|
85
|
+
end
|
86
|
+
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
# Wraps a previously-defined native glGen* function that returns the given
|
90
|
+
# type of object. The glGen function returns one or more GL object names.
|
91
|
+
# If returning a single name, the return type is Fixnum, otherwise it's an
|
92
|
+
# array of Fixnums.
|
93
|
+
#
|
94
|
+
def __define_gl_gen_object_method__(name, type)
|
95
|
+
self.module_exec(name, :"#{name}__", GL.__boxed_type__(type)) do
|
96
|
+
|func_name, raw_name, box_type|
|
97
|
+
|
98
|
+
define_method(func_name, -> (count) do
|
99
|
+
return nil if count <= 0
|
100
|
+
|
101
|
+
if count == 1
|
102
|
+
GL.__temp_alloc__(box_type) do |p|
|
103
|
+
send(raw_name, count, p.address)
|
104
|
+
p.name
|
105
|
+
end
|
106
|
+
else
|
107
|
+
GL.__temp_alloc__(box_type::Array, count) do |p|
|
108
|
+
send(raw_name, count, p.address)
|
109
|
+
Array.new(count) { |i| p[i].name }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end) # define_method
|
113
|
+
|
114
|
+
end # module_exec
|
115
|
+
end # __define_gl_get_method__
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
#
|
119
|
+
# Similar to __define_gl_gen_object_method__, except for deletion. Takes
|
120
|
+
# four possible types of objects to delete: a GLObject or an array of
|
121
|
+
# GLObjects, a Fixnum, or an array of Fixnums. Any other types will raise
|
122
|
+
# an error, and any type contained by an Array that is not implicitly
|
123
|
+
# convertible to a Fixnum will also raise an error.
|
124
|
+
#
|
125
|
+
def __define_gl_delete_object_method__(name, type)
|
126
|
+
self.module_exec(name, :"#{name}__") do |func_name, raw_name|
|
127
|
+
|
128
|
+
define_method(func_name, -> (objects) do
|
129
|
+
case objects
|
130
|
+
when GLObject
|
131
|
+
send(raw_name, 1, objects.address)
|
132
|
+
when GLObject::Array
|
133
|
+
send(raw_name, objects.length, objects.address)
|
134
|
+
when Fixnum
|
135
|
+
GL.__temp_alloc__(GLObject) do |p|
|
136
|
+
p.name = objects
|
137
|
+
send(raw_name, 1, p.address)
|
138
|
+
end
|
139
|
+
when Array # Assumes an array of fixnums
|
140
|
+
GL.__temp_alloc__(GLObject::Array, objects.length) do |p|
|
141
|
+
objects.each_with_index { |e, i| p[i].name = e }
|
142
|
+
send(raw_name, p.length, p.address)
|
143
|
+
end
|
144
|
+
else
|
145
|
+
raise ArgumentError,
|
146
|
+
"Invalid object passed to #{name} for deletion: #{objects.inspect}"
|
147
|
+
end
|
148
|
+
self
|
149
|
+
end) # define_method
|
150
|
+
|
151
|
+
end # module_exec
|
152
|
+
end # __define_gl_get_method__
|
153
|
+
|
154
|
+
# @api private
|
155
|
+
#
|
156
|
+
# Defines a glGet* method that returns a single value of the given type.
|
157
|
+
#
|
158
|
+
def __define_gl_get_method__(name, type)
|
159
|
+
self.module_exec(name, :"#{name}v__", GL.__boxed_type__(type)) do
|
160
|
+
|func_name, raw_name, box_type|
|
161
|
+
|
162
|
+
define_method(func_name, -> (pname) do
|
163
|
+
GL.__temp_alloc__(box_type) do |p|
|
164
|
+
send(raw_name, pname, p.address)
|
165
|
+
p.name
|
166
|
+
end
|
167
|
+
end) # define_method
|
168
|
+
|
169
|
+
end # module_exec
|
170
|
+
end # __define_gl_get_method__
|
171
|
+
|
172
|
+
end # singleton_class
|
173
|
+
|
174
|
+
|
175
|
+
# @!method self.glGenTextures(count)
|
176
|
+
# Returns an array of generated texture names.
|
177
|
+
__define_gl_gen_object_method__ :glGenTextures, :gl_uint
|
178
|
+
# @!method self.glDeleteTextures(count, objects)
|
179
|
+
__define_gl_delete_object_method__ :glDeleteTextures, :gl_uint
|
180
|
+
|
181
|
+
# @!method self.glGenVertexArrays(count)
|
182
|
+
# Returns an array of generated vertex array object names.
|
183
|
+
__define_gl_gen_object_method__ :glGenVertexArrays, :gl_uint
|
184
|
+
# @!method self.glDeleteVertexArrays(count, objects)
|
185
|
+
__define_gl_delete_object_method__ :glDeleteVertexArrays, :gl_uint
|
186
|
+
|
187
|
+
# @!method self.glGenBuffers(count)
|
188
|
+
# Returns an array of generated buffer object names.
|
189
|
+
__define_gl_gen_object_method__ :glGenBuffers, :gl_uint
|
190
|
+
# @!method self.glDeleteBuffers(count, objects)
|
191
|
+
__define_gl_delete_object_method__ :glDeleteBuffers, :gl_uint
|
192
|
+
|
193
|
+
# @!method self.glGenQueries(count)
|
194
|
+
# Returns an array of generated query object names.
|
195
|
+
__define_gl_gen_object_method__ :glGenQueries, :gl_uint
|
196
|
+
# @!method self.glDeleteQueries(count, objects)
|
197
|
+
__define_gl_delete_object_method__ :glDeleteQueries, :gl_uint
|
198
|
+
|
199
|
+
# @!method self.glGenSamplers(count)
|
200
|
+
# Returns an array of generated sampler object names.
|
201
|
+
__define_gl_gen_object_method__ :glGenSamplers, :gl_uint
|
202
|
+
# @!method self.glDeleteSamplers(count, objects)
|
203
|
+
__define_gl_delete_object_method__ :glDeleteSamplers, :gl_uint
|
204
|
+
|
205
|
+
# @!method self.glGenFramebuffers(count)
|
206
|
+
# Returns an array of generated framebuffer object names.
|
207
|
+
__define_gl_gen_object_method__ :glGenFramebuffers, :gl_uint
|
208
|
+
# @!method self.glDeleteFramebuffers(count, objects)
|
209
|
+
__define_gl_delete_object_method__ :glDeleteFramebuffers, :gl_uint
|
210
|
+
|
211
|
+
# @!method self.glGenRenderbuffers(count)
|
212
|
+
# Returns an array of generated renderbuffer object names.
|
213
|
+
__define_gl_gen_object_method__ :glGenRenderbuffers, :gl_uint
|
214
|
+
# @!method self.glDeleteRenderbuffers(count, objects)
|
215
|
+
__define_gl_delete_object_method__ :glDeleteRenderbuffers, :gl_uint
|
216
|
+
|
217
|
+
# @!method self.glGenRenderbuffersProgramPipelines(count)
|
218
|
+
# Returns an array of generated program pipeline object names.
|
219
|
+
__define_gl_gen_object_method__ :glGenProgramPipelines, :gl_uint
|
220
|
+
# @!method self.glDeleteRenderbuffersProgramPipelines(count, objects)
|
221
|
+
__define_gl_delete_object_method__ :glDeleteProgramPipelines, :gl_uint
|
222
|
+
|
223
|
+
# @!method self.glGenRenderbuffersTrasnformFeedbacks(count)
|
224
|
+
# Returns an array of generated transform feedback objects
|
225
|
+
__define_gl_gen_object_method__ :glGenTransformFeedbacks, :gl_uint
|
226
|
+
# @!method self.glDeleteRenderbuffersTrasnformFeedbacks(count, objects)
|
227
|
+
__define_gl_delete_object_method__ :glDeleteTransformFeedbacks, :gl_uint
|
228
|
+
|
229
|
+
__define_gl_get_method__ :glGetInteger, :gl_int
|
230
|
+
__define_gl_get_method__ :glGetInteger64, :gl_int64
|
231
|
+
__define_gl_get_method__ :glGetFloat, :float
|
232
|
+
__define_gl_get_method__ :glGetDouble, :double
|
233
|
+
|
234
|
+
# @return [Boolean] Returns the boolean value of the given parameter name.
|
235
|
+
def glGetBoolean(pname)
|
236
|
+
GL.__temp_alloc__(GL.__boxed_type__(:gl_boolean)) do |p|
|
237
|
+
p.name = 0
|
238
|
+
glGetBooleanv(pname, p.address)
|
239
|
+
p.name != GL_FALSE
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# @return [String] Returns the string value of the given parameter name.
|
244
|
+
def glGetString(name)
|
245
|
+
glGetString__(name).to_s
|
246
|
+
end
|
247
|
+
|
248
|
+
# @return [String] Returns the string value of a parameter name at a given index.
|
249
|
+
def glGetStringi(name, index)
|
250
|
+
glGetStringi__(name, index).to_s
|
251
|
+
end
|
252
|
+
|
253
|
+
# Assumes sources is a
|
254
|
+
def glShaderSource(shader, sources)
|
255
|
+
ary_len = (source_array = sources.kind_of?(Array)) ? sources.length : 1
|
256
|
+
|
257
|
+
lengths = GL.__boxed_type__(:gl_sizei)[ary_len]
|
258
|
+
pointers = GL.__boxed_type__(:intptr_t)[ary_len]
|
259
|
+
|
260
|
+
begin
|
261
|
+
assign_block = -> (src, index) do
|
262
|
+
lengths[index].name = src.bytesize
|
263
|
+
pointers[index].name = Fiddle::Pointer[src].to_i
|
264
|
+
end
|
265
|
+
|
266
|
+
if source_array
|
267
|
+
sources.each_with_index(&assign_block)
|
268
|
+
else
|
269
|
+
assign_block[sources, 0]
|
270
|
+
end
|
271
|
+
|
272
|
+
glShaderSource__(shader, ary_len, pointers.address, lengths.address)
|
273
|
+
|
274
|
+
ensure
|
275
|
+
lengths.free!
|
276
|
+
pointers.free!
|
277
|
+
end
|
278
|
+
|
279
|
+
self
|
280
|
+
end
|
281
|
+
|
282
|
+
# Returns the version or release number. Calls glGetString.
|
283
|
+
def gl_version
|
284
|
+
glGetString(GL_VERSION)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Returns the implementation vendor. Calls glGetString.
|
288
|
+
def gl_vendor
|
289
|
+
glGetString(GL_VENDOR)
|
290
|
+
end
|
291
|
+
|
292
|
+
# Returns the renderer. Calls glGetString.
|
293
|
+
def gl_renderer
|
294
|
+
glGetString(GL_RENDERER)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Returns the shading language version. Calls glGetString.
|
298
|
+
def gl_shading_language_version
|
299
|
+
glGetString(GL_SHADING_LANGUAGE_VERSION)
|
300
|
+
end
|
301
|
+
|
302
|
+
# Gets an array of GL extensions. This calls glGetIntegerv and glGetStringi,
|
303
|
+
# so be aware that you should probably cache the results.
|
304
|
+
def gl_extensions
|
305
|
+
Array.new(glGetInteger(GL_NUM_EXTENSIONS)) do |index|
|
306
|
+
glGetStringi(GL_EXTENSIONS, index)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def glGetShader(shader, pname)
|
311
|
+
GL.__temp_alloc__(GL.__boxed_type__(:gl_int)) do |p|
|
312
|
+
glGetShaderiv__(shader, pname, p.address)
|
313
|
+
p.name
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def glGetShaderInfoLog(shader)
|
318
|
+
length = glGetShader(shader, GL_INFO_LOG_LENGTH)
|
319
|
+
return '' if length == 0
|
320
|
+
output = ' ' * length
|
321
|
+
glGetShaderInfoLog__(shader, output.bytesize, 0, output)
|
322
|
+
output
|
323
|
+
end
|
324
|
+
|
325
|
+
def glGetShaderSource(shader)
|
326
|
+
length = glGetShader(shader, GL_SHADER_SOURCE_LENGTH)
|
327
|
+
return '' if length == 0
|
328
|
+
output = ' ' * length
|
329
|
+
glGetShaderInfoLog__(shader, output.bytesize, 0, output)
|
330
|
+
output
|
331
|
+
end
|
332
|
+
|
333
|
+
def glGetProgram(program, pname)
|
334
|
+
GL.__temp_alloc__(GL.__boxed_type__(:gl_int)) do |p|
|
335
|
+
glGetProgramiv__(program, pname, p.address)
|
336
|
+
p.name
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def glGetProgramInfoLog(program)
|
341
|
+
length = glGetProgram(program, GL_INFO_LOG_LENGTH)
|
342
|
+
return '' if length == 0
|
343
|
+
output = ' ' * length
|
344
|
+
glGetProgramInfoLog__(program, output.bytesize, 0, output)
|
345
|
+
output
|
346
|
+
end
|
347
|
+
|
348
|
+
GLProgramBinary = Struct.new(:format, :data)
|
349
|
+
|
350
|
+
def glGetProgramBinary(program)
|
351
|
+
binary_length = glGetProgram(program, GL_PROGRAM_BINARY_LENGTH)
|
352
|
+
|
353
|
+
return nil if binary_length <= 0
|
354
|
+
|
355
|
+
GL.__temp_alloc__(GL.__boxed_type__(:gl_enum)) do |format_buffer; binary_buffer|
|
356
|
+
binary_buffer = ' ' * binary_length
|
357
|
+
|
358
|
+
glGetProgramBinary(
|
359
|
+
program,
|
360
|
+
binary_buffer.bytesize,
|
361
|
+
0,
|
362
|
+
format_buffer.address,
|
363
|
+
binary_buffer.address
|
364
|
+
)
|
365
|
+
|
366
|
+
GLProgramBinary[format_buffer.name, binary_buffer]
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
extend self
|
371
|
+
|
372
|
+
end # GL
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# program.rb
|
7
|
+
# GL program object wrapper.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
|
12
|
+
|
13
|
+
# Declare it just for type checking
|
14
|
+
class GL::Shader ; end
|
15
|
+
|
16
|
+
class GL::Program
|
17
|
+
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
def current_program
|
22
|
+
GL::glGetInteger(GL::GL_CURRENT_PROGRAM)
|
23
|
+
end
|
24
|
+
|
25
|
+
def preserve_binding
|
26
|
+
raise ArgumentError, "No block given" unless block_given?
|
27
|
+
current = current_program
|
28
|
+
begin
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
GL.glUseProgram(current)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # singleton_class
|
36
|
+
|
37
|
+
|
38
|
+
attr_reader :name
|
39
|
+
|
40
|
+
def initialize(name = nil)
|
41
|
+
if name
|
42
|
+
@name = name
|
43
|
+
else
|
44
|
+
@name = GL.glCreateProgram()
|
45
|
+
raise GL::GLCreateError, "Unable to allocate shader" if @name == 0
|
46
|
+
end
|
47
|
+
|
48
|
+
@uniform_locations = {}
|
49
|
+
|
50
|
+
yield self if block_given?
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete
|
54
|
+
if @name != 0
|
55
|
+
GL.glDeleteProgram(@name)
|
56
|
+
@name = 0
|
57
|
+
end
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_program?
|
62
|
+
GL::glIsProgram(@name) != GL::GL_FALSE
|
63
|
+
end
|
64
|
+
|
65
|
+
def load_binary(binary_format, binary_string)
|
66
|
+
GL.glProgramBinary(@name, binary_format, binary_string, binary_string.bytesize)
|
67
|
+
__reload_uniforms__ if (link_successful = linked?)
|
68
|
+
link_successful
|
69
|
+
end
|
70
|
+
|
71
|
+
def binary
|
72
|
+
GL.glGetProgramBinary(@name)
|
73
|
+
end
|
74
|
+
|
75
|
+
def __reload_uniforms__
|
76
|
+
locs = @uniform_locations
|
77
|
+
locs.each_key do |key|
|
78
|
+
locs[key] = GL.glGetUniformLocation(@name, key.to_s)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def link
|
83
|
+
GL.glLinkProgram(@name)
|
84
|
+
@link_status = nil
|
85
|
+
__reload_uniforms__ if (link_successful = linked?)
|
86
|
+
link_successful
|
87
|
+
end
|
88
|
+
|
89
|
+
def linked?
|
90
|
+
GL.glGetProgram(@name, GL::GL_LINK_STATUS) != GL::GL_FALSE
|
91
|
+
end
|
92
|
+
|
93
|
+
def valid?
|
94
|
+
GL.glValidateProgram(@name)
|
95
|
+
GL.glGetProgram(@name, GL::GL_VALIDATE_STATUS) != GL::GL_FALSE
|
96
|
+
end
|
97
|
+
|
98
|
+
def info_log
|
99
|
+
GL.glGetProgramInfoLog(@name)
|
100
|
+
end
|
101
|
+
|
102
|
+
def use
|
103
|
+
if block_given?
|
104
|
+
preserve_binding do
|
105
|
+
use
|
106
|
+
yield self
|
107
|
+
end
|
108
|
+
else
|
109
|
+
GL.glUseProgram(@name)
|
110
|
+
self
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def attach_shader(shader)
|
115
|
+
case shader
|
116
|
+
when ::GL::Shader then GL.glAttachShader(@name, shader.name)
|
117
|
+
else GL.glAttachShader(@name, shader)
|
118
|
+
end
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def detach_shader(shader)
|
123
|
+
case shader
|
124
|
+
when ::GL::Shader then GL.glDetachShader(@name, shader.name)
|
125
|
+
else GL.glDetachShader(@name, shader)
|
126
|
+
end
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
130
|
+
def hint_uniform(name)
|
131
|
+
name = name.to_sym
|
132
|
+
@uniform_locations[name] ||= nil
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
def uniform_location(name)
|
137
|
+
uniform_sym = name.to_sym
|
138
|
+
locations = @uniform_locations
|
139
|
+
locations[uniform_sym] ||= GL.glGetUniformLocation(@name, name.to_s)
|
140
|
+
end
|
141
|
+
alias_method :[], :uniform_location
|
142
|
+
|
143
|
+
def clear_uniform_location_cache
|
144
|
+
@uniform_locations.clear
|
145
|
+
end
|
146
|
+
|
147
|
+
def subroutine_uniform_location(shader_kind, uniform_name)
|
148
|
+
GL.glGetSubroutineUniformLocation(@name, shader_kind, uniform_name)
|
149
|
+
end
|
150
|
+
|
151
|
+
def bind_attrib_location(attrib_index, attrib_name)
|
152
|
+
GL.glBindAttribLocation(@name, attrib_index, attrib_name.to_s)
|
153
|
+
self
|
154
|
+
end
|
155
|
+
|
156
|
+
def bind_frag_data_location(color_number, frag_data_name)
|
157
|
+
GL.glBindFragDataLocation(@name, color_number, frag_data_name.to_s)
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# shader.rb
|
7
|
+
# GL shader object wrapper.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
|
12
|
+
|
13
|
+
class GL::Shader
|
14
|
+
|
15
|
+
attr_reader :name
|
16
|
+
attr_reader :kind
|
17
|
+
|
18
|
+
def initialize(kind, name = nil)
|
19
|
+
if name
|
20
|
+
@name = name
|
21
|
+
else
|
22
|
+
@name = GL.glCreateShader(kind)
|
23
|
+
raise GL::GLCreateError, "Unable to allocate shader" if @name == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
@kind = kind
|
27
|
+
yield self if block_given?
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete
|
31
|
+
if @name != 0
|
32
|
+
GL.glDeleteShader(@name)
|
33
|
+
@name = 0
|
34
|
+
end
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_shader?
|
39
|
+
GL::glIsShader(@name) != GL::GL_FALSE
|
40
|
+
end
|
41
|
+
|
42
|
+
def source=(sources)
|
43
|
+
GL.glShaderSource(@name, sources)
|
44
|
+
sources
|
45
|
+
end
|
46
|
+
|
47
|
+
def source
|
48
|
+
GL.glGetShaderSource(@name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def compile
|
52
|
+
GL.glCompileShader(@name)
|
53
|
+
compiled?
|
54
|
+
end
|
55
|
+
|
56
|
+
def compiled?
|
57
|
+
GL.glGetShader(@name, GL::GL_COMPILE_STATUS) != GL::GL_FALSE
|
58
|
+
end
|
59
|
+
|
60
|
+
def info_log
|
61
|
+
GL.glGetShaderInfoLog(@name)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# texture.rb
|
7
|
+
# GL texture object wrapper.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
require 'opengl-aux/error'
|
12
|
+
|
13
|
+
|
14
|
+
class GL::Texture
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
attr_accessor :__texture_target_getters__
|
19
|
+
|
20
|
+
def current_unit
|
21
|
+
GL.glGetInteger(GL::GL_ACTIVE_TEXTURE)
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_binding(target)
|
25
|
+
GL.glGetInteger(__texture_target_getters__[target])
|
26
|
+
end
|
27
|
+
|
28
|
+
def preserve_unit
|
29
|
+
unit = current_unit
|
30
|
+
begin
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
GL.glActiveTexture(unit)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Implied preserve_unit
|
38
|
+
def preserve_binding(target)
|
39
|
+
preserve_unit do
|
40
|
+
binding = current_binding(target)
|
41
|
+
begin
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
GL.glBindTexture(target, binding)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end # singleton_class
|
50
|
+
|
51
|
+
|
52
|
+
self.__texture_target_getters__ = {
|
53
|
+
GL::GL_TEXTURE_1D => GL::GL_TEXTURE_BINDING_1D,
|
54
|
+
GL::GL_TEXTURE_2D => GL::GL_TEXTURE_BINDING_2D,
|
55
|
+
GL::GL_TEXTURE_3D => GL::GL_TEXTURE_BINDING_3D,
|
56
|
+
GL::GL_TEXTURE_1D_ARRAY => GL::GL_TEXTURE_BINDING_1D_ARRAY,
|
57
|
+
GL::GL_TEXTURE_2D_ARRAY => GL::GL_TEXTURE_BINDING_2D_ARRAY,
|
58
|
+
GL::GL_TEXTURE_RECTANGLE => GL::GL_TEXTURE_BINDING_RECTANGLE,
|
59
|
+
GL::GL_TEXTURE_CUBE_MAP => GL::GL_TEXTURE_BINDING_CUBE_MAP,
|
60
|
+
GL::GL_TEXTURE_CUBE_MAP_ARRAY => GL::GL_TEXTURE_BINDING_CUBE_MAP_ARRAY,
|
61
|
+
GL::GL_TEXTURE_BUFFER => GL::GL_TEXTURE_BINDING_BUFFER,
|
62
|
+
GL::GL_TEXTURE_2D_MULTISAMPLE => GL::GL_TEXTURE_BINDING_2D_MULTISAMPLE,
|
63
|
+
GL::GL_TEXTURE_2D_MULTISAMPLE_ARRAY => GL::GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY,
|
64
|
+
}
|
65
|
+
|
66
|
+
self.__texture_target_getters__.default_proc = -> (hash, key) do
|
67
|
+
raise ArgumentError, "No queryable texture binding target for #{key}"
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
attr_reader :name
|
72
|
+
attr_accessor :target
|
73
|
+
|
74
|
+
def initialize(target = nil, name = nil)
|
75
|
+
@name = name || 0
|
76
|
+
@target = target
|
77
|
+
yield self if block_given?
|
78
|
+
end
|
79
|
+
|
80
|
+
def is_texture?
|
81
|
+
GL::glIsTexture(@name) != GL::GL_FALSE
|
82
|
+
end
|
83
|
+
|
84
|
+
def delete
|
85
|
+
if @name != 0
|
86
|
+
GL.glDeleteTextures(@name)
|
87
|
+
@name = 0
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def bind(target = nil)
|
92
|
+
# You may think this is insane, but I assure you, it isn't.
|
93
|
+
target ||= (@target || GL_TEXTURE_2D)
|
94
|
+
@target ||= target
|
95
|
+
raise ArgumentError, "No target given and no previous target" unless target
|
96
|
+
|
97
|
+
if block_given?
|
98
|
+
self.class.preserve_binding(target) do
|
99
|
+
bind(target)
|
100
|
+
yield self
|
101
|
+
end
|
102
|
+
else
|
103
|
+
if @name == 0
|
104
|
+
@name ||= GL.glGenTextures(1)
|
105
|
+
if @name == 0
|
106
|
+
raise GL::GLCreateError, "Unable to allocate texture object"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
GL.glBindTexture(target, @name)
|
111
|
+
self
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end # GL::Texture
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# version.rb
|
7
|
+
# Version codes for opengl-aux
|
8
|
+
|
9
|
+
|
10
|
+
module GL
|
11
|
+
OPENGL_AUX_VERSION = '1.0.0.pre1'
|
12
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# vertex_array.rb
|
7
|
+
# GL vertex array object wrapper.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
require 'opengl-aux/error'
|
12
|
+
|
13
|
+
|
14
|
+
class GL::VertexArray
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
def current_binding
|
19
|
+
GL.glGetInteger(GL::GL_VERTEX_ARRAY_BINDING)
|
20
|
+
end
|
21
|
+
|
22
|
+
def preserve_binding
|
23
|
+
raise ArgumentError, "No block given" unless block_given?
|
24
|
+
binding = current_binding
|
25
|
+
begin
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
GL.glBindVertexArray(binding)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end # singleton_class
|
33
|
+
|
34
|
+
|
35
|
+
attr_reader :name
|
36
|
+
|
37
|
+
def initialize(name = nil)
|
38
|
+
@name = name || 0
|
39
|
+
yield self if block_given?
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete
|
43
|
+
if @name != 0
|
44
|
+
GL.glDeleteVertexArrays(@name)
|
45
|
+
@name = 0
|
46
|
+
end
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_vertex_array?
|
51
|
+
GL::glIsVertexArray(@name) != GL::GL_FALSE
|
52
|
+
end
|
53
|
+
|
54
|
+
def bind
|
55
|
+
if block_given?
|
56
|
+
self.class.preserve_binding do
|
57
|
+
bind
|
58
|
+
yield self
|
59
|
+
end
|
60
|
+
else
|
61
|
+
if @name == 0
|
62
|
+
@name = GL.glGenVertexArrays(1)
|
63
|
+
if @name == 0
|
64
|
+
raise GL::GLCreateError, "Unable to allocate vertex array object"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
GL.glBindVertexArray(@name)
|
69
|
+
self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end # GL::VertexArray
|
data/lib/opengl-aux.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# This file is part of the opengl-aux project.
|
2
|
+
# <https://github.com/nilium/opengl-aux>
|
3
|
+
#
|
4
|
+
# -----------------------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# opengl-aux.rb
|
7
|
+
# Root file of opengl-aux -- requires all relevant sub-files.
|
8
|
+
|
9
|
+
|
10
|
+
require 'opengl-aux/gl'
|
11
|
+
require 'opengl-aux/error'
|
12
|
+
require 'opengl-aux/vertex_array'
|
13
|
+
require 'opengl-aux/buffer'
|
14
|
+
require 'opengl-aux/texture'
|
15
|
+
require 'opengl-aux/shader'
|
16
|
+
require 'opengl-aux/program'
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: opengl-aux
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Noel Raymond Cower
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: opengl-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: snow-data
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.3.1
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.3'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.3.1
|
47
|
+
description: A collection auxiliary of functions and types to simplify using the opengl-core
|
48
|
+
gem.
|
49
|
+
email: ncower@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/opengl-aux.rb
|
55
|
+
- lib/opengl-aux/buffer.rb
|
56
|
+
- lib/opengl-aux/error.rb
|
57
|
+
- lib/opengl-aux/gl.rb
|
58
|
+
- lib/opengl-aux/program.rb
|
59
|
+
- lib/opengl-aux/shader.rb
|
60
|
+
- lib/opengl-aux/texture.rb
|
61
|
+
- lib/opengl-aux/version.rb
|
62
|
+
- lib/opengl-aux/vertex_array.rb
|
63
|
+
homepage: https://github.com/nilium/opengl-aux
|
64
|
+
licenses:
|
65
|
+
- Simplified BSD
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.3.1
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 2.2.1
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Auxiliary types and functions for OpenGL use.
|
87
|
+
test_files: []
|
88
|
+
has_rdoc:
|