glu 8.2.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/ext/glu/glu.c ADDED
@@ -0,0 +1,1538 @@
1
+ /*
2
+ * Last edit by previous maintainer:
3
+ * 2003/10/25 15:25:05, yoshi
4
+ *
5
+ * Copyright (C) 1999 - 2005 Yoshi <yoshi@giganet.net>
6
+ * Copyright (C) 2006 John M. Gabriele <jmg3000@gmail.com>
7
+ *
8
+ * This program is distributed under the terms of the MIT license.
9
+ * See the included COPYRIGHT file for the terms of this license.
10
+ *
11
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
15
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
16
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
+ */
19
+
20
+ #include "common.h"
21
+
22
+ static VALUE module;
23
+
24
+ VALUE Class_GLUError;
25
+
26
+ void glu_init_enums(VALUE);
27
+
28
+ typedef GLUtesselator tesselatorObj;
29
+
30
+ /* pointers passed to gluNurbsCurve/Surface etc.,
31
+ - some implementations (Mesa) needs these to be valid
32
+ at EndCurve/Surface etc. call., so we store them here
33
+ and free them after that call */
34
+
35
+ struct glu_MesaStack {
36
+ int len;
37
+ GLfloat **ptr;
38
+ };
39
+
40
+ static struct glu_MesaStack gms = {0, NULL};
41
+
42
+ struct nurbsdata {
43
+ GLUnurbsObj *nobj;
44
+ VALUE n_ref;
45
+ };
46
+ struct tessdata {
47
+ tesselatorObj *tobj;
48
+ VALUE t_ref;
49
+ };
50
+
51
+ struct quaddata {
52
+ GLUquadricObj *qobj;
53
+ VALUE q_ref;
54
+ };
55
+
56
+ static VALUE cNurbs;
57
+ static VALUE cTess;
58
+ static VALUE cQuad;
59
+
60
+ #define REF_LAST 15
61
+
62
+ #define GetNURBS(obj, ndata) {\
63
+ Data_Get_Struct(obj, struct nurbsdata, ndata);\
64
+ if (ndata->nobj == NULL) rb_raise(rb_eRuntimeError, "Nurbs Object already deleted!");\
65
+ }
66
+
67
+ #define GetTESS(obj, tdata) {\
68
+ Data_Get_Struct(obj, struct tessdata, tdata);\
69
+ if (tdata->tobj == NULL) rb_raise(rb_eRuntimeError, "Triangulator Object already deleted!");\
70
+ }
71
+
72
+ #define GetQUAD(obj, qdata) {\
73
+ Data_Get_Struct(obj, struct quaddata, qdata);\
74
+ if (qdata->qobj == NULL) rb_raise(rb_eRuntimeError, "Quadric Object already deleted!");\
75
+ }
76
+
77
+ static ID callId;
78
+ static ID refId;
79
+
80
+ /*
81
+ * GLU Implementation
82
+ */
83
+
84
+ /*
85
+ * Nurbs
86
+ */
87
+ /* from nurbscrv.c */
88
+ static int
89
+ get_curve_dim(type)
90
+ GLenum type;
91
+ {
92
+ switch(type)
93
+ {
94
+ case GL_MAP1_VERTEX_3: return 3;
95
+ case GL_MAP1_VERTEX_4: return 4;
96
+ case GL_MAP1_INDEX: return 1;
97
+ case GL_MAP1_COLOR_4: return 4;
98
+ case GL_MAP1_NORMAL: return 3;
99
+ case GL_MAP1_TEXTURE_COORD_1: return 1;
100
+ case GL_MAP1_TEXTURE_COORD_2: return 2;
101
+ case GL_MAP1_TEXTURE_COORD_3: return 3;
102
+ case GL_MAP1_TEXTURE_COORD_4: return 4;
103
+ default:
104
+ rb_raise(rb_eArgError,"Unknown curve type '%i'",type);
105
+ }
106
+ return 0; /* never gets here */
107
+ }
108
+ /* from nurbssrf.c */
109
+ static int
110
+ get_surface_dim(GLenum type)
111
+ {
112
+ switch(type)
113
+ {
114
+ case GL_MAP2_VERTEX_3: return 3;
115
+ case GL_MAP2_VERTEX_4: return 4;
116
+ case GL_MAP2_INDEX: return 1;
117
+ case GL_MAP2_COLOR_4: return 4;
118
+ case GL_MAP2_NORMAL: return 3;
119
+ case GL_MAP2_TEXTURE_COORD_1: return 1;
120
+ case GL_MAP2_TEXTURE_COORD_2: return 2;
121
+ case GL_MAP2_TEXTURE_COORD_3: return 3;
122
+ case GL_MAP2_TEXTURE_COORD_4: return 4;
123
+ default:
124
+ rb_raise(rb_eArgError,"Unknown surface type '%i'",type);
125
+ }
126
+ return 0; /* never gets here */
127
+ }
128
+
129
+ VALUE GLUError_initialize(VALUE obj,VALUE message, VALUE error_id)
130
+ {
131
+ rb_call_super(1, &message);
132
+ rb_iv_set(obj, "@id", error_id);
133
+
134
+ return obj;
135
+ }
136
+
137
+ void check_for_gluerror(GLenum error)
138
+ {
139
+ const char *error_string;
140
+ VALUE exc;
141
+
142
+ /* no error */
143
+ if (error==0)
144
+ return;
145
+
146
+ switch(error) {
147
+ case GLU_INVALID_ENUM: error_string = "invalid enumerant"; break;
148
+ case GLU_INVALID_VALUE: error_string = "invalid value"; break;
149
+ case GLU_INVALID_OPERATION: error_string = "invalid operation"; break;
150
+ case GLU_OUT_OF_MEMORY: error_string = "out of memory"; break;
151
+ default: error_string = "unknown error"; break;
152
+ }
153
+
154
+ exc = rb_funcall(Class_GLUError, rb_intern("new"), 2, rb_str_new2(error_string), UINT2NUM(error));
155
+ rb_funcall(rb_cObject, rb_intern("raise"), 1, exc);
156
+ }
157
+
158
+ /*
159
+ * NURBS API
160
+ */
161
+ static VALUE n_current;
162
+
163
+ static void
164
+ free_nurbs(ndata)
165
+ struct nurbsdata *ndata;
166
+ {
167
+ if (ndata->nobj) gluDeleteNurbsRenderer(ndata->nobj);
168
+ ndata->nobj = NULL;
169
+ ndata->n_ref = Qnil;
170
+ }
171
+ static void
172
+ mark_nurbs(ndata)
173
+ struct nurbsdata* ndata;
174
+ {
175
+ if (ndata->nobj)
176
+ rb_gc_mark(ndata->n_ref);
177
+ }
178
+
179
+ static void CALLBACK
180
+ n_error(errorno)
181
+ GLenum errorno;
182
+ {
183
+ VALUE nurbs;
184
+ struct nurbsdata *ndata;
185
+ nurbs = rb_ary_entry(n_current, -1);
186
+ if (nurbs == Qnil)
187
+ return;
188
+ GetNURBS(nurbs, ndata);
189
+ rb_funcall(rb_ary_entry(ndata->n_ref, GLU_ERROR), callId, 1, INT2NUM(errorno));
190
+ }
191
+
192
+ static VALUE
193
+ glu_NurbsCallback(obj, arg1, arg2, arg3)
194
+ VALUE obj, arg1, arg2, arg3;
195
+ {
196
+ struct nurbsdata* ndata;
197
+ GLenum type;
198
+ GetNURBS(arg1, ndata);
199
+ type = (GLenum)NUM2INT(arg2);
200
+ if (!rb_obj_is_kind_of(arg3,rb_cProc) && !NIL_P(arg3))
201
+ rb_raise(rb_eTypeError, "gluNurbsCallback needs Proc Object:%s",rb_class2name(CLASS_OF(arg3)));
202
+
203
+ if (type!=GLU_ERROR)
204
+ return Qnil;
205
+
206
+ rb_ary_store(ndata->n_ref, type, arg3);
207
+ if (NIL_P(arg3))
208
+ gluNurbsCallback(ndata->nobj, type, NULL);
209
+ else
210
+ gluNurbsCallback(ndata->nobj, type, n_error);
211
+
212
+ return Qnil;
213
+ }
214
+
215
+
216
+ static VALUE
217
+ glu_NewNurbsRenderer(obj)
218
+ VALUE obj;
219
+ {
220
+ VALUE ret;
221
+ struct nurbsdata *ndata;
222
+ ret = Data_Make_Struct(cNurbs, struct nurbsdata, mark_nurbs, free_nurbs, ndata);
223
+ ndata->nobj = gluNewNurbsRenderer();
224
+ ndata->n_ref = rb_ary_new2(REF_LAST);
225
+
226
+ return ret;
227
+ }
228
+ static VALUE
229
+ glu_DeleteNurbsRenderer(obj, arg1)
230
+ VALUE obj, arg1;
231
+ {
232
+ struct nurbsdata *ndata;
233
+ GetNURBS(arg1, ndata);
234
+ free_nurbs(ndata);
235
+
236
+ return Qnil;
237
+ }
238
+ static VALUE
239
+ glu_NurbsProperty(obj, arg1, arg2, arg3)
240
+ VALUE obj, arg1, arg2, arg3;
241
+ {
242
+ struct nurbsdata *ndata;
243
+ GLenum property;
244
+ GLfloat value;
245
+ GetNURBS(arg1, ndata);
246
+ property = (GLenum)NUM2INT(arg2);
247
+ value = (GLfloat)NUM2DBL(arg3);
248
+ gluNurbsProperty(ndata->nobj, property, value);
249
+
250
+ return Qnil;
251
+ }
252
+ static VALUE
253
+ glu_GetNurbsProperty(obj, arg1, arg2)
254
+ VALUE obj, arg1, arg2;
255
+ {
256
+ struct nurbsdata *ndata;
257
+ GLenum property;
258
+ GLfloat value;
259
+ GetNURBS(arg1, ndata);
260
+ property = (GLenum)NUM2INT(arg2);
261
+ gluGetNurbsProperty(ndata->nobj, property, &value);
262
+
263
+ return cond_GLBOOL2RUBY_F(property,value);
264
+ }
265
+ static VALUE
266
+ glu_BeginCurve(obj, arg1)
267
+ VALUE obj, arg1;
268
+ {
269
+ struct nurbsdata *ndata;
270
+ GetNURBS(arg1, ndata);
271
+ rb_ary_push(n_current, arg1);
272
+ gluBeginCurve(ndata->nobj);
273
+
274
+ return Qnil;
275
+ }
276
+ static VALUE
277
+ glu_EndCurve(obj, arg1)
278
+ VALUE obj, arg1;
279
+ {
280
+ struct nurbsdata *ndata;
281
+ GetNURBS(arg1, ndata);
282
+ gluEndCurve(ndata->nobj);
283
+
284
+ for (;gms.len>0;gms.len--)
285
+ free(gms.ptr[gms.len-1]);
286
+ free(gms.ptr);
287
+ gms.ptr = NULL;
288
+
289
+ rb_ary_pop(n_current);
290
+
291
+
292
+ return Qnil;
293
+ }
294
+ static VALUE
295
+ glu_NurbsCurve(argc,argv,obj)
296
+ int argc;
297
+ VALUE *argv;
298
+ VALUE obj;
299
+ {
300
+ struct nurbsdata *ndata;
301
+ GLint uknot_count;
302
+ GLfloat *uknot;
303
+ GLint u_stride;
304
+ GLint uorder;
305
+ GLfloat *ctlarray;
306
+ GLenum type;
307
+ GLfloat **gms_ptr;
308
+
309
+ VALUE args[7];
310
+ VALUE ary_ctl1;
311
+
312
+ switch (rb_scan_args(argc, argv, "52", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5], &args[6])) {
313
+ case 5:
314
+ uknot_count = (GLint)RARRAY_LENINT(args[1]);
315
+ uorder = (GLenum)NUM2INT(args[3]);
316
+ type = (GLenum)NUM2INT(args[4]);
317
+ u_stride = get_curve_dim(type);
318
+
319
+ uknot = ALLOC_N(GLfloat, uknot_count);
320
+ ary2cflt(args[1], uknot, uknot_count);
321
+
322
+ ary_ctl1 = rb_funcall(args[2],rb_intern("flatten"),0);
323
+ break;
324
+ case 7:
325
+ uknot_count = (GLint)NUM2INT(args[1]);
326
+ u_stride = (GLint)NUM2INT(args[3]);
327
+ uorder = (GLint)NUM2INT(args[5]);
328
+ type = (GLenum)NUM2INT(args[6]);
329
+
330
+ uknot = ALLOC_N(GLfloat, uknot_count);
331
+ ary2cflt(args[2], uknot, uknot_count);
332
+
333
+ ary_ctl1 = rb_funcall(args[4],rb_intern("flatten"),0);
334
+ break;
335
+ default:
336
+ rb_raise(rb_eArgError, "gluNurbsCurve needs 5 or 7 arguments");
337
+ }
338
+ ctlarray = ALLOC_N(GLfloat, u_stride*(uknot_count-uorder));
339
+ ary2cflt((VALUE)ary_ctl1, ctlarray, (uknot_count-uorder)*u_stride);
340
+
341
+ GetNURBS(args[0], ndata);
342
+ gluNurbsCurve(ndata->nobj, uknot_count, uknot, u_stride, ctlarray, uorder, type);
343
+
344
+ /* store the pointers */
345
+ gms_ptr = gms.ptr;
346
+ gms.ptr = REALLOC_N(gms_ptr, GLfloat*, gms.len+=2);
347
+ gms.ptr[gms.len - 2] = uknot;
348
+ gms.ptr[gms.len - 1] = ctlarray;
349
+
350
+ return Qnil;
351
+ }
352
+ static VALUE
353
+ glu_BeginSurface(obj, arg1)
354
+ VALUE obj, arg1;
355
+ {
356
+ struct nurbsdata *ndata;
357
+ GetNURBS(arg1, ndata);
358
+ rb_ary_push(n_current, arg1);
359
+ gluBeginSurface(ndata->nobj);
360
+
361
+ return Qnil;
362
+ }
363
+ static VALUE
364
+ glu_EndSurface(obj, arg1)
365
+ VALUE obj, arg1;
366
+ {
367
+ struct nurbsdata *ndata;
368
+ GetNURBS(arg1, ndata);
369
+ gluEndSurface(ndata->nobj);
370
+
371
+ for(; gms.len>0; gms.len--)
372
+ free(gms.ptr[gms.len-1]);
373
+ free(gms.ptr);
374
+ gms.ptr = NULL;
375
+
376
+ rb_ary_pop(n_current);
377
+
378
+
379
+ return Qnil;
380
+ }
381
+
382
+ static VALUE
383
+ glu_NurbsSurface(argc, argv, obj)
384
+ int argc;
385
+ VALUE *argv;
386
+ VALUE obj;
387
+ {
388
+ struct nurbsdata *ndata;
389
+ GLint sknot_count;
390
+ GLfloat *sknot;
391
+ GLint tknot_count;
392
+ GLfloat *tknot;
393
+ GLint s_stride;
394
+ GLint t_stride;
395
+ GLfloat *ctlarray;
396
+ GLint sorder;
397
+ GLint torder;
398
+ GLenum type;
399
+ GLfloat **gms_ptr;
400
+
401
+ VALUE args[11];
402
+ VALUE ary_ctl1;
403
+ int type_len;
404
+
405
+ switch (rb_scan_args(argc, argv, "74", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5], &args[6], &args[7], &args[8], &args[9], &args[10])) {
406
+ case 7:
407
+ sknot_count = (GLint)RARRAY_LENINT(args[1]);
408
+ sknot = ALLOC_N(GLfloat, sknot_count);
409
+ ary2cflt(args[1], sknot, sknot_count);
410
+
411
+ tknot_count = (GLint)RARRAY_LENINT(args[2]);
412
+ tknot = ALLOC_N(GLfloat, tknot_count);
413
+ ary2cflt(args[2], tknot, tknot_count);
414
+
415
+ sorder = (GLint)NUM2INT(args[4]);
416
+ torder = (GLint)NUM2INT(args[5]);
417
+ type = (GLenum)NUM2INT(args[6]);
418
+
419
+ t_stride = get_surface_dim(type);
420
+ s_stride = t_stride * sorder;
421
+
422
+ ctlarray = ALLOC_N(GLfloat, (sknot_count-sorder)*(tknot_count-torder)*t_stride);
423
+ ary_ctl1 = rb_funcall(args[3],rb_intern("flatten"),0);
424
+ ary2cflt(ary_ctl1, ctlarray, (sknot_count-sorder)*(tknot_count-torder)*t_stride);
425
+ break;
426
+ case 11:
427
+ sknot_count = (GLint)NUM2INT(args[1]);
428
+ sknot = ALLOC_N(GLfloat, sknot_count);
429
+ ary2cflt(args[2], sknot, sknot_count);
430
+
431
+ tknot_count = (GLint)NUM2INT(args[3]);
432
+ tknot = ALLOC_N(GLfloat, tknot_count);
433
+ ary2cflt(args[4], tknot, tknot_count);
434
+
435
+ s_stride = (GLint)NUM2INT(args[5]);
436
+ t_stride = (GLint)NUM2INT(args[6]);
437
+ sorder = (GLint)NUM2INT(args[8]);
438
+ torder = (GLint)NUM2INT(args[9]);
439
+ type = (GLint)NUM2INT(args[10]);
440
+ type_len = get_surface_dim(type);
441
+
442
+ ctlarray = ALLOC_N(GLfloat, (sknot_count-sorder)*(tknot_count-torder)*type_len);
443
+ ary_ctl1 = rb_funcall(args[7],rb_intern("flatten"),0);
444
+ ary2cflt(ary_ctl1, ctlarray, (sknot_count-sorder)*(tknot_count-torder)*type_len);
445
+ break;
446
+ default:
447
+ rb_raise(rb_eArgError, "gluNurbsSurface needs 7 or 11 arguments");
448
+ return Qnil; /* not reached */
449
+ }
450
+ GetNURBS(args[0], ndata);
451
+ gluNurbsSurface(ndata->nobj, sknot_count, sknot, tknot_count, tknot,
452
+ s_stride, t_stride, ctlarray, sorder, torder, type);
453
+
454
+ /* store the pointers */
455
+
456
+ gms_ptr = gms.ptr;
457
+ gms.ptr = REALLOC_N(gms_ptr, GLfloat*, gms.len+=3);
458
+ gms.ptr[gms.len-3] = sknot;
459
+ gms.ptr[gms.len-2] = tknot;
460
+ gms.ptr[gms.len-1] = ctlarray;
461
+
462
+
463
+ return Qnil;
464
+ }
465
+ static VALUE
466
+ glu_BeginTrim(obj, arg1)
467
+ VALUE obj, arg1;
468
+ {
469
+ struct nurbsdata *ndata;
470
+ GetNURBS(arg1, ndata);
471
+ rb_ary_push(n_current, arg1);
472
+ gluBeginTrim(ndata->nobj);
473
+
474
+ return Qnil;
475
+ }
476
+ static VALUE
477
+ glu_EndTrim(obj, arg1)
478
+ VALUE obj, arg1;
479
+ {
480
+ struct nurbsdata *ndata;
481
+ GetNURBS(arg1, ndata);
482
+ gluEndTrim(ndata->nobj);
483
+ rb_ary_pop(n_current);
484
+
485
+ return Qnil;
486
+ }
487
+ static VALUE
488
+ glu_PwlCurve(argc, argv, obj)
489
+ int argc;
490
+ VALUE *argv;
491
+ VALUE obj;
492
+ {
493
+ struct nurbsdata *ndata;
494
+ GLint count;
495
+ GLfloat *array;
496
+ GLint stride;
497
+ GLenum type;
498
+
499
+ VALUE args[5];
500
+ VALUE ary_ctl1;
501
+
502
+ switch (rb_scan_args(argc, argv, "32", &args[0], &args[1], &args[2], &args[3], &args[4])) {
503
+ case 3:
504
+ count = (GLint)RARRAY_LENINT(args[1]);
505
+ type = NUM2INT(args[2]);
506
+ stride = (type == GLU_MAP1_TRIM_2 ? 2 : 3);
507
+
508
+ array = ALLOC_N(GLfloat, count*stride);
509
+ ary_ctl1 = rb_funcall(args[1],rb_intern("flatten"),0);
510
+ ary2cflt(ary_ctl1, array, count*stride);
511
+ break;
512
+ case 5:
513
+ count = NUM2INT(args[1]);
514
+ stride = NUM2INT(args[3]);
515
+ type = NUM2INT(args[4]);
516
+
517
+ array = ALLOC_N(GLfloat, count*stride);
518
+ ary_ctl1 = rb_funcall(args[2],rb_intern("flatten"),0);
519
+ ary2cflt(ary_ctl1, array, count*stride);
520
+ break;
521
+ default:
522
+ rb_raise(rb_eArgError, "gluPwlCurve needs 3 or 5 arguments");
523
+ return Qnil; /* not reached */
524
+ }
525
+
526
+ GetNURBS(args[0], ndata);
527
+ gluPwlCurve(ndata->nobj, count, array, stride, type);
528
+ free(array);
529
+
530
+ return Qnil;
531
+ }
532
+
533
+ static VALUE glu_LoadSamplingMatrices(obj,arg1,arg2,arg3,arg4)
534
+ VALUE obj, arg1,arg2,arg3,arg4;
535
+ {
536
+ struct nurbsdata *ndata;
537
+ GLfloat mdl_mtx[4*4];
538
+ GLfloat persp_mtx[4*4];
539
+ GLint viewport[4];
540
+
541
+ GetNURBS(arg1, ndata);
542
+ ary2cmatfloat(arg2,mdl_mtx,4,4);
543
+ ary2cmatfloat(arg3,persp_mtx,4,4);
544
+ ary2cint(arg4,viewport,4);
545
+
546
+ gluLoadSamplingMatrices(ndata->nobj,mdl_mtx,persp_mtx,viewport);
547
+
548
+
549
+ return Qnil;
550
+ }
551
+
552
+ /*
553
+ * Tesselation API
554
+ */
555
+ static VALUE t_current;
556
+ #define TESS_DATA 0
557
+ #define TESS_BEGIN 1
558
+ #define TESS_VERTEX 2
559
+ #define TESS_END 3
560
+ #define TESS_ERROR 4
561
+ #define TESS_EDGE_FLAG 5
562
+ #define TESS_OUTDATA 6
563
+ #define TESS_COMBINE 7
564
+ #define TESS_BEGIN_DATA 8
565
+ #define TESS_VERTEX_DATA 9
566
+ #define TESS_END_DATA 10
567
+ #define TESS_ERROR_DATA 11
568
+ #define TESS_EDGE_FLAG_DATA 12
569
+ #define TESS_COMBINE_DATA 13
570
+ #define TESS_USERDATA 14
571
+
572
+ static void
573
+ mark_tess(tdata)
574
+ struct tessdata* tdata;
575
+ {
576
+ if (tdata->tobj)
577
+ rb_gc_mark(tdata->t_ref);
578
+ }
579
+ static void
580
+ free_tess(tdata)
581
+ struct tessdata *tdata;
582
+ {
583
+ if (tdata->tobj)
584
+ gluDeleteTess(tdata->tobj);
585
+ tdata->t_ref = Qnil;
586
+ tdata->tobj = NULL;
587
+ }
588
+ static VALUE
589
+ glu_NewTess(obj)
590
+ VALUE obj;
591
+ {
592
+ VALUE ret;
593
+ struct tessdata *tdata;
594
+ ret = Data_Make_Struct(cTess, struct tessdata, mark_tess, free_tess, tdata);
595
+ tdata->tobj = gluNewTess();
596
+ tdata->t_ref = rb_ary_new2(REF_LAST);
597
+
598
+ return ret;
599
+ }
600
+ static VALUE
601
+ glu_DeleteTess(obj, arg1)
602
+ VALUE obj, arg1;
603
+ {
604
+ struct tessdata *tdata;
605
+ GetTESS(arg1, tdata);
606
+ free_tess(tdata);
607
+
608
+ return Qnil;
609
+ }
610
+
611
+ /* tess* callback function wrappers */
612
+ #define TESS_CALLBACK_COMMON \
613
+ VALUE tess; \
614
+ struct tessdata *tdata; \
615
+ tess = rb_ary_entry(t_current, -1); \
616
+ if (tess == Qnil) \
617
+ return; \
618
+ GetTESS(tess, tdata);
619
+
620
+ static void CALLBACK
621
+ t_begin(type)
622
+ GLenum type;
623
+ {
624
+ TESS_CALLBACK_COMMON
625
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_BEGIN), callId, 1, INT2NUM(type));
626
+ }
627
+ static void CALLBACK
628
+ t_edgeFlag(flag)
629
+ GLboolean flag;
630
+ {
631
+ TESS_CALLBACK_COMMON
632
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_EDGE_FLAG), callId, 1, GLBOOL2RUBY(flag));
633
+ }
634
+ static void CALLBACK
635
+ t_vertex(data)
636
+ void* data;
637
+ {
638
+ TESS_CALLBACK_COMMON
639
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_VERTEX), callId, 1, data);
640
+ }
641
+ static void CALLBACK
642
+ t_end()
643
+ {
644
+ TESS_CALLBACK_COMMON
645
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_END), callId, 0);
646
+ }
647
+ static void CALLBACK
648
+ t_error(errorno)
649
+ GLenum errorno;
650
+ {
651
+ TESS_CALLBACK_COMMON
652
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_ERROR), callId, 1, INT2NUM(errorno));
653
+ }
654
+ static void CALLBACK
655
+ t_begin_data(type, user_data)
656
+ GLenum type;
657
+ void* user_data;
658
+ {
659
+ TESS_CALLBACK_COMMON
660
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_BEGIN_DATA), callId, 2, INT2NUM(type), user_data);
661
+ }
662
+ static void CALLBACK
663
+ t_edgeFlag_data(flag, user_data)
664
+ GLboolean flag;
665
+ void* user_data;
666
+ {
667
+ TESS_CALLBACK_COMMON
668
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_EDGE_FLAG_DATA), callId, 2, GLBOOL2RUBY(flag), user_data);
669
+ }
670
+ static void CALLBACK
671
+ t_vertex_data(data, user_data)
672
+ void* data;
673
+ void* user_data;
674
+ {
675
+ TESS_CALLBACK_COMMON
676
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_VERTEX_DATA), callId, 2, data, user_data);
677
+ }
678
+ static void CALLBACK
679
+ t_end_data(user_data)
680
+ void* user_data;
681
+ {
682
+ TESS_CALLBACK_COMMON
683
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_END_DATA), callId, 1, user_data);
684
+ }
685
+ static void CALLBACK
686
+ t_error_data(errorno, user_data)
687
+ GLenum errorno;
688
+ void* user_data;
689
+ {
690
+ TESS_CALLBACK_COMMON
691
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_ERROR_DATA), callId, 2, INT2NUM(errorno), user_data);
692
+ }
693
+
694
+ static void CALLBACK
695
+ t_combine(coords, vertex_data, weight, outData)
696
+ GLdouble coords[3];
697
+ void* vertex_data[4];
698
+ GLfloat weight[4];
699
+ void** outData;
700
+ {
701
+ VALUE rb_coord, rb_vertex_data, rb_weight;
702
+ int i;
703
+ TESS_CALLBACK_COMMON
704
+
705
+ rb_coord = rb_ary_new2(3);
706
+ for (i = 0; i < 3; i++)
707
+ rb_ary_store(rb_coord, i, rb_float_new(coords[i]));
708
+ rb_vertex_data = rb_ary_new2(4);
709
+ for (i = 0; i < 4; i++)
710
+ rb_ary_store(rb_vertex_data, i, (VALUE)vertex_data[i]);
711
+ rb_weight = rb_ary_new2(4);
712
+ for (i = 0; i < 4; i++)
713
+ rb_ary_store(rb_weight, i, rb_float_new(weight[i]));
714
+ *outData = (void*)rb_funcall(rb_ary_entry(tdata->t_ref, TESS_COMBINE), callId, 3, rb_coord, rb_vertex_data, rb_weight);
715
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_OUTDATA), (VALUE)*outData);
716
+ }
717
+
718
+ static void CALLBACK
719
+ t_combine_data(coords, vertex_data, weight, outData, user_data)
720
+ GLdouble coords[3];
721
+ void* vertex_data[4];
722
+ GLfloat weight[4];
723
+ void** outData;
724
+ void* user_data;
725
+ {
726
+ VALUE rb_coord, rb_vertex_data, rb_weight;
727
+ int i;
728
+ TESS_CALLBACK_COMMON
729
+
730
+ rb_coord = rb_ary_new2(3);
731
+ for (i = 0; i < 3; i++)
732
+ rb_ary_store(rb_coord, i, rb_float_new(coords[i]));
733
+ rb_vertex_data = rb_ary_new2(4);
734
+ for (i = 0; i < 4; i++)
735
+ rb_ary_store(rb_vertex_data, i, (VALUE)vertex_data[i]);
736
+ rb_weight = rb_ary_new2(4);
737
+ for (i = 0; i < 4; i++)
738
+ rb_ary_store(rb_weight, i, rb_float_new(weight[i]));
739
+
740
+ *outData = (void*)rb_funcall(rb_ary_entry(tdata->t_ref, TESS_COMBINE_DATA), callId, 4, rb_coord, rb_vertex_data, rb_weight, (VALUE)user_data);
741
+
742
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_OUTDATA), (VALUE)*outData);
743
+ }
744
+
745
+ #undef TESS_CALLBACK_COMMON
746
+
747
+ static VALUE
748
+ glu_TessProperty(obj, arg1, arg2, arg3)
749
+ VALUE obj, arg1, arg2, arg3;
750
+ {
751
+ struct tessdata* tdata;
752
+ GLenum property;
753
+ GLdouble value;
754
+ GetTESS(arg1, tdata);
755
+ property = (GLenum)NUM2INT(arg2);
756
+ if (property == GLU_TESS_BOUNDARY_ONLY) {
757
+ value = (GLdouble)RUBYBOOL2GL(arg3);
758
+ } else {
759
+ value = (GLdouble)NUM2DBL(arg3);
760
+ }
761
+ gluTessProperty(tdata->tobj, property, value);
762
+
763
+ return Qnil;
764
+ }
765
+ static VALUE
766
+ glu_GetTessProperty(obj, arg1, arg2)
767
+ VALUE obj, arg1, arg2;
768
+ {
769
+ struct tessdata* tdata;
770
+ GLenum property;
771
+ GLdouble value;
772
+ GetTESS(arg1, tdata);
773
+ property = (GLenum)NUM2INT(arg2);
774
+ gluGetTessProperty(tdata->tobj, property, &value);
775
+
776
+ return cond_GLBOOL2RUBY_D(property,value);
777
+ }
778
+ static VALUE
779
+ glu_TessNormal(obj, arg1, arg2, arg3, arg4)
780
+ VALUE obj, arg1, arg2, arg3, arg4;
781
+ {
782
+ struct tessdata* tdata;
783
+ GLdouble x, y, z;
784
+ GetTESS(arg1, tdata);
785
+ x = (GLdouble)NUM2DBL(arg2);
786
+ y = (GLdouble)NUM2DBL(arg3);
787
+ z = (GLdouble)NUM2DBL(arg4);
788
+ gluTessNormal(tdata->tobj, x, y, z);
789
+
790
+ return Qnil;
791
+ }
792
+ static VALUE
793
+ glu_TessBeginPolygon(obj, arg1, arg2)
794
+ VALUE obj, arg1, arg2;
795
+ {
796
+ struct tessdata* tdata;
797
+ GetTESS(arg1, tdata);
798
+ rb_ary_store(tdata->t_ref, TESS_USERDATA, arg2);
799
+ rb_ary_store(tdata->t_ref, TESS_OUTDATA, rb_ary_new());
800
+ rb_ary_store(tdata->t_ref, TESS_DATA, rb_ary_new());
801
+ rb_ary_push(t_current, arg1);
802
+ gluTessBeginPolygon(tdata->tobj, (void*)arg2);
803
+
804
+ return Qnil;
805
+ }
806
+ static VALUE
807
+ glu_TessEndPolygon(obj, arg1)
808
+ VALUE obj, arg1;
809
+ {
810
+ struct tessdata* tdata;
811
+ GetTESS(arg1, tdata);
812
+ gluTessEndPolygon(tdata->tobj);
813
+ rb_ary_store(tdata->t_ref, TESS_USERDATA, Qnil);
814
+ rb_ary_store(tdata->t_ref, TESS_OUTDATA, Qnil);
815
+ rb_ary_store(tdata->t_ref, TESS_DATA, Qnil);
816
+ rb_ary_pop(t_current);
817
+
818
+ return Qnil;
819
+ }
820
+ static VALUE
821
+ glu_TessBeginContour(obj, arg1)
822
+ VALUE obj, arg1;
823
+ {
824
+ struct tessdata* tdata;
825
+ GetTESS(arg1, tdata);
826
+ gluTessBeginContour(tdata->tobj);
827
+
828
+ return Qnil;
829
+ }
830
+ static VALUE
831
+ glu_TessEndContour(obj, arg1)
832
+ VALUE obj, arg1;
833
+ {
834
+ struct tessdata* tdata;
835
+ GetTESS(arg1, tdata);
836
+ gluTessEndContour(tdata->tobj);
837
+
838
+ return Qnil;
839
+ }
840
+
841
+ #define TESS_CALLBACK_CASE(_type_,_function_) \
842
+ case GLU_##_type_: \
843
+ rb_ary_store(tdata->t_ref, _type_, arg3); \
844
+ if (NIL_P(arg3)) \
845
+ gluTessCallback(tdata->tobj, type, NULL); \
846
+ else \
847
+ gluTessCallback(tdata->tobj, type, _function_); \
848
+ break;
849
+
850
+ static VALUE
851
+ glu_TessCallback(obj, arg1, arg2, arg3)
852
+ VALUE obj, arg1, arg2, arg3;
853
+ {
854
+ struct tessdata* tdata;
855
+ GLenum type;
856
+ GetTESS(arg1, tdata);
857
+ type = (GLenum)NUM2INT(arg2);
858
+ if (!rb_obj_is_kind_of(arg3,rb_cProc) && !NIL_P(arg3))
859
+ rb_raise(rb_eTypeError, "gluTessCallback needs Proc Object:%s",rb_class2name(CLASS_OF(arg3)));
860
+
861
+ switch (type) {
862
+ TESS_CALLBACK_CASE(TESS_BEGIN,t_begin)
863
+ TESS_CALLBACK_CASE(TESS_BEGIN_DATA,t_begin_data)
864
+ TESS_CALLBACK_CASE(TESS_EDGE_FLAG,t_edgeFlag)
865
+ TESS_CALLBACK_CASE(TESS_EDGE_FLAG_DATA,t_edgeFlag_data)
866
+ TESS_CALLBACK_CASE(TESS_VERTEX,t_vertex)
867
+ TESS_CALLBACK_CASE(TESS_VERTEX_DATA,t_vertex_data)
868
+ TESS_CALLBACK_CASE(TESS_END,t_end)
869
+ TESS_CALLBACK_CASE(TESS_END_DATA,t_end_data)
870
+ TESS_CALLBACK_CASE(TESS_ERROR,t_error)
871
+ TESS_CALLBACK_CASE(TESS_ERROR_DATA,t_error_data)
872
+ TESS_CALLBACK_CASE(TESS_COMBINE,t_combine)
873
+ TESS_CALLBACK_CASE(TESS_COMBINE_DATA,t_combine_data)
874
+ }
875
+
876
+ return Qnil;
877
+ }
878
+ #undef TESS_CALLBACK_CASE
879
+
880
+ static VALUE
881
+ glu_BeginPolygon(obj, arg1)
882
+ VALUE obj, arg1;
883
+ {
884
+ struct tessdata* tdata;
885
+ GetTESS(arg1, tdata);
886
+ rb_ary_store(tdata->t_ref, TESS_DATA, rb_ary_new());
887
+ rb_ary_push(t_current, arg1);
888
+ gluBeginPolygon(tdata->tobj);
889
+
890
+ return Qnil;
891
+ }
892
+ static VALUE
893
+ glu_TessVertex(obj, arg1, arg2, arg3)
894
+ VALUE obj, arg1, arg2, arg3;
895
+ {
896
+ struct tessdata* tdata;
897
+ GLdouble v[3] = {0.0,0.0,0.0};
898
+ GetTESS(arg1, tdata);
899
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_DATA), arg3);
900
+ Check_Type(arg2,T_ARRAY);
901
+ ary2cdbl(arg2, v, 3);
902
+ gluTessVertex(tdata->tobj, v,(void *)arg3);
903
+
904
+ return Qnil;
905
+ }
906
+ static VALUE
907
+ glu_NextContour(obj, arg1, arg2)
908
+ VALUE obj, arg1, arg2;
909
+ {
910
+ struct tessdata* tdata;
911
+ GLenum type;
912
+ GetTESS(arg1, tdata);
913
+ type = (GLenum)NUM2INT(arg2);
914
+ gluNextContour(tdata->tobj, type);
915
+
916
+ return Qnil;
917
+ }
918
+ static VALUE
919
+ glu_EndPolygon(obj, arg1)
920
+ VALUE obj, arg1;
921
+ {
922
+ struct tessdata* tdata;
923
+ GetTESS(arg1, tdata);
924
+ gluEndPolygon(tdata->tobj);
925
+ rb_ary_store(tdata->t_ref, TESS_DATA, Qnil);
926
+ rb_ary_pop(t_current);
927
+
928
+ return Qnil;
929
+ }
930
+
931
+ /*
932
+ * Quadric API
933
+ */
934
+ static VALUE q_current;
935
+
936
+ static void CALLBACK
937
+ q_error(errorno)
938
+ GLenum errorno;
939
+ {
940
+ VALUE quad;
941
+ struct quaddata *qdata;
942
+ quad = rb_ary_entry(q_current, -1);
943
+ if (quad == Qnil)
944
+ return;
945
+ GetQUAD(quad, qdata);
946
+ rb_funcall(rb_ary_entry(qdata->q_ref, GLU_ERROR), callId, 1, INT2NUM(errorno));
947
+ }
948
+
949
+ static VALUE
950
+ glu_QuadricCallback(obj, arg1, arg2, arg3)
951
+ VALUE obj, arg1, arg2, arg3;
952
+ {
953
+ struct quaddata* qdata;
954
+ GLenum type;
955
+ GetQUAD(arg1, qdata);
956
+ type = (GLenum)NUM2INT(arg2);
957
+ if (!rb_obj_is_kind_of(arg3,rb_cProc) && !NIL_P(arg3))
958
+ rb_raise(rb_eTypeError, "gluQuadricCallback needs Proc Object:%s",rb_class2name(CLASS_OF(arg3)));
959
+
960
+
961
+ if (type!=GLU_ERROR)
962
+ return Qnil;
963
+
964
+ rb_ary_store(qdata->q_ref, type, arg3);
965
+ if (NIL_P(arg3))
966
+ gluQuadricCallback(qdata->qobj, type, NULL);
967
+ else
968
+ gluQuadricCallback(qdata->qobj, type, q_error);
969
+
970
+
971
+ return Qnil;
972
+ }
973
+
974
+ static void
975
+ free_quad(qdata)
976
+ struct quaddata *qdata;
977
+ {
978
+ if (qdata->qobj) gluDeleteQuadric(qdata->qobj);
979
+ qdata->qobj = NULL;
980
+ qdata->q_ref = Qnil;
981
+ }
982
+ static void
983
+ mark_quad(qdata)
984
+ struct quaddata* qdata;
985
+ {
986
+ if (qdata->qobj)
987
+ rb_gc_mark(qdata->q_ref);
988
+ }
989
+ static VALUE
990
+ glu_NewQuadric(obj)
991
+ VALUE obj;
992
+ {
993
+ VALUE ret;
994
+ struct quaddata *qdata;
995
+ ret = Data_Make_Struct(cQuad, struct quaddata, mark_quad, free_quad, qdata);
996
+ qdata->qobj = gluNewQuadric();
997
+ qdata->q_ref = rb_ary_new2(REF_LAST);
998
+
999
+ return ret;
1000
+ }
1001
+ static VALUE
1002
+ glu_DeleteQuadric(obj, arg1)
1003
+ VALUE obj, arg1;
1004
+ {
1005
+ struct quaddata *qdata;
1006
+ GetQUAD(arg1, qdata);
1007
+ free_quad(qdata);
1008
+
1009
+ return Qnil;
1010
+ }
1011
+ static VALUE
1012
+ glu_QuadricNormals(obj, arg1, arg2)
1013
+ VALUE obj, arg1, arg2;
1014
+ {
1015
+ struct quaddata* qdata;
1016
+ GLenum normals;
1017
+ GetQUAD(arg1, qdata);
1018
+ normals = (GLenum)NUM2INT(arg2);
1019
+ gluQuadricNormals(qdata->qobj, normals);
1020
+
1021
+ return Qnil;
1022
+ }
1023
+ static VALUE
1024
+ glu_QuadricTexture(obj, arg1, arg2)
1025
+ VALUE obj, arg1, arg2;
1026
+ {
1027
+ struct quaddata* qdata;
1028
+ GLboolean textureCoords;
1029
+ GetQUAD(arg1, qdata);
1030
+ textureCoords = (GLboolean)RUBYBOOL2GL(arg2);
1031
+ gluQuadricTexture(qdata->qobj, textureCoords);
1032
+
1033
+ return Qnil;
1034
+ }
1035
+ static VALUE
1036
+ glu_QuadricOrientation(obj, arg1, arg2)
1037
+ VALUE obj, arg1, arg2;
1038
+ {
1039
+ struct quaddata* qdata;
1040
+ GLenum orientation;
1041
+ GetQUAD(arg1, qdata);
1042
+ orientation = (GLenum)NUM2INT(arg2);
1043
+ gluQuadricOrientation(qdata->qobj, orientation);
1044
+
1045
+ return Qnil;
1046
+ }
1047
+ static VALUE
1048
+ glu_QuadricDrawStyle(obj, arg1, arg2)
1049
+ VALUE obj, arg1, arg2;
1050
+ {
1051
+ struct quaddata* qdata;
1052
+ GLenum drawStyle;
1053
+ GetQUAD(arg1, qdata);
1054
+ drawStyle = (GLenum)NUM2INT(arg2);
1055
+ gluQuadricDrawStyle(qdata->qobj, drawStyle);
1056
+
1057
+ return Qnil;
1058
+ }
1059
+ static VALUE
1060
+ glu_Cylinder(obj, arg1, arg2, arg3, arg4, arg5, arg6)
1061
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6;
1062
+ {
1063
+ struct quaddata* qdata;
1064
+ GLdouble baseRadius;
1065
+ GLdouble topRadius;
1066
+ GLdouble height;
1067
+ GLint slices;
1068
+ GLint stacks;
1069
+
1070
+ GetQUAD(arg1, qdata);
1071
+ baseRadius = (GLdouble)NUM2DBL(arg2);
1072
+ topRadius = (GLdouble)NUM2DBL(arg3);
1073
+ height = (GLdouble)NUM2DBL(arg4);
1074
+ slices = (GLint)NUM2INT(arg5);
1075
+ stacks = (GLint)NUM2INT(arg6);
1076
+
1077
+ rb_ary_push(q_current, arg1);
1078
+ gluCylinder(qdata->qobj, baseRadius, topRadius, height, slices, stacks);
1079
+ rb_ary_pop(q_current);
1080
+
1081
+ return Qnil;
1082
+ }
1083
+ static VALUE
1084
+ glu_Disk(obj, arg1, arg2, arg3, arg4, arg5)
1085
+ VALUE obj, arg1, arg2, arg3, arg4, arg5;
1086
+ {
1087
+ struct quaddata* qdata;
1088
+ GLdouble innerRadius;
1089
+ GLdouble outerRadius;
1090
+ GLint slices;
1091
+ GLint loops;
1092
+
1093
+ GetQUAD(arg1, qdata);
1094
+ innerRadius = (GLdouble)NUM2DBL(arg2);
1095
+ outerRadius = (GLdouble)NUM2DBL(arg3);
1096
+ slices = (GLint)NUM2INT(arg4);
1097
+ loops = (GLint)NUM2INT(arg5);
1098
+
1099
+ rb_ary_push(q_current, arg1);
1100
+
1101
+ gluDisk(qdata->qobj, innerRadius, outerRadius, slices, loops);
1102
+ rb_ary_pop(q_current);
1103
+
1104
+ return Qnil;
1105
+ }
1106
+ static VALUE
1107
+ glu_PartialDisk(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
1108
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
1109
+ {
1110
+ struct quaddata* qdata;
1111
+ GLdouble innerRadius;
1112
+ GLdouble outerRadius;
1113
+ GLint slices;
1114
+ GLint loops;
1115
+ GLdouble startAngle;
1116
+ GLdouble sweepAngle;
1117
+
1118
+ GetQUAD(arg1, qdata);
1119
+ innerRadius = (GLdouble)NUM2DBL(arg2);
1120
+ outerRadius = (GLdouble)NUM2DBL(arg3);
1121
+ slices = (GLint)NUM2INT(arg4);
1122
+ loops = (GLint)NUM2INT(arg5);
1123
+ startAngle = (GLdouble)NUM2DBL(arg6);
1124
+ sweepAngle = (GLdouble)NUM2DBL(arg7);
1125
+
1126
+ rb_ary_push(q_current, arg1);
1127
+ gluPartialDisk(qdata->qobj, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle);
1128
+ rb_ary_pop(q_current);
1129
+
1130
+ return Qnil;
1131
+ }
1132
+ static VALUE
1133
+ glu_Sphere(obj, arg1, arg2, arg3, arg4)
1134
+ VALUE obj, arg1, arg2, arg3, arg4;
1135
+ {
1136
+ struct quaddata* qdata;
1137
+ GLdouble radius;
1138
+ GLint slices;
1139
+ GLint stacks;
1140
+
1141
+ GetQUAD(arg1, qdata);
1142
+ radius = (GLdouble)NUM2DBL(arg2);
1143
+ slices = (GLint)NUM2INT(arg3);
1144
+ stacks = (GLint)NUM2INT(arg4);
1145
+
1146
+ rb_ary_push(q_current, arg1);
1147
+ gluSphere(qdata->qobj, radius, slices, stacks);
1148
+ rb_ary_pop(q_current);
1149
+
1150
+ return Qnil;
1151
+ }
1152
+
1153
+ /* */
1154
+
1155
+ static VALUE
1156
+ glu_LookAt(obj,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)
1157
+ VALUE obj,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9;
1158
+ {
1159
+ GLdouble eyex;
1160
+ GLdouble eyey;
1161
+ GLdouble eyez;
1162
+ GLdouble centerx;
1163
+ GLdouble centery;
1164
+ GLdouble centerz;
1165
+ GLdouble upx;
1166
+ GLdouble upy;
1167
+ GLdouble upz;
1168
+ eyex = (GLdouble)NUM2DBL(arg1);
1169
+ eyey = (GLdouble)NUM2DBL(arg2);
1170
+ eyez = (GLdouble)NUM2DBL(arg3);
1171
+ centerx = (GLdouble)NUM2DBL(arg4);
1172
+ centery = (GLdouble)NUM2DBL(arg5);
1173
+ centerz = (GLdouble)NUM2DBL(arg6);
1174
+ upx = (GLdouble)NUM2DBL(arg7);
1175
+ upy = (GLdouble)NUM2DBL(arg8);
1176
+ upz = (GLdouble)NUM2DBL(arg9);
1177
+ gluLookAt( eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz );
1178
+
1179
+ return Qnil;
1180
+ }
1181
+ static VALUE
1182
+ glu_Ortho2D(obj,arg1,arg2,arg3,arg4)
1183
+ VALUE obj,arg1,arg2,arg3,arg4;
1184
+ {
1185
+ GLdouble left;
1186
+ GLdouble right;
1187
+ GLdouble bottom;
1188
+ GLdouble top;
1189
+ left = (GLdouble)NUM2DBL(arg1);
1190
+ right = (GLdouble)NUM2DBL(arg2);
1191
+ bottom = (GLdouble)NUM2DBL(arg3);
1192
+ top = (GLdouble)NUM2DBL(arg4);
1193
+ gluOrtho2D(left,right,bottom,top);
1194
+
1195
+ return Qnil;
1196
+ }
1197
+ static VALUE
1198
+ glu_Perspective(obj,arg1,arg2,arg3,arg4)
1199
+ VALUE obj,arg1,arg2,arg3,arg4;
1200
+ {
1201
+ GLdouble fovy;
1202
+ GLdouble aspect;
1203
+ GLdouble zNear;
1204
+ GLdouble zFar;
1205
+ fovy = (GLdouble)NUM2DBL(arg1);
1206
+ aspect = (GLdouble)NUM2DBL(arg2);
1207
+ zNear = (GLdouble)NUM2DBL(arg3);
1208
+ zFar = (GLdouble)NUM2DBL(arg4);
1209
+ gluPerspective(fovy,aspect,zNear,zFar);
1210
+
1211
+ return Qnil;
1212
+ }
1213
+ static VALUE
1214
+ glu_PickMatrix(argc,argv,obj)
1215
+ int argc;
1216
+ VALUE* argv;
1217
+ VALUE obj;
1218
+ {
1219
+ GLdouble x;
1220
+ GLdouble y;
1221
+ GLdouble width;
1222
+ GLdouble height;
1223
+ GLint viewport[4];
1224
+
1225
+ VALUE args[5];
1226
+
1227
+ switch (rb_scan_args(argc, argv, "23", &args[0], &args[1], &args[2], &args[3], &args[4])) {
1228
+ case 2:
1229
+ width = 5.0f;
1230
+ height = 5.0f;
1231
+ glGetIntegerv(GL_VIEWPORT, viewport);
1232
+ break;
1233
+ case 4:
1234
+ width = (GLdouble)NUM2DBL(args[2]);
1235
+ height = (GLdouble)NUM2DBL(args[3]);
1236
+ glGetIntegerv(GL_VIEWPORT, viewport);
1237
+ break;
1238
+ case 5:
1239
+ width = (GLdouble)NUM2DBL(args[2]);
1240
+ height = (GLdouble)NUM2DBL(args[3]);
1241
+ ary2cint(args[4], viewport, 4);
1242
+ break;
1243
+ default:
1244
+ rb_raise(rb_eArgError, "gluPickMatrix needs 2,4 or 5 parameters");
1245
+ }
1246
+ x = (GLdouble)NUM2DBL(args[0]);
1247
+ y = (GLdouble)NUM2DBL(args[1]);
1248
+ gluPickMatrix(x, y, width, height, viewport);
1249
+
1250
+ return Qnil;
1251
+ }
1252
+
1253
+ static VALUE
1254
+ glu_Project(argc,argv,obj)
1255
+ int argc;
1256
+ VALUE* argv;
1257
+ VALUE obj;
1258
+ {
1259
+ GLdouble ox;
1260
+ GLdouble oy;
1261
+ GLdouble oz;
1262
+ GLdouble mdl_mtx[4*4];
1263
+ GLdouble prj_mtx[4*4];
1264
+ GLint vport[4];
1265
+ GLdouble wx;
1266
+ GLdouble wy;
1267
+ GLdouble wz;
1268
+
1269
+ VALUE args[6];
1270
+
1271
+ switch (rb_scan_args(argc, argv, "33", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5])) {
1272
+ case 3:
1273
+ glGetDoublev(GL_MODELVIEW_MATRIX, mdl_mtx);
1274
+ glGetDoublev(GL_PROJECTION_MATRIX, prj_mtx);
1275
+ glGetIntegerv(GL_VIEWPORT, vport);
1276
+ break;
1277
+ case 6:
1278
+ ary2cmatdouble(args[3], mdl_mtx, 4, 4);
1279
+ ary2cmatdouble(args[4], prj_mtx, 4, 4);
1280
+ ary2cint(args[5], vport, 4);
1281
+ break;
1282
+ default:
1283
+ rb_raise(rb_eArgError, "gluProject needs 3 or 6 parameters");
1284
+ }
1285
+ ox = (GLdouble)NUM2DBL(args[0]);
1286
+ oy = (GLdouble)NUM2DBL(args[1]);
1287
+ oz = (GLdouble)NUM2DBL(args[2]);
1288
+
1289
+ if (gluProject(ox, oy, oz, mdl_mtx, prj_mtx, vport, &wx, &wy, &wz) == GL_TRUE) {
1290
+
1291
+ return rb_ary_new3(3, rb_float_new(wx), rb_float_new(wy), rb_float_new(wz));
1292
+ } else {
1293
+
1294
+ check_for_gluerror(GLU_INVALID_VALUE);
1295
+ return Qnil; /* not reached */
1296
+ }
1297
+ }
1298
+ static VALUE
1299
+ glu_UnProject(argc,argv,obj)
1300
+ int argc;
1301
+ VALUE* argv;
1302
+ VALUE obj;
1303
+ {
1304
+ GLdouble wx;
1305
+ GLdouble wy;
1306
+ GLdouble wz;
1307
+ GLdouble mdl_mtx[4*4];
1308
+ GLdouble prj_mtx[4*4];
1309
+ GLint vport[4];
1310
+ GLdouble ox;
1311
+ GLdouble oy;
1312
+ GLdouble oz;
1313
+
1314
+ VALUE args[6];
1315
+
1316
+ switch (rb_scan_args(argc, argv, "33", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5])) {
1317
+ case 3:
1318
+ glGetDoublev(GL_MODELVIEW_MATRIX, mdl_mtx);
1319
+ glGetDoublev(GL_PROJECTION_MATRIX, prj_mtx);
1320
+ glGetIntegerv(GL_VIEWPORT, vport);
1321
+ break;
1322
+ case 6:
1323
+ ary2cmatdouble(args[3], mdl_mtx, 4, 4);
1324
+ ary2cmatdouble(args[4], prj_mtx, 4, 4);
1325
+ ary2cint(args[5], vport, 4);
1326
+ break;
1327
+ default:
1328
+ rb_raise(rb_eArgError, "gluUnProject needs 3 or 6 parameters");
1329
+ }
1330
+ wx = (GLdouble)NUM2DBL(args[0]);
1331
+ wy = (GLdouble)NUM2DBL(args[1]);
1332
+ wz = (GLdouble)NUM2DBL(args[2]);
1333
+
1334
+ if (gluUnProject(wx, wy, wz, mdl_mtx, prj_mtx, vport, &ox, &oy, &oz) == GL_TRUE) {
1335
+
1336
+ return rb_ary_new3(3, rb_float_new(ox), rb_float_new(oy), rb_float_new(oz));
1337
+ } else {
1338
+
1339
+ check_for_gluerror(GLU_INVALID_VALUE);
1340
+ return Qnil; /* not reached */
1341
+ }
1342
+ }
1343
+
1344
+ static VALUE
1345
+ glu_Build1DMipmaps(obj, arg1, arg2, arg3, arg4, arg5, arg6)
1346
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6;
1347
+ {
1348
+ GLenum target;
1349
+ GLint components;
1350
+ GLint width;
1351
+ GLenum format;
1352
+ GLenum type;
1353
+ int ret;
1354
+
1355
+ target = (GLenum)NUM2INT(arg1);
1356
+ components = (GLint)NUM2INT(arg2);
1357
+ width = (GLint)NUM2INT(arg3);
1358
+ format = (GLenum)NUM2INT(arg4);
1359
+ type = (GLenum)NUM2INT(arg5);
1360
+ Check_Type(arg6,T_STRING);
1361
+ CheckDataSize(type,format,width,arg6);
1362
+
1363
+ ret = gluBuild1DMipmaps(target, components, width, format, type, RSTRING_PTR(arg6));
1364
+ check_for_gluerror(ret);
1365
+
1366
+ return INT2NUM(ret);
1367
+ }
1368
+
1369
+ static VALUE
1370
+ glu_Build2DMipmaps(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
1371
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
1372
+ {
1373
+ GLenum target;
1374
+ GLint components;
1375
+ GLint width;
1376
+ GLint height;
1377
+ GLenum format;
1378
+ GLenum type;
1379
+ int ret;
1380
+
1381
+ target = (GLenum)NUM2INT(arg1);
1382
+ components = (GLint)NUM2INT(arg2);
1383
+ width = (GLint)NUM2INT(arg3);
1384
+ height = (GLint)NUM2INT(arg4);
1385
+ format = (GLenum)NUM2INT(arg5);
1386
+ type = (GLenum)NUM2INT(arg6);
1387
+ Check_Type(arg7,T_STRING);
1388
+ CheckDataSize(type,format,width*height,arg7);
1389
+
1390
+ ret = gluBuild2DMipmaps(target, components, width, height, format, type, RSTRING_PTR(arg7));
1391
+ check_for_gluerror(ret);
1392
+
1393
+ return INT2NUM(ret);
1394
+ }
1395
+
1396
+ static VALUE
1397
+ glu_ScaleImage(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
1398
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
1399
+ {
1400
+ GLenum format;
1401
+ GLint widthin;
1402
+ GLint heightin;
1403
+ GLenum typein;
1404
+ void* datain;
1405
+ GLint widthout;
1406
+ GLint heightout;
1407
+ GLenum typeout;
1408
+ VALUE ret;
1409
+ GLint retcode;
1410
+
1411
+ format = (GLenum)NUM2INT(arg1);
1412
+ widthin = (GLint)NUM2INT(arg2);
1413
+ heightin = (GLint)NUM2INT(arg3);
1414
+ typein = (GLenum)NUM2INT(arg4);
1415
+ Check_Type(arg5,T_STRING);
1416
+ CheckDataSize(typein,format,heightin*widthin,arg5);
1417
+ datain = RSTRING_PTR(arg5);
1418
+ widthout = (GLint)NUM2INT(arg6);
1419
+ heightout = (GLint)NUM2INT(arg7);
1420
+ typeout = (GLenum)NUM2INT(arg8);
1421
+ ret = allocate_buffer_with_string(GetDataSize(typeout,format,widthout*heightout));
1422
+ retcode = gluScaleImage(format, widthin, heightin, typein, datain,
1423
+ widthout, heightout, typeout, (GLvoid*)RSTRING_PTR(ret));
1424
+
1425
+ check_for_gluerror(retcode);
1426
+
1427
+ return ret;
1428
+ }
1429
+
1430
+ static VALUE
1431
+ glu_ErrorString(obj, arg1)
1432
+ VALUE obj, arg1;
1433
+ {
1434
+ GLenum errorCode;
1435
+ GLubyte* error;
1436
+ errorCode = (GLenum)NUM2INT(arg1);
1437
+ error = (GLubyte*)gluErrorString(errorCode);
1438
+
1439
+ if (error)
1440
+ return rb_str_new2((char *)error);
1441
+ else
1442
+ return Qnil;
1443
+ }
1444
+ static VALUE
1445
+ glu_GetString(obj, arg1)
1446
+ VALUE obj, arg1;
1447
+ {
1448
+ GLenum name;
1449
+ GLubyte* str;
1450
+ name = (GLenum)NUM2INT(arg1);
1451
+ str = (GLubyte*)gluGetString(name);
1452
+
1453
+ if (str)
1454
+ return rb_str_new2((char *)str);
1455
+ else
1456
+ return Qnil;
1457
+ }
1458
+
1459
+ static VALUE module;
1460
+
1461
+ DLLEXPORT void Init_glu()
1462
+ {
1463
+ callId = rb_intern("call");
1464
+ refId = rb_intern("[]");
1465
+ module = rb_define_module("Glu");
1466
+
1467
+ glu_init_enums(module);
1468
+
1469
+ rb_define_module_function(module, "gluNewNurbsRenderer", glu_NewNurbsRenderer, 0);
1470
+ rb_define_module_function(module, "gluDeleteNurbsRenderer", glu_DeleteNurbsRenderer, 1);
1471
+ rb_define_module_function(module, "gluNurbsProperty", glu_NurbsProperty, 3);
1472
+ rb_define_module_function(module, "gluGetNurbsProperty", glu_GetNurbsProperty, 2);
1473
+ rb_define_module_function(module, "gluBeginCurve", glu_BeginCurve, 1);
1474
+ rb_define_module_function(module, "gluEndCurve", glu_EndCurve, 1);
1475
+ rb_define_module_function(module, "gluNurbsCurve", glu_NurbsCurve, -1);
1476
+ rb_define_module_function(module, "gluBeginSurface", glu_BeginSurface, 1);
1477
+ rb_define_module_function(module, "gluEndSurface", glu_EndSurface, 1);
1478
+ rb_define_module_function(module, "gluNurbsSurface", glu_NurbsSurface, -1);
1479
+ rb_define_module_function(module, "gluBeginTrim", glu_BeginTrim, 1);
1480
+ rb_define_module_function(module, "gluEndTrim", glu_EndTrim, 1);
1481
+ rb_define_module_function(module, "gluPwlCurve", glu_PwlCurve, -1);
1482
+ rb_define_module_function(module, "gluNewTess", glu_NewTess, 0);
1483
+ rb_define_module_function(module, "gluDeleteTess", glu_DeleteTess, 1);
1484
+ rb_define_module_function(module, "gluTessCallback", glu_TessCallback, 3);
1485
+ rb_define_module_function(module, "gluBeginPolygon", glu_BeginPolygon, 1);
1486
+ rb_define_module_function(module, "gluTessVertex", glu_TessVertex, 3);
1487
+ rb_define_module_function(module, "gluNextContour", glu_NextContour, 2);
1488
+ rb_define_module_function(module, "gluEndPolygon", glu_EndPolygon, 1);
1489
+ rb_define_module_function(module, "gluTessBeginPolygon", glu_TessBeginPolygon, 2);
1490
+ rb_define_module_function(module, "gluTessBeginContour", glu_TessBeginContour, 1);
1491
+ rb_define_module_function(module, "gluTessEndContour", glu_TessEndContour, 1);
1492
+ rb_define_module_function(module, "gluTessEndPolygon", glu_TessEndPolygon, 1);
1493
+ rb_define_module_function(module, "gluTessProperty", glu_TessProperty, 3);
1494
+ rb_define_module_function(module, "gluTessNormal", glu_TessNormal, 4);
1495
+ rb_define_module_function(module, "gluGetTessProperty", glu_GetTessProperty, 2);
1496
+ rb_define_module_function(module, "gluNewQuadric", glu_NewQuadric, 0);
1497
+ rb_define_module_function(module, "gluDeleteQuadric", glu_DeleteQuadric, 1);
1498
+ rb_define_module_function(module, "gluQuadricNormals", glu_QuadricNormals, 2);
1499
+ rb_define_module_function(module, "gluQuadricTexture", glu_QuadricTexture, 2);
1500
+ rb_define_module_function(module, "gluQuadricOrientation", glu_QuadricOrientation, 2);
1501
+ rb_define_module_function(module, "gluQuadricDrawStyle", glu_QuadricDrawStyle, 2);
1502
+ rb_define_module_function(module, "gluCylinder", glu_Cylinder, 6);
1503
+ rb_define_module_function(module, "gluDisk", glu_Disk, 5);
1504
+ rb_define_module_function(module, "gluPartialDisk", glu_PartialDisk, 7);
1505
+ rb_define_module_function(module, "gluSphere", glu_Sphere, 4);
1506
+
1507
+ rb_define_module_function(module, "gluLookAt", glu_LookAt, 9);
1508
+ rb_define_module_function(module, "gluOrtho2D", glu_Ortho2D, 4);
1509
+ rb_define_module_function(module, "gluPerspective", glu_Perspective, 4);
1510
+ rb_define_module_function(module, "gluPickMatrix", glu_PickMatrix, -1);
1511
+ rb_define_module_function(module, "gluProject", glu_Project, -1);
1512
+ rb_define_module_function(module, "gluUnProject", glu_UnProject, -1);
1513
+ rb_define_module_function(module, "gluBuild1DMipmaps", glu_Build1DMipmaps, 6);
1514
+ rb_define_module_function(module, "gluBuild2DMipmaps", glu_Build2DMipmaps, 7);
1515
+ rb_define_module_function(module, "gluScaleImage", glu_ScaleImage, 8);
1516
+ rb_define_module_function(module, "gluErrorString", glu_ErrorString, 1);
1517
+ rb_define_module_function(module, "gluGetString", glu_GetString, 1);
1518
+
1519
+ rb_define_module_function(module, "gluLoadSamplingMatrices",glu_LoadSamplingMatrices,4);
1520
+ rb_define_module_function(module, "gluQuadricCallback", glu_QuadricCallback, 3);
1521
+ rb_define_module_function(module, "gluNurbsCallback", glu_NurbsCallback, 3);
1522
+
1523
+ Class_GLUError = rb_define_class_under(module, "Error", rb_eStandardError);
1524
+
1525
+ rb_define_method(Class_GLUError, "initialize", GLUError_initialize, 2);
1526
+ rb_define_attr(Class_GLUError, "id", 1, 0);
1527
+
1528
+ cNurbs = rb_define_class("Nurbs", rb_cObject);
1529
+ cTess = rb_define_class("Tess", rb_cObject);
1530
+ cQuad = rb_define_class("Quadric", rb_cObject);
1531
+
1532
+ rb_global_variable(&t_current); /* current active tesselator, nurbs and quadric, used for callbacks */
1533
+ t_current = rb_ary_new();
1534
+ rb_global_variable(&n_current);
1535
+ n_current = rb_ary_new();
1536
+ rb_global_variable(&q_current);
1537
+ q_current = rb_ary_new();
1538
+ }