opengl 0.9.2-x86-mingw32 → 0.10.0.pre1-x86-mingw32

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -0
  3. data/Manifest.txt +5 -1
  4. data/README.rdoc +25 -28
  5. data/Rakefile +56 -28
  6. data/examples/RedBook/font.rb +2 -2
  7. data/examples/RedBook/light.rb +2 -0
  8. data/examples/RedBook/stroke.rb +6 -6
  9. data/ext/opengl/GL/gl.h +2115 -0
  10. data/ext/opengl/GL/glext.h +11770 -0
  11. data/ext/opengl/common.h +116 -172
  12. data/ext/opengl/conv.h +2 -2
  13. data/ext/opengl/extconf.rb +3 -31
  14. data/ext/opengl/fptr_struct.h +912 -0
  15. data/ext/opengl/funcdef.h +29 -63
  16. data/ext/opengl/gl-1.0-1.1.c +918 -648
  17. data/ext/opengl/gl-1.2.c +13 -13
  18. data/ext/opengl/gl-1.3.c +68 -64
  19. data/ext/opengl/gl-1.4.c +64 -66
  20. data/ext/opengl/gl-1.5.c +32 -31
  21. data/ext/opengl/gl-2.0.c +126 -128
  22. data/ext/opengl/gl-2.1.c +8 -8
  23. data/ext/opengl/gl-3.0.c +102 -93
  24. data/ext/opengl/gl-enums.c +9 -29
  25. data/ext/opengl/gl-enums.h +31 -91
  26. data/ext/opengl/gl-error.c +15 -17
  27. data/ext/opengl/gl-error.h +4 -7
  28. data/ext/opengl/gl-ext-3dfx.c +2 -2
  29. data/ext/opengl/gl-ext-arb.c +176 -171
  30. data/ext/opengl/gl-ext-ati.c +4 -4
  31. data/ext/opengl/gl-ext-ext.c +151 -155
  32. data/ext/opengl/gl-ext-gremedy.c +4 -4
  33. data/ext/opengl/gl-ext-nv.c +141 -142
  34. data/ext/opengl/gl.c +121 -76
  35. data/ext/opengl/gl_buffer.c +44 -19
  36. data/ext/opengl/glimpl.c +187 -0
  37. data/ext/opengl/glimpl.h +47 -0
  38. data/ext/opengl/opengl.c +5 -3
  39. data/lib/opengl.rb +24 -4
  40. data/lib/opengl/1.9/opengl.so +0 -0
  41. data/lib/opengl/2.0/opengl.so +0 -0
  42. data/lib/opengl/2.1/opengl.so +0 -0
  43. data/lib/opengl/2.2/opengl.so +0 -0
  44. data/lib/opengl/2.3/opengl.so +0 -0
  45. data/lib/opengl/bindings_version.rb +4 -0
  46. data/lib/opengl/implementation.rb +38 -0
  47. data/opengl.gemspec +33 -0
  48. data/test/test_gl.rb +7 -0
  49. data/test/test_gl_21.rb +21 -21
  50. data/test/test_gl_ext_arb.rb +1 -1
  51. data/test/test_glimpl.rb +23 -0
  52. data/test/test_opengl_buffer.rb +2 -0
  53. data/utils/enumgen.rb +2 -2
  54. metadata +69 -60
  55. checksums.yaml.gz.sig +0 -2
  56. data.tar.gz.sig +0 -0
  57. data/ext/opengl/gl-types.h +0 -67
  58. metadata.gz.sig +0 -0
data/ext/opengl/gl.c CHANGED
@@ -17,8 +17,6 @@
17
17
 
18
18
  #include "common.h"
19
19
 
20
- static VALUE module;
21
-
22
20
  void gl_init_enums(VALUE);
23
21
  void gl_init_functions_1_0__1_1(VALUE);
24
22
  void gl_init_functions_1_2(VALUE);
@@ -34,34 +32,42 @@ void gl_init_functions_ext_ati(VALUE);
34
32
  void gl_init_functions_ext_ext(VALUE);
