opengl-core 1.0.1 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55bdceadec316a5cd6b73898cc0ab222ad09df0f
4
- data.tar.gz: c06ce592e0f3bfcab2d897c3ea5e87359350aa03
3
+ metadata.gz: c407076d78ec2776bf4d930d623b95f2c761c70b
4
+ data.tar.gz: d4685fda0b7fa879b6de9a3bb3871b5fa4d077b3
5
5
  SHA512:
6
- metadata.gz: 54176bf34be034bfb3e7cdf613d1efb23bb0a0b30a56cf8324372b06cdb93cd5768f03281c2c121b5d08c116f14588770ed3f06f8d522a0f8e4426f547ef697a
7
- data.tar.gz: b77fe84a6e9303886a09d850182e033a274f6647f1d2fc729b5e5d98e15e4be24406b87c39a4e487c9049e30f435e3466b01788eb281f857c9da27b372c26422
6
+ metadata.gz: 998d1e941a7d72130eb9a45ee307694d247d28f2639e6dc30083b49edaf34ddb8d320a692197105e5c9668c04a3a21c77e00aa6cf3d8764574b0fdecadead5c9
7
+ data.tar.gz: 112b7d8abd9e5dc7620fdfb82b82f08a88b336e95fbbd80a2148c8136ebdfc428c0d21d2887031c11fc8bde533a5aa9743004d8351656598d030444b6f47123e
@@ -1,6 +1,7 @@
1
1
  #include "ruby.h"
2
2
 
3
3
 
4
+ /* @api private */
4
5
  static VALUE plat_is_apple(VALUE self)
5
6
  {
6
7
  #if defined(__APPLE__)
@@ -11,6 +12,7 @@ static VALUE plat_is_apple(VALUE self)
11
12
  }
12
13
 
13
14
 
15
+ /* @api private */
14
16
  static VALUE plat_is_windows(VALUE self)
15
17
  {
16
18
  #if defined(_WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
@@ -21,6 +23,7 @@ static VALUE plat_is_windows(VALUE self)
21
23
  }
22
24
 
23
25
 
26
+ /* @api private */
24
27
  static VALUE plat_is_unix(VALUE self)
25
28
  {
26
29
  #if defined(__unix) || defined(__unix__) || defined(unix) || defined(__APPLE__)
@@ -31,6 +34,7 @@ static VALUE plat_is_unix(VALUE self)
31
34
  }
32
35
 
33
36
 
37
+ /* @api private */
34
38
  static VALUE plat_is_linux(VALUE self)
35
39
  {
36
40
  #if defined(__linux__) || defined(linux) || defined(__linux)
@@ -43,9 +47,10 @@ static VALUE plat_is_linux(VALUE self)
43
47
 
44
48
  void Init_opengl_stub(void)
45
49
  {
46
- VALUE module = rb_define_module("GlSym");
47
- rb_define_singleton_method(module, "apple?", plat_is_apple, 0);
48
- rb_define_singleton_method(module, "windows?", plat_is_windows, 0);
49
- rb_define_singleton_method(module, "unix?", plat_is_unix, 0);
50
- rb_define_singleton_method(module, "linux?", plat_is_linux, 0);
50
+ VALUE gl_module = rb_define_module("Gl");
51
+ VALUE gl_sym_module = rb_define_module_under(gl_module, "GlSym");
52
+ rb_define_singleton_method(gl_sym_module, "apple?", plat_is_apple, 0);
53
+ rb_define_singleton_method(gl_sym_module, "windows?", plat_is_windows, 0);
54
+ rb_define_singleton_method(gl_sym_module, "unix?", plat_is_unix, 0);
55
+ rb_define_singleton_method(gl_sym_module, "linux?", plat_is_linux, 0);
51
56
  }
data/lib/opengl-core.rb CHANGED
@@ -4,4 +4,25 @@ require 'opengl-core/gl_enums'
4
4
  require 'opengl-core/gl_commands'
5
5
 
6
6
  module Gl
7
+
8
+ # Checks if a GL command is availalbe to use. This necessarily loads the
9
+ # command if it's not yet loaded just to check if it exists, so do not call
10
+ # this from multiple threads when other Gl commands are being loaded. If you
11
+ # want to ensure this only reads, you can call load_all_gl_commands! ahead of
12
+ # time and query it afterward.
13
+ def have_gl_command?(command)
14
+ !!GlSym.__load_gl_sym__(command.intern)
15
+ end
16
+
17
+ # Does what it says on the tin. Should only be called once, preferably from
18
+ # the main thread, though I'm not aware of any thread requirements re: symbol
19
+ # loading. If you're using Gl commands from multiple threads with multiple
20
+ # contexts, you should call this before using any Gl commands.
21
+ def load_all_gl_commands!()
22
+ GlSym::GL_COMMAND_TYPES.each_key { |fnsym| GlSym.__load_gl_sym__(fnsym) }
23
+ self
24
+ end
25
+
26
+ extend self
27
+
7
28
  end
@@ -0,0 +1,7 @@
1
+ require 'opengl-core'
2
+ require 'opengl-core/aux/gl'
3
+ require 'opengl-core/aux/vertex_array'
4
+ require 'opengl-core/aux/buffer'
5
+ require 'opengl-core/aux/texture'
6
+ require 'opengl-core/aux/shader'
7
+ require 'opengl-core/aux/program'
@@ -0,0 +1,44 @@
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
@@ -0,0 +1,238 @@
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
@@ -0,0 +1,66 @@
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
@@ -0,0 +1,116 @@
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
+ attr_reader :kind
11
+
12
+ def initialize(name = nil)
13
+ super()
14
+ @name = (name != 0 && name) || Gl.glCreateProgram()
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] = uniform_location(key)
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_locations[uniform_name.to_sym] =
90
+ (@uniform_locations[uniform_name.to_sym] || -1)
91
+ self
92
+ end
93
+
94
+ def uniform_location(uniform_name)
95
+ uniform_sym = uniform_name.to_sym
96
+ @uniform_locations[uniform_sym] ||
97
+ (@uniform_locations[uniform_sym] =
98
+ Gl.glGetUniformLocation(@name, uniform_name.to_s))
99
+ end
100
+ alias_method :[], :uniform_location
101
+
102
+ def subroutine_uniform_location(shader_kind, uniform_name)
103
+ Gl.glGetSubroutineUniformLocation(@name, shader_kind, uniform_name)
104
+ end
105
+
106
+ def bind_attrib_location(attrib_index, attrib_name)
107
+ Gl.glBindAttribLocation(@name, attrib_index, attrib_name.to_s)
108
+ self
109
+ end
110
+
111
+ def bind_frag_data_location(color_number, frag_data_name)
112
+ Gl.glBindFragDataLocation(@name, color_number, frag_data_name.to_s)
113
+ self
114
+ end
115
+
116
+ end