opengl-core 1.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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