35
33
  void gl_init_functions_ext_gremedy(VALUE);
36
34
  void gl_init_functions_ext_nv(VALUE);
37
- void gl_init_buffer(void);
35
+ void gl_init_buffer(VALUE);
36
+ void gl_init_glimpl(VALUE);
38
37
 
39
- static int opengl_version[2]; /* major, minor */
40
- static char *opengl_extensions = NULL;
38
+ VALUE g_default_glimpl;
41
39
 
42
40
  /* Returns current OpenGL version as major, minor or 0,0 if
43
41
  * unknown (context not yet initialised etc.) The version is
44
42
  * cached for subsequent calls.
45
43
  */
46
- const int *GetOpenglVersion(void)
44
+ const int *GetOpenglVersion(VALUE obj)
47
45
  {
48
- if (opengl_version[0]==0) { /* not cached, query */
49
- const char *vstr = (const char *) glGetString(GL_VERSION);
50
- CHECK_GLERROR_FROM("glGetString");
51
- if (vstr)
52
- sscanf( vstr, "%d.%d", &opengl_version[0], &opengl_version[1] );
53
- }
54
- return opengl_version;
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;
55
61
  }
56
62
 
57
63
  /* Checks if OpenGL version is at least the same or higher than
58
64
  * major.minor
59
65
  */
