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

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