danabr75-opengl 0.10.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.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +29 -0
  3. data/.gemtest +0 -0
  4. data/.gitignore +6 -0
  5. data/.travis.yml +19 -0
  6. data/Gemfile +8 -0
  7. data/History.md +101 -0
  8. data/MIT-LICENSE +18 -0
  9. data/Manifest.txt +142 -0
  10. data/README.rdoc +105 -0
  11. data/Rakefile +170 -0
  12. data/danabr75-opengl.gemspec +32 -0
  13. data/examples/NeHe/NeHe.png +0 -0
  14. data/examples/NeHe/crate.png +0 -0
  15. data/examples/NeHe/glass.png +0 -0
  16. data/examples/NeHe/nehe_lesson02.rb +117 -0
  17. data/examples/NeHe/nehe_lesson03.rb +123 -0
  18. data/examples/NeHe/nehe_lesson04.rb +132 -0
  19. data/examples/NeHe/nehe_lesson05.rb +182 -0
  20. data/examples/NeHe/nehe_lesson06.rb +186 -0
  21. data/examples/NeHe/nehe_lesson07.rb +240 -0
  22. data/examples/NeHe/nehe_lesson08.rb +255 -0
  23. data/examples/NeHe/nehe_lesson09.rb +203 -0
  24. data/examples/NeHe/nehe_lesson11.rb +176 -0
  25. data/examples/NeHe/nehe_lesson12.rb +203 -0
  26. data/examples/NeHe/nehe_lesson16.rb +211 -0
  27. data/examples/NeHe/nehe_lesson19.rb +209 -0
  28. data/examples/NeHe/nehe_lesson36.rb +308 -0
  29. data/examples/NeHe/particle.png +0 -0
  30. data/examples/NeHe/star.png +0 -0
  31. data/examples/NeHe/tim.png +0 -0
  32. data/examples/OrangeBook/3Dlabs-License.txt +33 -0
  33. data/examples/OrangeBook/brick.frag +36 -0
  34. data/examples/OrangeBook/brick.rb +378 -0
  35. data/examples/OrangeBook/brick.vert +41 -0
  36. data/examples/OrangeBook/particle.frag +17 -0
  37. data/examples/OrangeBook/particle.rb +408 -0
  38. data/examples/OrangeBook/particle.vert +38 -0
  39. data/examples/README +16 -0
  40. data/examples/RedBook/aapoly.rb +143 -0
  41. data/examples/RedBook/aargb.rb +121 -0
  42. data/examples/RedBook/accanti.rb +164 -0
  43. data/examples/RedBook/accpersp.rb +217 -0
  44. data/examples/RedBook/alpha.rb +125 -0
  45. data/examples/RedBook/alpha3D.rb +160 -0
  46. data/examples/RedBook/bezcurve.rb +107 -0
  47. data/examples/RedBook/bezmesh.rb +139 -0
  48. data/examples/RedBook/checker.rb +126 -0
  49. data/examples/RedBook/clip.rb +97 -0
  50. data/examples/RedBook/colormat.rb +137 -0
  51. data/examples/RedBook/cube.rb +71 -0
  52. data/examples/RedBook/depthcue.rb +101 -0
  53. data/examples/RedBook/dof.rb +206 -0
  54. data/examples/RedBook/double.rb +107 -0
  55. data/examples/RedBook/drawf.rb +93 -0
  56. data/examples/RedBook/feedback.rb +147 -0
  57. data/examples/RedBook/fog.rb +168 -0
  58. data/examples/RedBook/font.rb +153 -0
  59. data/examples/RedBook/hello.rb +81 -0
  60. data/examples/RedBook/image.rb +139 -0
  61. data/examples/RedBook/jitter.rb +207 -0
  62. data/examples/RedBook/light.rb +157 -0
  63. data/examples/RedBook/lines.rb +130 -0
  64. data/examples/RedBook/list.rb +113 -0
  65. data/examples/RedBook/material.rb +276 -0
  66. data/examples/RedBook/mipmap.rb +158 -0
  67. data/examples/RedBook/model.rb +115 -0
  68. data/examples/RedBook/movelight.rb +134 -0
  69. data/examples/RedBook/pickdepth.rb +181 -0
  70. data/examples/RedBook/planet.rb +110 -0
  71. data/examples/RedBook/quadric.rb +160 -0
  72. data/examples/RedBook/robot.rb +117 -0
  73. data/examples/RedBook/select.rb +198 -0
  74. data/examples/RedBook/smooth.rb +97 -0
  75. data/examples/RedBook/stencil.rb +165 -0
  76. data/examples/RedBook/stroke.rb +169 -0
  77. data/examples/RedBook/surface.rb +168 -0
  78. data/examples/RedBook/teaambient.rb +134 -0
  79. data/examples/RedBook/teapots.rb +184 -0
  80. data/examples/RedBook/tess.rb +185 -0
  81. data/examples/RedBook/texbind.rb +149 -0
  82. data/examples/RedBook/texgen.rb +171 -0
  83. data/examples/RedBook/texturesurf.rb +130 -0
  84. data/examples/RedBook/varray.rb +161 -0
  85. data/examples/RedBook/wrap.rb +150 -0
  86. data/examples/misc/OGLBench.rb +338 -0
  87. data/examples/misc/anisotropic.rb +196 -0
  88. data/examples/misc/fbo_test.rb +357 -0
  89. data/examples/misc/font-glut.rb +47 -0
  90. data/examples/misc/glfwtest.rb +30 -0
  91. data/examples/misc/plane.rb +161 -0
  92. data/examples/misc/readpixel.rb +66 -0
  93. data/examples/misc/sdltest.rb +36 -0
  94. data/examples/misc/trislam.rb +829 -0
  95. data/ext/opengl/GL/gl.h +2115 -0
  96. data/ext/opengl/GL/glext.h +11770 -0
  97. data/ext/opengl/common.h +372 -0
  98. data/ext/opengl/conv.h +247 -0
  99. data/ext/opengl/extconf.rb +19 -0
  100. data/ext/opengl/fptr_struct.h +912 -0
  101. data/ext/opengl/funcdef.h +279 -0
  102. data/ext/opengl/gl-1.0-1.1.c +3345 -0
  103. data/ext/opengl/gl-1.2.c +155 -0
  104. data/ext/opengl/gl-1.3.c +447 -0
  105. data/ext/opengl/gl-1.4.c +346 -0
  106. data/ext/opengl/gl-1.5.c +225 -0
  107. data/ext/opengl/gl-2.0.c +665 -0
  108. data/ext/opengl/gl-2.1.c +57 -0
  109. data/ext/opengl/gl-3.0.c +502 -0
  110. data/ext/opengl/gl-enums.c +4853 -0
  111. data/ext/opengl/gl-enums.h +14528 -0
  112. data/ext/opengl/gl-error.c +110 -0
  113. data/ext/opengl/gl-error.h +25 -0
  114. data/ext/opengl/gl-ext-3dfx.c +27 -0
  115. data/ext/opengl/gl-ext-arb.c +880 -0
  116. data/ext/opengl/gl-ext-ati.c +41 -0
  117. data/ext/opengl/gl-ext-ext.c +885 -0
  118. data/ext/opengl/gl-ext-gremedy.c +41 -0
  119. data/ext/opengl/gl-ext-nv.c +679 -0
  120. data/ext/opengl/gl.c +265 -0
  121. data/ext/opengl/gl_buffer.c +202 -0
  122. data/ext/opengl/glimpl.c +187 -0
  123. data/ext/opengl/glimpl.h +47 -0
  124. data/ext/opengl/opengl.c +9 -0
  125. data/lib/gl.rb +1 -0
  126. data/lib/opengl.rb +79 -0
  127. data/lib/opengl/bindings_version.rb +4 -0
  128. data/lib/opengl/implementation.rb +38 -0
  129. data/lib/opengl/test_case.rb +86 -0
  130. data/test/dummy.xorg.conf +140 -0
  131. data/test/test_gl.rb +45 -0
  132. data/test/test_gl_10_11.rb +1363 -0
  133. data/test/test_gl_12.rb +71 -0
  134. data/test/test_gl_13.rb +221 -0
  135. data/test/test_gl_14.rb +218 -0
  136. data/test/test_gl_15.rb +258 -0
  137. data/test/test_gl_20.rb +417 -0
  138. data/test/test_gl_21.rb +436 -0
  139. data/test/test_gl_ext_arb.rb +508 -0
  140. data/test/test_gl_ext_ati.rb +28 -0
  141. data/test/test_gl_ext_ext.rb +608 -0
  142. data/test/test_gl_ext_gremedy.rb +29 -0
  143. data/test/test_gl_ext_nv.rb +349 -0
  144. data/test/test_glimpl.rb +23 -0
  145. data/test/test_opengl_buffer.rb +122 -0
  146. data/utils/README +6 -0
  147. data/utils/enumgen.rb +108 -0
  148. data/utils/extlistgen.rb +90 -0
  149. metadata +326 -0