60
- GLboolean CheckOpenglVersion(int major, int minor)
66
+ GLboolean CheckOpenglVersion(VALUE obj, int major, int minor)
61
67
  {
62
68
  const int *version;
63
69
 
64
- version = GetOpenglVersion();
70
+ version = GetOpenglVersion(obj);
65
71
 
66
72
  if (version[0]>major || (version[0]==major && version[1] >=minor))
67
73
  return GL_TRUE;
@@ -73,33 +79,38 @@ GLboolean CheckOpenglVersion(int major, int minor)
73
79
  * if unknown (context not yet initialised etc.) The list is
74
80
  * cached for subsequent calls.
75
81
  */
76
- const char *GetOpenglExtensions(void)
82
+ const char *GetOpenglExtensions(VALUE obj)
77
83
  {
78
- if (opengl_extensions == NULL) {
79
- const char *estr = (const char *) glGetString(GL_EXTENSIONS);
80
- CHECK_GLERROR_FROM("glGetString");
81
- if (estr) {
82
- long len = strlen(estr);
83
- opengl_extensions = ALLOC_N(GLchar,len+1+1); /* terminating null and added space */
84
- strcpy(opengl_extensions,estr);
85
- opengl_extensions[len] = ' '; /* add space char for easy searchs */
86
- opengl_extensions[len+1] = '\0';
87
- }
88
- }
89
- return opengl_extensions;
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;
90
101
  }
91
102
 
92
103
  /* Checks if extension is supported by the current OpenGL implementation
93
104
  */
94
- GLboolean CheckExtension(const char *name)
105
+ GLboolean CheckExtension(VALUE obj, const char *name)
95
106
  {
96
107
  const char *extensions;
97
108
  char *name_tmp;
98
109
  long name_len;
99
110
  GLboolean res;
100
-
101
- extensions = GetOpenglExtensions();
102
-
111
+
112
+ extensions = GetOpenglExtensions(obj);
113
+
103
114
  if(extensions==NULL)
104
115
  return GL_FALSE;
105
116
 
@@ -116,30 +127,42 @@ GLboolean CheckExtension(const char *name)
116
127
  res = GL_FALSE;
117
128
 
118
129
  xfree(name_tmp);
119
- return res;
130
+ return res;
120
131
  }
121
132
 
122
133
  /* wrapper for CheckOpenglVersion and CheckExtension, also used by macros
123
134
  */
124
- GLboolean CheckVersionExtension(const char *name)
135
+ GLboolean CheckVersionExtension(VALUE obj, const char *name)
125
136
  {
126
137
  if (name && name[0] && name[0]>='0' && name[0]<='9') { /* GL version query */
127
138
  int major,minor;
128
139
 
129
140
  if (sscanf( name, "%d.%d", &major, &minor ) != 2)
130
141
  return GL_FALSE;
131
-
132
- return (CheckOpenglVersion(major,minor));
142
+
143
+ return (CheckOpenglVersion(obj, major,minor));
133
144
  } else {
134
- return (CheckExtension(name));
145
+ return (CheckExtension(obj, name));
135
146
  }
136
147
  }
137
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
+
138
162
  /* Checks if given OpenGL version or extension is available
139
163
  */
140
164
  static VALUE
141
- IsAvailable(obj,arg1)
142
- VALUE obj,arg1;
165
+ IsAvailable(VALUE obj, VALUE arg1)
143
166
  {
144
167
  char *name = NULL;
145
168
  VALUE s;
@@ -148,7 +171,7 @@ VALUE obj,arg1;
148
171
  s = rb_funcall(arg1, rb_intern("to_s"), 0);
149
172
  name = RSTRING_PTR(s);
150
173
 
151
- res = CheckVersionExtension(name);
174
+ res = CheckVersionExtension(obj, name);
152
175
 
153
176
  return GLBOOL2RUBY(res);
154
177
  }
@@ -156,65 +179,87 @@ VALUE obj,arg1;
156
179
  /* Checks whether non-zero buffer of type $buffer is bound
157
180
  * - this affects several functions that pass data from/to OpenGL.
158
181
  */
159
- GLint CheckBufferBinding(GLint buffer)
182
+ GLint CheckBufferBinding(VALUE obj, GLint buffer)
160
183
  {
161
184
  GLint result = 0;
162
-
185
+ DECL_GL_FUNC_PTR(void,glGetIntegerv,(GLenum pname, GLint *params));
186
+
187
+ LOAD_GL_FUNC(glGetIntegerv, NULL);
188
+
163
189
  /* check if the buffer functionality is supported */
164
190
  switch(buffer) {
165
191
  case GL_ARRAY_BUFFER_BINDING:
166
192
  case GL_ELEMENT_ARRAY_BUFFER_BINDING:
167
- if (!CheckOpenglVersion(1,5))
193
+ if (!CheckOpenglVersion(obj, 1,5))
168
194
  return 0;
169
195
  break;
170
196
  case GL_PIXEL_PACK_BUFFER_BINDING:
171
197
  case GL_PIXEL_UNPACK_BUFFER_BINDING:
172
- if (!CheckOpenglVersion(2,1))
198
+ if (!CheckOpenglVersion(obj, 2,1))
173
199
  return 0;
174
200
  break;
175
201
  default:
176
202
  rb_raise(rb_eRuntimeError,"Internal Error: buffer type '%i' does not exist", buffer);
177
203
  break;
178
204
  }
179
- glGetIntegerv(buffer,&result);
205
+ fptr_glGetIntegerv(buffer,&result);
180
206
  CHECK_GLERROR_FROM("glGetIntegerv");
181
207
  return result;
182
208
  }
183
209
 
184
- DLLEXPORT void Init_gl()
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)
185
231
  {
186
- VALUE mOpenGL = rb_path2class("OpenGL");
187
- VALUE version = rb_const_get(mOpenGL, rb_intern("VERSION"));
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);
188
250
 
189
- gl_init_buffer();
190
251
 
191
- module = rb_define_module("Gl");
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);
192
258
 
193
- /* TODO remove */
194
- rb_define_const(module, "BINDINGS_VERSION", version);
195
- rb_define_const(module, "RUBY_OPENGL_VERSION", version);
196
259
 
197
- gl_init_error(module);
198
- gl_init_enums(module);
199
- gl_init_functions_1_0__1_1(module);
200
- gl_init_functions_1_2(module);
201
- gl_init_functions_1_3(module);
202
- gl_init_functions_1_4(module);
203
- gl_init_functions_1_5(module);
204
- gl_init_functions_2_0(module);
205
- gl_init_functions_2_1(module);
206
- gl_init_functions_3_0(module);
207
- gl_init_functions_ext_3dfx(module);
208
- gl_init_functions_ext_arb(module);
209
- gl_init_functions_ext_ati(module);
210
- gl_init_functions_ext_ext(module);
211
- gl_init_functions_ext_gremedy(module);
212
- gl_init_functions_ext_nv(module);
213
-
214
- rb_define_module_function(module, "is_available?", IsAvailable, 1);
215
- rb_define_module_function(module, "is_supported?", IsAvailable, 1);
216
- rb_define_module_function(module, "extension_available?", IsAvailable, 1);
217
- rb_define_module_function(module, "extension_supported?", IsAvailable, 1);
218
- rb_define_module_function(module, "version_available?", IsAvailable, 1);
219
- rb_define_module_function(module, "version_supported?", IsAvailable, 1);
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);
220
265
  }
@@ -1,18 +1,25 @@
1
1
  #include "common.h"
2
2
 
3
- static GLvoid * (APIENTRY * fptr_glMapBuffer)(GLenum,GLenum);
4
- static GLboolean (APIENTRY * fptr_glUnmapBuffer)(GLenum);
5
-
6
3
  struct buffer {
7
- GLenum target;
8
- void *ptr;
9
- GLsizeiptr len;
4
+ VALUE glimpl;
5
+ void *ptr;
6
+ GLsizeiptr len;
7
+ GLenum target;
10
8
  };
11
9
 
10
+ static void
11
+ buffer_mark(void *ptr)
12
+ {
13
+ struct buffer *this = ptr;
14
+ rb_gc_mark(this->glimpl);
15
+ }
16
+
12
17
  static void