@@ -0,0 +1,265 @@
1
+ /*
2
+ * Copyright (C) 1999 - 2005 Yoshi <yoshi@giganet.net>
3
+ * Copyright (C) 2006 John M. Gabriele <jmg3000@gmail.com>
4
+ * Copyright (C) 2007 Jan Dvorak <jan.dvorak@kraxnet.cz>
5
+ *
6
+ * This program is distributed under the terms of the MIT license.
7
+ * See the included MIT-LICENSE file for the terms of this license.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
13
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ */
17
+
18
+ #include "common.h"
19
+
20
+ void gl_init_enums(VALUE);
21
+ void gl_init_functions_1_0__1_1(VALUE);
22
+ void gl_init_functions_1_2(VALUE);
23
+ void gl_init_functions_1_3(VALUE);
24
+ void gl_init_functions_1_4(VALUE);
25
+ void gl_init_functions_1_5(VALUE);
26
+ void gl_init_functions_2_0(VALUE);
27
+ void gl_init_functions_2_1(VALUE);
28
+ void gl_init_functions_3_0(VALUE);
29
+ void gl_init_functions_ext_3dfx(VALUE);
30
+ void gl_init_functions_ext_arb(VALUE);
31
+ void gl_init_functions_ext_ati(VALUE);
32
+ void gl_init_functions_ext_ext(VALUE);
33
+ void gl_init_functions_ext_gremedy(VALUE);
34
+ void gl_init_functions_ext_nv(VALUE);
35
+ void gl_init_buffer(VALUE);
36
+ void gl_init_glimpl(VALUE);
37
+
38
+ VALUE g_default_glimpl;
39
+
40
+ /* Returns current OpenGL version as major, minor or 0,0 if
41
+ * unknown (context not yet initialised etc.) The version is
42
+ * cached for subsequent calls.
43
+ */
44
+ const int *GetOpenglVersion(VALUE obj)
45
+ {
46
+ int *opengl_version = GET_GLIMPL_VARIABLE(opengl_version);
47
+ DECL_GL_FUNC_PTR(const GLubyte *,glGetString,(GLenum name));
48
+
49
+ LOAD_GL_FUNC(glGetString, NULL);
50
+ if (opengl_version[0]==0) { /* not cached, query */
51
+ const char *vstr = (const char *) fptr_glGetString(GL_VERSION);
52
+ CHECK_GLERROR_FROM("glGetString");
53
+ if (vstr){
54
+ int v0, v1;
55
+ sscanf( vstr, "%d.%d", &v0, &v1 );
56
+ SET_GLIMPL_VARIABLE(opengl_version[0], v0);
57
+ SET_GLIMPL_VARIABLE(opengl_version[1], v1);
58
+ }
59
+ }
60
+ return opengl_version;
61
+ }
62
+
63
+ /* Checks if OpenGL version is at least the same or higher than
64
+ * major.minor
65
+ */
66
+ GLboolean CheckOpenglVersion(VALUE obj, int major, int minor)
67
+ {
68
+ const int *version;
69
+
70
+ version = GetOpenglVersion(obj);
71
+
72
+ if (version[0]>major || (version[0]==major && version[1] >=minor))
73
+ return GL_TRUE;
74
+ else
75
+ return GL_FALSE;
76
+ }
77
+
78
+ /* Returns supported OpenGL extensions as char* or NULL
79
+ * if unknown (context not yet initialised etc.) The list is
80
+ * cached for subsequent calls.
81
+ */
82
+ const char *GetOpenglExtensions(VALUE obj)
83
+ {
84
+ char *opengl_extensions = GET_GLIMPL_VARIABLE(opengl_extensions);
85
+ DECL_GL_FUNC_PTR(const GLubyte *,glGetString,(GLenum name));
86
+
87
+ LOAD_GL_FUNC(glGetString, NULL);
88
+ if (opengl_extensions == NULL) {
89
+ const char *estr = (const char *) fptr_glGetString(GL_EXTENSIONS);
90
+ CHECK_GLERROR_FROM("glGetString");
91
+ if (estr) {
92
+ long len = strlen(estr);
93
+ opengl_extensions = ALLOC_N(GLchar,len+1+1); /* terminating null and added space */
94
+ strcpy(opengl_extensions,estr);
95
+ opengl_extensions[len] = ' '; /* add space char for easy searchs */
96
+ opengl_extensions[len+1] = '\0';
97
+ SET_GLIMPL_VARIABLE(opengl_extensions, opengl_extensions);
98
+ }
99
+ }
100
+ return opengl_extensions;
101
+ }
102
+
103
+ /* Checks if extension is supported by the current OpenGL implementation
104
+ */
105
+ GLboolean CheckExtension(VALUE obj, const char *name)
106
+ {
107
+ const char *extensions;
108
+ char *name_tmp;
109
+ long name_len;
110
+ GLboolean res;
111
+
112
+ extensions = GetOpenglExtensions(obj);
113
+
114
+ if(extensions==NULL)
115
+ return GL_FALSE;
116
+
117
+ /* add trailing space */
118
+ name_len = strlen(name);
119
+ name_tmp = ALLOC_N(GLchar,name_len+1+1); /* terminating null and added space */
120
+ strcpy(name_tmp,name);
121
+ name_tmp[name_len] = ' '; /* add space char for search */
122
+ name_tmp[name_len+1] = '\0';
123
+
124
+ if (strstr(extensions,name_tmp))
125
+ res = GL_TRUE;
126
+ else
127
+ res = GL_FALSE;
128
+
129
+ xfree(name_tmp);
130
+ return res;
131
+ }
132
+
133
+ /* wrapper for CheckOpenglVersion and CheckExtension, also used by macros
134
+ */
135
+ GLboolean CheckVersionExtension(VALUE obj, const char *name)
136
+ {
137
+ if (name && name[0] && name[0]>='0' && name[0]<='9') { /* GL version query */
138
+ int major,minor;
139
+
140
+ if (sscanf( name, "%d.%d", &major, &minor ) != 2)
141
+ return GL_FALSE;
142
+
143
+ return (CheckOpenglVersion(obj, major,minor));
144
+ } else {
145
+ return (CheckExtension(obj, name));
146
+ }
147
+ }
148
+
149
+ void EnsureVersionExtension(VALUE obj, const char *verext)
150
+ {
151
+ if (CheckVersionExtension(obj, verext) == GL_FALSE) {
152
+ if (isdigit(verext[0])) {
153
+ rb_raise(rb_eNotImpError,
154
+ "OpenGL version %s is not available on this system",verext);
155
+ } else {
156
+ rb_raise(rb_eNotImpError,
157
+ "Extension %s is not available on this system",verext);
158
+ }
159
+ }
160
+ }
161
+
162
+ /* Checks if given OpenGL version or extension is available
163
+ */
164
+ static VALUE
165
+ IsAvailable(VALUE obj, VALUE arg1)
166
+ {
167
+ char *name = NULL;
168
+ VALUE s;
169
+ GLboolean res;
170
+
171
+ s = rb_funcall(arg1, rb_intern("to_s"), 0);
172
+ name = RSTRING_PTR(s);
173
+
174
+ res = CheckVersionExtension(obj, name);
175
+
176
+ return GLBOOL2RUBY(res);
177
+ }
178
+
179
+ /* Checks whether non-zero buffer of type $buffer is bound
180
+ * - this affects several functions that pass data from/to OpenGL.
181
+ */
182
+ GLint CheckBufferBinding(VALUE obj, GLint buffer)
183
+ {
184
+ GLint result = 0;
185
+ DECL_GL_FUNC_PTR(void,glGetIntegerv,(GLenum pname, GLint *params));
186
+
187
+ LOAD_GL_FUNC(glGetIntegerv, NULL);
188
+
189
+ /* check if the buffer functionality is supported */
190
+ switch(buffer) {
191
+ case GL_ARRAY_BUFFER_BINDING:
192
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
193
+ if (!CheckOpenglVersion(obj, 1,5))
194
+ return 0;
195
+ break;
196
+ case GL_PIXEL_PACK_BUFFER_BINDING:
197
+ case GL_PIXEL_UNPACK_BUFFER_BINDING:
198
+ if (!CheckOpenglVersion(obj, 2,1))
199
+ return 0;
200
+ break;
201
+ default:
202
+ rb_raise(rb_eRuntimeError,"Internal Error: buffer type '%i' does not exist", buffer);
203
+ break;
204
+ }
205
+ fptr_glGetIntegerv(buffer,&result);
206
+ CHECK_GLERROR_FROM("glGetIntegerv");
207
+ return result;
208
+ }
209
+
210
+ static VALUE
211
+ rb_gl_s_get_implementation( VALUE module )
212
+ {
213
+ if( NIL_P(g_default_glimpl) ){
214
+ VALUE rb_cGlimpl = rb_path2class("Gl::DefaultImplementation");
215
+ g_default_glimpl = rb_funcall(rb_cGlimpl, rb_intern("open"), 0);
216
+ }
217
+ return g_default_glimpl;
218
+ }
219
+
220
+ static VALUE
221
+ rb_gl_s_set_implementation( VALUE module, VALUE glimpl )
222
+ {
223
+ if(!rb_obj_is_kind_of(glimpl, rb_cGlimpl)){
224
+ rb_raise(rb_eArgError, "wrong argument type %s (expected kind of Gl::Implementation)", rb_obj_classname(glimpl));
225
+ }
226
+ g_default_glimpl = glimpl;
227
+ return glimpl;
228
+ }
229
+
230
+ void Init_gl(VALUE module)
231
+ {
232
+ gl_init_glimpl(module);
233
+ gl_init_error(rb_cGlimpl, module);
234
+ gl_init_enums(module);
235
+ gl_init_functions_1_0__1_1(rb_cGlimpl);
236
+ gl_init_functions_1_2(rb_cGlimpl);
237
+ gl_init_functions_1_3(rb_cGlimpl);
238
+ gl_init_functions_1_4(rb_cGlimpl);
239
+ gl_init_functions_1_5(rb_cGlimpl);
240
+ gl_init_functions_2_0(rb_cGlimpl);
241
+ gl_init_functions_2_1(rb_cGlimpl);
242
+ gl_init_functions_3_0(rb_cGlimpl);
243
+ gl_init_functions_ext_3dfx(rb_cGlimpl);
244
+ gl_init_functions_ext_arb(rb_cGlimpl);
245
+ gl_init_functions_ext_ati(rb_cGlimpl);
246
+ gl_init_functions_ext_ext(rb_cGlimpl);
247
+ gl_init_functions_ext_gremedy(rb_cGlimpl);
248
+ gl_init_functions_ext_nv(rb_cGlimpl);
249
+ gl_init_buffer(module);
250
+
251
+
252
+ rb_define_method(rb_cGlimpl, "is_available?", IsAvailable, 1);
253
+ rb_define_method(rb_cGlimpl, "is_supported?", IsAvailable, 1);
254
+ rb_define_method(rb_cGlimpl, "extension_available?", IsAvailable, 1);
255
+ rb_define_method(rb_cGlimpl, "extension_supported?", IsAvailable, 1);
256
+ rb_define_method(rb_cGlimpl, "version_available?", IsAvailable, 1);
257
+ rb_define_method(rb_cGlimpl, "version_supported?", IsAvailable, 1);
258
+
259
+
260
+ rb_define_module_function(module, "implementation", rb_gl_s_get_implementation, 0);
261
+ rb_define_module_function(module, "implementation=", rb_gl_s_set_implementation, 1);
262
+
263
+ g_default_glimpl = Qnil;
264
+ rb_global_variable(&g_default_glimpl);
265
+ }
@@ -0,0 +1,202 @@
1
+ #include "common.h"
2
+
3
+ struct buffer {
4
+ VALUE glimpl;
5
+ void *ptr;
6
+ GLsizeiptr len;
7
+ GLenum target;
8
+ };
9
+
10
+ static void
11
+ buffer_mark(void *ptr)
12
+ {
13
+ struct buffer *this = ptr;
14
+ rb_gc_mark(this->glimpl);
15
+ }
16
+
17
+ static void
18
+ buffer_free(void *ptr) {
19
+ struct buffer *buf = ptr;
20
+ VALUE obj = buf->glimpl;
21
+ DECL_GL_FUNC_PTR(GLboolean,glUnmapBuffer,(GLenum));
22
+ LOAD_GL_FUNC(glUnmapBuffer, "1.5");
23
+
24
+ if (buf->ptr != NULL)
25
+ fptr_glUnmapBuffer(buf->target);
26
+ }
27
+
28
+ static size_t
29
+ buffer_memsize(const void *ptr) {
30
+ const struct buffer *buf = ptr;
31
+ return sizeof(struct buffer) + (size_t)buf->len;
32
+ }
33
+
34
+ static const rb_data_type_t buffer_type = {
35
+ "OpenGL/buffer",
36
+ { buffer_mark, buffer_free, buffer_memsize, },
37
+ };
38
+
39
+ VALUE
40
+ rb_gl_buffer_s_map(int argc, VALUE *argv, VALUE klass)
41
+ {
42
+ VALUE _target;
43
+ VALUE _access;
44
+ VALUE obj;
45
+ struct buffer *buf;
46
+ DECL_GL_FUNC_PTR(GLvoid *,glMapBuffer,(GLenum,GLenum));
47
+
48
+ rb_scan_args(argc, argv, "21", &_target, &_access, &obj);
49
+ if(NIL_P(obj)){
50
+ obj = g_default_glimpl;
51
+ } else if(!rb_obj_is_kind_of(obj, rb_cGlimpl)){
52
+ rb_raise(rb_eArgError, "wrong argument type %s (expected kind of Gl::Implementation)", rb_obj_classname(obj));
53
+ }
54
+
55
+ buf = ALLOC(struct buffer);
56
+ LOAD_GL_FUNC(glMapBuffer, "1.5");
57
+
58
+ buf->target = RUBY2GLENUM(_target);
59
+ buf->len = 0;
60
+ buf->glimpl = obj;
61
+
62
+ buf->ptr = fptr_glMapBuffer(buf->target, RUBY2GLENUM(_access));
63
+
64
+ if (buf->ptr == NULL) {
65
+ xfree(buf);
66
+ CHECK_GLERROR_FROM("glMapBuffer");
67
+ }
68
+
69
+ return TypedData_Wrap_Struct(klass, &buffer_type, buf);
70
+ }
71
+
72
+ static VALUE
73
+ rb_gl_buffer_addr(VALUE self) {
74
+ struct buffer *buf;
75
+
76
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
77
+
78
+ return SIZET2NUM((size_t)buf->ptr);
79
+ }
80
+
81
+ static VALUE
82
+ rb_gl_buffer_length(VALUE self) {
83
+ struct buffer *buf;
84
+
85
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
86
+
87
+ return RETCONV_GLsizeiptr(buf->len);
88
+ }
89
+
90
+ static VALUE
91
+ rb_gl_buffer_read(int argc, VALUE *argv, VALUE self) {
92
+ struct buffer *buf;
93
+ VALUE _length, _offset;
94
+ GLsizeiptr offset, length;
95
+
96
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
97
+
98
+ rb_scan_args(argc, argv, "02", &_length, &_offset);
99
+
100
+ if (buf->len == 0 && NIL_P(_length))
101
+ rb_raise(rb_eArgError, "length must be provided for unbounded buffer");
102
+
103
+ length = NUM2SIZET(_length);
104
+
105
+ if (NIL_P(_offset)) {
106
+ offset = 0;
107
+ } else {
108
+ offset = NUM2SIZET(_offset);
109
+ }
110
+
111
+ if (buf->len != 0 && length + offset > buf->len)
112
+ rb_raise(rb_eArgError, "read to %lu past end of buffer %lu",
113
+ (unsigned long)(length + offset), (unsigned long)buf->len);
114
+
115
+ return rb_str_new((char *)buf->ptr + offset, length);
116
+ }
117
+
118
+ static VALUE
119
+ rb_gl_buffer_target(VALUE self) {
120
+ struct buffer *buf;
121
+
122
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
123
+
124
+ return RETCONV_GLenum(buf->target);
125
+ }
126
+
127
+ static VALUE
128
+ rb_gl_buffer_unmap(VALUE self) {
129
+ struct buffer *buf;
130
+ VALUE obj;
131
+ DECL_GL_FUNC_PTR(GLboolean,glUnmapBuffer,(GLenum));
132
+
133
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
134
+ obj = buf->glimpl;
135
+
136
+ LOAD_GL_FUNC(glUnmapBuffer, "1.5");
137
+
138
+ if (!buf->ptr)
139
+ return self;
140
+
141
+ fptr_glUnmapBuffer(buf->target);
142
+
143
+ CHECK_GLERROR_FROM("glUnmapBuffer");
144
+
145
+ buf->ptr = NULL;
146
+ buf->len = 0;
147
+ buf->target = 0;
148
+
149
+ return self;
150
+ }
151
+
152
+ static VALUE
153
+ rb_gl_buffer_write(int argc, VALUE *argv, VALUE self) {
154
+ struct buffer *buf;
155
+ VALUE _data, _offset;
156
+ GLsizeiptr offset;
157
+ long length;
158
+
159
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
160
+
161
+ if (!buf->ptr)
162
+ rb_raise(rb_eArgError, "write to unmapped buffer");
163
+
164
+ rb_scan_args(argc, argv, "11", &_data, &_offset);
165
+
166
+ if (NIL_P(_data))
167
+ rb_raise(rb_eArgError, "cannot write nil to buffer");
168
+
169
+ _data = rb_String(_data);
170
+
171
+ length = RSTRING_LEN(_data);
172
+
173
+ if (NIL_P(_offset)) {
174
+ offset = 0;
175
+ } else {
176
+ offset = NUM2SIZET(_offset);
177
+ }
178
+
179
+ if (buf->len != 0 && length + offset > buf->len)
180
+ rb_raise(rb_eArgError, "write to %lu past end of buffer %lu",
181
+ (unsigned long)(length + offset), (unsigned long)buf->len);
182
+
183
+ memcpy((char *)buf->ptr + offset, RSTRING_PTR(_data), RSTRING_LEN(_data));
184
+
185
+ return self;
186
+ }
187
+
188
+ void
189
+ gl_init_buffer(VALUE module) {
190
+ VALUE cBuffer = rb_define_class_under(module, "Buffer", rb_cObject);
191
+
192
+ rb_undef_alloc_func(cBuffer);
193
+ rb_define_singleton_method(cBuffer, "map", rb_gl_buffer_s_map, -1);
194
+
195
+ rb_define_method(cBuffer, "addr", rb_gl_buffer_addr, 0);
196
+ rb_define_method(cBuffer, "length", rb_gl_buffer_length, 0);
197
+ rb_define_method(cBuffer, "read", rb_gl_buffer_read, -1);
198
+ rb_define_method(cBuffer, "target", rb_gl_buffer_target, 0);
199
+ rb_define_method(cBuffer, "unmap", rb_gl_buffer_unmap, 0);
200
+ rb_define_method(cBuffer, "write", rb_gl_buffer_write, -1);
201
+ }
202
+