13
18
  buffer_free(void *ptr) {
14
- struct buffer *buf = ptr;
15
- LOAD_GL_FUNC(glUnmapBuffer, "1.5");
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");
16
23
 
17
24
  if (buf->ptr != NULL)
18
25
  fptr_glUnmapBuffer(buf->target);
@@ -26,16 +33,31 @@ buffer_memsize(const void *ptr) {
26
33
 
27
34
  static const rb_data_type_t buffer_type = {
28
35
  "OpenGL/buffer",
29
- { NULL, buffer_free, buffer_memsize, },
36
+ { buffer_mark, buffer_free, buffer_memsize, },
30
37
  };
31
38
 
32
39
  VALUE
33
- rb_gl_buffer_s_map(VALUE klass, VALUE _target, VALUE _access) {
34
- struct buffer *buf = ALLOC(struct buffer);
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);
35
56
  LOAD_GL_FUNC(glMapBuffer, "1.5");
36
57
 
37
58
  buf->target = RUBY2GLENUM(_target);
38
- buf->len = 0;
59
+ buf->len = 0;
60
+ buf->glimpl = obj;
39
61
 
40
62
  buf->ptr = fptr_glMapBuffer(buf->target, RUBY2GLENUM(_access));
41
63
 
@@ -104,10 +126,14 @@ rb_gl_buffer_target(VALUE self) {
104
126
 
105
127
  static VALUE
106
128
  rb_gl_buffer_unmap(VALUE self) {
107
- struct buffer *buf;
108
- LOAD_GL_FUNC(glUnmapBuffer, "1.5");
129
+ struct buffer *buf;
130
+ VALUE obj;
131
+ DECL_GL_FUNC_PTR(GLboolean,glUnmapBuffer,(GLenum));
109
132
 
110
- TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
133
+ TypedData_Get_Struct(self, struct buffer, &buffer_type, buf);
134
+ obj = buf->glimpl;
135
+
136
+ LOAD_GL_FUNC(glUnmapBuffer, "1.5");
111
137
 
112
138
  if (!buf->ptr)
113
139
  return self;
@@ -160,12 +186,11 @@ rb_gl_buffer_write(int argc, VALUE *argv, VALUE self) {
160
186
  }
161
187
 
162
188
  void
163
- gl_init_buffer(void) {
164
- VALUE mOpenGL = rb_path2class("OpenGL");
165
- VALUE cBuffer = rb_define_class_under(mOpenGL, "Buffer", rb_cObject);
189
+ gl_init_buffer(VALUE module) {
190
+ VALUE cBuffer = rb_define_class_under(module, "Buffer", rb_cObject);
166
191
 
167
192
  rb_undef_alloc_func(cBuffer);
168
- rb_define_singleton_method(cBuffer, "map", rb_gl_buffer_s_map, 2);
193
+ rb_define_singleton_method(cBuffer, "map", rb_gl_buffer_s_map, -1);
169
194
 
170
195
  rb_define_method(cBuffer, "addr", rb_gl_buffer_addr, 0);
171
196
  rb_define_method(cBuffer, "length", rb_gl_buffer_length, 0);
@@ -0,0 +1,187 @@
1
+ #include "common.h"
2
+
3
+ #ifdef HAVE_DLFCN_H
4
+ #include <dlfcn.h>
5
+ #endif
6
+ #ifdef HAVE_WINDOWS_H
7
+ #include <windows.h>
8
+ #endif
9
+
10
+ VALUE rb_cGlimpl;
11
+
12
+ static void *gl_load_library(const char *name)
13
+ {
14
+ void *dl = NULL;
15
+
16
+ #if defined(HAVE_DLFCN_H)
17
+ dl = dlopen(name, RTLD_LAZY | RTLD_LOCAL
18
+ #if defined(RTLD_FIRST)
19
+ | RTLD_FIRST
20
+ #endif
21
+ );
22
+ if (dl == NULL)
23
+ rb_raise(rb_eLoadError,"Can't load OpenGL library %s: %s", name, dlerror());
24
+
25
+ #elif defined(HAVE_WINDOWS_H)
26
+ dl = LoadLibrary(name);
27
+ if (dl == NULL) {
28
+ char error_text[999] = "LoadLibrary() error";
29
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
30
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
31
+ (LPTSTR)&error_text, sizeof(error_text), NULL);
32
+ rb_raise(rb_eLoadError,"Can't load OpenGL library %s: %s", name, error_text);
33
+ }
34
+ #else
35
+ #error No loading mechanism available
36
+ #endif
37
+
38
+ return dl;
39
+ }
40
+
41
+ static void *gl_load_symbol(void *dl, const char *name, int raise)
42
+ {
43
+ void *fptr = NULL;
44
+
45
+ #if defined(HAVE_DLFCN_H)
46
+ fptr = dlsym(dl, name);
47
+ if (fptr == NULL && raise)
48
+ rb_raise(rb_eNotImpError,"Function %s is not available on this system: %s",name, dlerror());
49
+
50
+ #elif defined(HAVE_WINDOWS_H)
51
+ fptr = GetProcAddress(dl, name);
52
+ if (fptr == NULL && raise){
53
+ char error_text[999] = "GetProcAddress() error";
54
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
55
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
56
+ (LPTSTR)&error_text, sizeof(error_text), NULL);
57
+ rb_raise(rb_eNotImpError,"Function %s is not available on this system: %s",name, error_text);
58
+ }
59
+ #else
60
+ #error No loading mechanism available
61
+ #endif
62
+
63
+ return fptr;
64
+ }
65
+
66
+ static void gl_close_library(void *dl)
67
+ {
68
+ #if defined(HAVE_DLFCN_H)
69
+ dlclose(dl);
70
+ #elif defined(HAVE_WINDOWS_H)
71
+ FreeLibrary(dl);
72
+ #else
73
+ #error No loading mechanism available
74
+ #endif
75
+ }
76
+
77
+
78
+ static struct glimpl *
79
+ rb_glimpl_struct( VALUE self )
80
+ {
81
+ return DATA_PTR(self);
82
+ }
83
+
84
+ static void *load_gl_function(VALUE self, const char *name, int raise)
85
+ {
86
+ struct glimpl *this = rb_glimpl_struct(self);
87
+ void *func_ptr = NULL;
88
+
89
+ if(this->fptr_GetProcAddress){
90
+ func_ptr = this->fptr_GetProcAddress(name);
91
+ }
92
+
93
+ if(func_ptr == NULL){
94
+ func_ptr = gl_load_symbol(this->dl, name, 0);
95
+ }
96
+
97
+ if(func_ptr == NULL)
98
+ {
99
+ /* prepend a '_' for the Unix C symbol mangling convention */
100
+ char *symbol_name = ALLOC_N(char, strlen(name) + 2);
101
+ symbol_name[0] = '_';
102
+ strcpy(symbol_name + 1, name);
103
+ func_ptr = gl_load_symbol(this->dl, symbol_name, 0);
104
+ xfree(symbol_name);
105
+ }
106
+
107
+ if(func_ptr == NULL && raise == 1)
108
+ rb_raise(rb_eNotImpError,"Function %s is not available on this system",name);
109
+
110
+ return func_ptr;
111
+ }
112
+
113
+ static void
114
+ rb_glimpl_mark( struct glimpl *this )
115
+ {
116
+ int i;
117
+ rb_gc_mark(this->current_sel_buffer);
118
+ rb_gc_mark(this->current_feed_buffer);
119
+ rb_gc_mark(this->Vertex_ptr);
120
+ rb_gc_mark(this->Normal_ptr);
121
+ rb_gc_mark(this->Color_ptr);
122
+ rb_gc_mark(this->Index_ptr);
123
+ rb_gc_mark(this->TexCoord_ptr);
124
+ rb_gc_mark(this->EdgeFlag_ptr);
125
+ rb_gc_mark(this->FogCoord_ptr);
126
+ rb_gc_mark(this->SecondaryColor_ptr);
127
+ rb_gc_mark(this->error_checking);
128
+ rb_gc_mark(this->inside_begin_end);
129
+
130
+ for (i=0;i<_MAX_VERTEX_ATTRIBS;i++){
131
+ rb_gc_mark(this->VertexAttrib_ptr[i]);
132
+ }
133
+ }
134
+
135
+ static void rb_glimpl_free( struct glimpl *this )
136
+ {
137
+ if(this->dl) gl_close_library(this->dl);
138
+ this->dl = NULL;
139
+ xfree(this);
140
+ }
141
+
142
+ static VALUE
143
+ rb_glimpl_s_open(int argc, VALUE *argv, VALUE klass)
144
+ {
145
+ VALUE self;
146
+ struct glimpl *this;
147
+ VALUE dl_name;
148
+ VALUE proc_address_function;
149
+ char *p_dl_name;
150
+
151
+ rb_scan_args(argc, argv, "11", &dl_name, &proc_address_function);
152
+
153
+ p_dl_name = StringValueCStr(dl_name);
154
+
155
+ self = Data_Make_Struct( klass, struct glimpl, rb_glimpl_mark, rb_glimpl_free, this );
156
+
157
+ this->error_checking = Qtrue;
158
+ this->inside_begin_end = Qfalse;
159
+ this->load_gl_function = load_gl_function;
160
+ this->dl = gl_load_library(p_dl_name);
161
+
162
+ if( NIL_P(proc_address_function) ){
163
+ this->fptr_GetProcAddress = NULL;
164
+ } else {
165
+ char *p_proc_address_function = StringValueCStr(proc_address_function);
166
+ this->fptr_GetProcAddress = gl_load_symbol(this->dl, p_proc_address_function, 1);
167
+ }
168
+
169
+ return self;
170
+ }
171
+
172
+ static VALUE rb_glimpl_close(VALUE self)
173
+ {
174
+ struct glimpl *this = rb_glimpl_struct(self);
175
+ if(this->dl) gl_close_library(this->dl);
176
+ this->dl = NULL;
177
+ return Qnil;
178
+ }
179
+
180
+ void gl_init_glimpl(VALUE module)
181
+ {
182
+ rb_cGlimpl = rb_define_class_under(module, "Implementation", rb_cObject);
183
+
184
+ rb_undef_alloc_func(rb_cGlimpl);
185
+ rb_define_singleton_method(rb_cGlimpl, "open", rb_glimpl_s_open, -1);
186
+ rb_define_method(rb_cGlimpl, "close", rb_glimpl_close, 0);
187
+ }