glu 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1534 @@
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), RETCONV_GLenum(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
+
308
+ VALUE args[7];
309
+ VALUE ary_ctl1;
310
+
311
+ switch (rb_scan_args(argc, argv, "52", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5], &args[6])) {
312
+ case 5:
313
+ uknot_count = (GLint)RARRAY_LENINT(args[1]);
314
+ uorder = (GLenum)NUM2INT(args[3]);
315
+ type = (GLenum)NUM2INT(args[4]);
316
+ u_stride = get_curve_dim(type);
317
+
318
+ uknot = ALLOC_N(GLfloat, uknot_count);
319
+ ary2cflt(args[1], uknot, uknot_count);
320
+
321
+ ary_ctl1 = rb_funcall(args[2],rb_intern("flatten"),0);
322
+ break;
323
+ case 7:
324
+ uknot_count = (GLint)NUM2INT(args[1]);
325
+ u_stride = (GLint)NUM2INT(args[3]);
326
+ uorder = (GLint)NUM2INT(args[5]);
327
+ type = (GLenum)NUM2INT(args[6]);
328
+
329
+ uknot = ALLOC_N(GLfloat, uknot_count);
330
+ ary2cflt(args[2], uknot, uknot_count);
331
+
332
+ ary_ctl1 = rb_funcall(args[4],rb_intern("flatten"),0);
333
+ break;
334
+ default:
335
+ rb_raise(rb_eArgError, "gluNurbsCurve needs 5 or 7 arguments");
336
+ }
337
+ ctlarray = ALLOC_N(GLfloat, u_stride*(uknot_count-uorder));
338
+ ary2cflt((VALUE)ary_ctl1, ctlarray, (uknot_count-uorder)*u_stride);
339
+
340
+ GetNURBS(args[0], ndata);
341
+ gluNurbsCurve(ndata->nobj, uknot_count, uknot, u_stride, ctlarray, uorder, type);
342
+
343
+ /* store the pointers */
344
+ gms.ptr = REALLOC_N(gms.ptr, GLfloat*, gms.len+=2);
345
+ gms.ptr[gms.len - 2] = uknot;
346
+ gms.ptr[gms.len - 1] = ctlarray;
347
+
348
+ return Qnil;
349
+ }
350
+ static VALUE
351
+ glu_BeginSurface(obj, arg1)
352
+ VALUE obj, arg1;
353
+ {
354
+ struct nurbsdata *ndata;
355
+ GetNURBS(arg1, ndata);
356
+ rb_ary_push(n_current, arg1);
357
+ gluBeginSurface(ndata->nobj);
358
+
359
+ return Qnil;
360
+ }
361
+ static VALUE
362
+ glu_EndSurface(obj, arg1)
363
+ VALUE obj, arg1;
364
+ {
365
+ struct nurbsdata *ndata;
366
+ GetNURBS(arg1, ndata);
367
+ gluEndSurface(ndata->nobj);
368
+
369
+ for(; gms.len>0; gms.len--)
370
+ free(gms.ptr[gms.len-1]);
371
+ free(gms.ptr);
372
+ gms.ptr = NULL;
373
+
374
+ rb_ary_pop(n_current);
375
+
376
+
377
+ return Qnil;
378
+ }
379
+
380
+ static VALUE
381
+ glu_NurbsSurface(argc, argv, obj)
382
+ int argc;
383
+ VALUE *argv;
384
+ VALUE obj;
385
+ {
386
+ struct nurbsdata *ndata;
387
+ GLint sknot_count;
388
+ GLfloat *sknot;
389
+ GLint tknot_count;
390
+ GLfloat *tknot;
391
+ GLint s_stride;
392
+ GLint t_stride;
393
+ GLfloat *ctlarray;
394
+ GLint sorder;
395
+ GLint torder;
396
+ GLenum type;
397
+
398
+ VALUE args[11];
399
+ VALUE ary_ctl1;
400
+ int type_len;
401
+
402
+ 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])) {
403
+ case 7:
404
+ sknot_count = (GLint)RARRAY_LENINT(args[1]);
405
+ sknot = ALLOC_N(GLfloat, sknot_count);
406
+ ary2cflt(args[1], sknot, sknot_count);
407
+
408
+ tknot_count = (GLint)RARRAY_LENINT(args[2]);
409
+ tknot = ALLOC_N(GLfloat, tknot_count);
410
+ ary2cflt(args[2], tknot, tknot_count);
411
+
412
+ sorder = (GLint)NUM2INT(args[4]);
413
+ torder = (GLint)NUM2INT(args[5]);
414
+ type = (GLenum)NUM2INT(args[6]);
415
+
416
+ t_stride = get_surface_dim(type);
417
+ s_stride = t_stride * sorder;
418
+
419
+ ctlarray = ALLOC_N(GLfloat, (sknot_count-sorder)*(tknot_count-torder)*t_stride);
420
+ ary_ctl1 = rb_funcall(args[3],rb_intern("flatten"),0);
421
+ ary2cflt(ary_ctl1, ctlarray, (sknot_count-sorder)*(tknot_count-torder)*t_stride);
422
+ break;
423
+ case 11:
424
+ sknot_count = (GLint)NUM2INT(args[1]);
425
+ sknot = ALLOC_N(GLfloat, sknot_count);
426
+ ary2cflt(args[2], sknot, sknot_count);
427
+
428
+ tknot_count = (GLint)NUM2INT(args[3]);
429
+ tknot = ALLOC_N(GLfloat, tknot_count);
430
+ ary2cflt(args[4], tknot, tknot_count);
431
+
432
+ s_stride = (GLint)NUM2INT(args[5]);
433
+ t_stride = (GLint)NUM2INT(args[6]);
434
+ sorder = (GLint)NUM2INT(args[8]);
435
+ torder = (GLint)NUM2INT(args[9]);
436
+ type = (GLint)NUM2INT(args[10]);
437
+ type_len = get_surface_dim(type);
438
+
439
+ ctlarray = ALLOC_N(GLfloat, (sknot_count-sorder)*(tknot_count-torder)*type_len);
440
+ ary_ctl1 = rb_funcall(args[7],rb_intern("flatten"),0);
441
+ ary2cflt(ary_ctl1, ctlarray, (sknot_count-sorder)*(tknot_count-torder)*type_len);
442
+ break;
443
+ default:
444
+ rb_raise(rb_eArgError, "gluNurbsSurface needs 7 or 11 arguments");
445
+ return Qnil; /* not reached */
446
+ }
447
+ GetNURBS(args[0], ndata);
448
+ gluNurbsSurface(ndata->nobj, sknot_count, sknot, tknot_count, tknot,
449
+ s_stride, t_stride, ctlarray, sorder, torder, type);
450
+
451
+ /* store the pointers */
452
+
453
+ gms.ptr = REALLOC_N(gms.ptr, GLfloat*, gms.len+=3);
454
+ gms.ptr[gms.len-3] = sknot;
455
+ gms.ptr[gms.len-2] = tknot;
456
+ gms.ptr[gms.len-1] = ctlarray;
457
+
458
+
459
+ return Qnil;
460
+ }
461
+ static VALUE
462
+ glu_BeginTrim(obj, arg1)
463
+ VALUE obj, arg1;
464
+ {
465
+ struct nurbsdata *ndata;
466
+ GetNURBS(arg1, ndata);
467
+ rb_ary_push(n_current, arg1);
468
+ gluBeginTrim(ndata->nobj);
469
+
470
+ return Qnil;
471
+ }
472
+ static VALUE
473
+ glu_EndTrim(obj, arg1)
474
+ VALUE obj, arg1;
475
+ {
476
+ struct nurbsdata *ndata;
477
+ GetNURBS(arg1, ndata);
478
+ gluEndTrim(ndata->nobj);
479
+ rb_ary_pop(n_current);
480
+
481
+ return Qnil;
482
+ }
483
+ static VALUE
484
+ glu_PwlCurve(argc, argv, obj)
485
+ int argc;
486
+ VALUE *argv;
487
+ VALUE obj;
488
+ {
489
+ struct nurbsdata *ndata;
490
+ GLint count;
491
+ GLfloat *array;
492
+ GLint stride;
493
+ GLenum type;
494
+
495
+ VALUE args[5];
496
+ VALUE ary_ctl1;
497
+
498
+ switch (rb_scan_args(argc, argv, "32", &args[0], &args[1], &args[2], &args[3], &args[4])) {
499
+ case 3:
500
+ count = (GLint)RARRAY_LENINT(args[1]);
501
+ type = NUM2INT(args[2]);
502
+ stride = (type == GLU_MAP1_TRIM_2 ? 2 : 3);
503
+
504
+ array = ALLOC_N(GLfloat, count*stride);
505
+ ary_ctl1 = rb_funcall(args[1],rb_intern("flatten"),0);
506
+ ary2cflt(ary_ctl1, array, count*stride);
507
+ break;
508
+ case 5:
509
+ count = NUM2INT(args[1]);
510
+ stride = NUM2INT(args[3]);
511
+ type = NUM2INT(args[4]);
512
+
513
+ array = ALLOC_N(GLfloat, count*stride);
514
+ ary_ctl1 = rb_funcall(args[2],rb_intern("flatten"),0);
515
+ ary2cflt(ary_ctl1, array, count*stride);
516
+ break;
517
+ default:
518
+ rb_raise(rb_eArgError, "gluPwlCurve needs 3 or 5 arguments");
519
+ return Qnil; /* not reached */
520
+ }
521
+
522
+ GetNURBS(args[0], ndata);
523
+ gluPwlCurve(ndata->nobj, count, array, stride, type);
524
+ free(array);
525
+
526
+ return Qnil;
527
+ }
528
+
529
+ static VALUE glu_LoadSamplingMatrices(obj,arg1,arg2,arg3,arg4)
530
+ VALUE obj, arg1,arg2,arg3,arg4;
531
+ {
532
+ struct nurbsdata *ndata;
533
+ GLfloat mdl_mtx[4*4];
534
+ GLfloat persp_mtx[4*4];
535
+ GLint viewport[4];
536
+
537
+ GetNURBS(arg1, ndata);
538
+ ary2cmatfloat(arg2,mdl_mtx,4,4);
539
+ ary2cmatfloat(arg3,persp_mtx,4,4);
540
+ ary2cint(arg4,viewport,4);
541
+
542
+ gluLoadSamplingMatrices(ndata->nobj,mdl_mtx,persp_mtx,viewport);
543
+
544
+
545
+ return Qnil;
546
+ }
547
+
548
+ /*
549
+ * Tesselation API
550
+ */
551
+ static VALUE t_current;
552
+ #define TESS_DATA 0
553
+ #define TESS_BEGIN 1
554
+ #define TESS_VERTEX 2
555
+ #define TESS_END 3
556
+ #define TESS_ERROR 4
557
+ #define TESS_EDGE_FLAG 5
558
+ #define TESS_OUTDATA 6
559
+ #define TESS_COMBINE 7
560
+ #define TESS_BEGIN_DATA 8
561
+ #define TESS_VERTEX_DATA 9
562
+ #define TESS_END_DATA 10
563
+ #define TESS_ERROR_DATA 11
564
+ #define TESS_EDGE_FLAG_DATA 12
565
+ #define TESS_COMBINE_DATA 13
566
+ #define TESS_USERDATA 14
567
+
568
+ static void
569
+ mark_tess(tdata)
570
+ struct tessdata* tdata;
571
+ {
572
+ if (tdata->tobj)
573
+ rb_gc_mark(tdata->t_ref);
574
+ }
575
+ static void
576
+ free_tess(tdata)
577
+ struct tessdata *tdata;
578
+ {
579
+ if (tdata->tobj)
580
+ gluDeleteTess(tdata->tobj);
581
+ tdata->t_ref = Qnil;
582
+ tdata->tobj = NULL;
583
+ }
584
+ static VALUE
585
+ glu_NewTess(obj)
586
+ VALUE obj;
587
+ {
588
+ VALUE ret;
589
+ struct tessdata *tdata;
590
+ ret = Data_Make_Struct(cTess, struct tessdata, mark_tess, free_tess, tdata);
591
+ tdata->tobj = gluNewTess();
592
+ tdata->t_ref = rb_ary_new2(REF_LAST);
593
+
594
+ return ret;
595
+ }
596
+ static VALUE
597
+ glu_DeleteTess(obj, arg1)
598
+ VALUE obj, arg1;
599
+ {
600
+ struct tessdata *tdata;
601
+ GetTESS(arg1, tdata);
602
+ free_tess(tdata);
603
+
604
+ return Qnil;
605
+ }
606
+
607
+ /* tess* callback function wrappers */
608
+ #define TESS_CALLBACK_COMMON \
609
+ VALUE tess; \
610
+ struct tessdata *tdata; \
611
+ tess = rb_ary_entry(t_current, -1); \
612
+ if (tess == Qnil) \
613
+ return; \
614
+ GetTESS(tess, tdata);
615
+
616
+ static void CALLBACK
617
+ t_begin(type)
618
+ GLenum type;
619
+ {
620
+ TESS_CALLBACK_COMMON
621
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_BEGIN), callId, 1, INT2NUM(type));
622
+ }
623
+ static void CALLBACK
624
+ t_edgeFlag(flag)
625
+ GLboolean flag;
626
+ {
627
+ TESS_CALLBACK_COMMON
628
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_EDGE_FLAG), callId, 1, GLBOOL2RUBY(flag));
629
+ }
630
+ static void CALLBACK
631
+ t_vertex(data)
632
+ void* data;
633
+ {
634
+ TESS_CALLBACK_COMMON
635
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_VERTEX), callId, 1, data);
636
+ }
637
+ static void CALLBACK
638
+ t_end()
639
+ {
640
+ TESS_CALLBACK_COMMON
641
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_END), callId, 0);
642
+ }
643
+ static void CALLBACK
644
+ t_error(errorno)
645
+ GLenum errorno;
646
+ {
647
+ TESS_CALLBACK_COMMON
648
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_ERROR), callId, 1, INT2NUM(errorno));
649
+ }
650
+ static void CALLBACK
651
+ t_begin_data(type, user_data)
652
+ GLenum type;
653
+ void* user_data;
654
+ {
655
+ TESS_CALLBACK_COMMON
656
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_BEGIN_DATA), callId, 2, INT2NUM(type), user_data);
657
+ }
658
+ static void CALLBACK
659
+ t_edgeFlag_data(flag, user_data)
660
+ GLboolean flag;
661
+ void* user_data;
662
+ {
663
+ TESS_CALLBACK_COMMON
664
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_EDGE_FLAG_DATA), callId, 2, GLBOOL2RUBY(flag), user_data);
665
+ }
666
+ static void CALLBACK
667
+ t_vertex_data(data, user_data)
668
+ void* data;
669
+ void* user_data;
670
+ {
671
+ TESS_CALLBACK_COMMON
672
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_VERTEX_DATA), callId, 2, data, user_data);
673
+ }
674
+ static void CALLBACK
675
+ t_end_data(user_data)
676
+ void* user_data;
677
+ {
678
+ TESS_CALLBACK_COMMON
679
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_END_DATA), callId, 1, user_data);
680
+ }
681
+ static void CALLBACK
682
+ t_error_data(errorno, user_data)
683
+ GLenum errorno;
684
+ void* user_data;
685
+ {
686
+ TESS_CALLBACK_COMMON
687
+ rb_funcall(rb_ary_entry(tdata->t_ref, TESS_ERROR_DATA), callId, 2, INT2NUM(errorno), user_data);
688
+ }
689
+
690
+ static void CALLBACK
691
+ t_combine(coords, vertex_data, weight, outData)
692
+ GLdouble coords[3];
693
+ void* vertex_data[4];
694
+ GLfloat weight[4];
695
+ void** outData;
696
+ {
697
+ VALUE rb_coord, rb_vertex_data, rb_weight;
698
+ int i;
699
+ TESS_CALLBACK_COMMON
700
+
701
+ rb_coord = rb_ary_new2(3);
702
+ for (i = 0; i < 3; i++)
703
+ rb_ary_store(rb_coord, i, rb_float_new(coords[i]));
704
+ rb_vertex_data = rb_ary_new2(4);
705
+ for (i = 0; i < 4; i++)
706
+ rb_ary_store(rb_vertex_data, i, (VALUE)vertex_data[i]);
707
+ rb_weight = rb_ary_new2(4);
708
+ for (i = 0; i < 4; i++)
709
+ rb_ary_store(rb_weight, i, rb_float_new(weight[i]));
710
+ *outData = (void*)rb_funcall(rb_ary_entry(tdata->t_ref, TESS_COMBINE), callId, 3, rb_coord, rb_vertex_data, rb_weight);
711
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_OUTDATA), (VALUE)*outData);
712
+ }
713
+
714
+ static void CALLBACK
715
+ t_combine_data(coords, vertex_data, weight, outData, user_data)
716
+ GLdouble coords[3];
717
+ void* vertex_data[4];
718
+ GLfloat weight[4];
719
+ void** outData;
720
+ void* user_data;
721
+ {
722
+ VALUE rb_coord, rb_vertex_data, rb_weight;
723
+ int i;
724
+ TESS_CALLBACK_COMMON
725
+
726
+ rb_coord = rb_ary_new2(3);
727
+ for (i = 0; i < 3; i++)
728
+ rb_ary_store(rb_coord, i, rb_float_new(coords[i]));
729
+ rb_vertex_data = rb_ary_new2(4);
730
+ for (i = 0; i < 4; i++)
731
+ rb_ary_store(rb_vertex_data, i, (VALUE)vertex_data[i]);
732
+ rb_weight = rb_ary_new2(4);
733
+ for (i = 0; i < 4; i++)
734
+ rb_ary_store(rb_weight, i, rb_float_new(weight[i]));
735
+
736
+ *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);
737
+
738
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_OUTDATA), (VALUE)*outData);
739
+ }
740
+
741
+ #undef TESS_CALLBACK_COMMON
742
+
743
+ static VALUE
744
+ glu_TessProperty(obj, arg1, arg2, arg3)
745
+ VALUE obj, arg1, arg2, arg3;
746
+ {
747
+ struct tessdata* tdata;
748
+ GLenum property;
749
+ GLdouble value;
750
+ GetTESS(arg1, tdata);
751
+ property = (GLenum)NUM2INT(arg2);
752
+ if (property == GLU_TESS_BOUNDARY_ONLY) {
753
+ value = (GLdouble)RUBYBOOL2GL(arg3);
754
+ } else {
755
+ value = (GLdouble)NUM2DBL(arg3);
756
+ }
757
+ gluTessProperty(tdata->tobj, property, value);
758
+
759
+ return Qnil;
760
+ }
761
+ static VALUE
762
+ glu_GetTessProperty(obj, arg1, arg2)
763
+ VALUE obj, arg1, arg2;
764
+ {
765
+ struct tessdata* tdata;
766
+ GLenum property;
767
+ GLdouble value;
768
+ GetTESS(arg1, tdata);
769
+ property = (GLenum)NUM2INT(arg2);
770
+ gluGetTessProperty(tdata->tobj, property, &value);
771
+
772
+ return cond_GLBOOL2RUBY_D(property,value);
773
+ }
774
+ static VALUE
775
+ glu_TessNormal(obj, arg1, arg2, arg3, arg4)
776
+ VALUE obj, arg1, arg2, arg3, arg4;
777
+ {
778
+ struct tessdata* tdata;
779
+ GLdouble x, y, z;
780
+ GetTESS(arg1, tdata);
781
+ x = (GLdouble)NUM2DBL(arg2);
782
+ y = (GLdouble)NUM2DBL(arg3);
783
+ z = (GLdouble)NUM2DBL(arg4);
784
+ gluTessNormal(tdata->tobj, x, y, z);
785
+
786
+ return Qnil;
787
+ }
788
+ static VALUE
789
+ glu_TessBeginPolygon(obj, arg1, arg2)
790
+ VALUE obj, arg1, arg2;
791
+ {
792
+ struct tessdata* tdata;
793
+ GetTESS(arg1, tdata);
794
+ rb_ary_store(tdata->t_ref, TESS_USERDATA, arg2);
795
+ rb_ary_store(tdata->t_ref, TESS_OUTDATA, rb_ary_new());
796
+ rb_ary_store(tdata->t_ref, TESS_DATA, rb_ary_new());
797
+ rb_ary_push(t_current, arg1);
798
+ gluTessBeginPolygon(tdata->tobj, (void*)arg2);
799
+
800
+ return Qnil;
801
+ }
802
+ static VALUE
803
+ glu_TessEndPolygon(obj, arg1)
804
+ VALUE obj, arg1;
805
+ {
806
+ struct tessdata* tdata;
807
+ GetTESS(arg1, tdata);
808
+ gluTessEndPolygon(tdata->tobj);
809
+ rb_ary_store(tdata->t_ref, TESS_USERDATA, Qnil);
810
+ rb_ary_store(tdata->t_ref, TESS_OUTDATA, Qnil);
811
+ rb_ary_store(tdata->t_ref, TESS_DATA, Qnil);
812
+ rb_ary_pop(t_current);
813
+
814
+ return Qnil;
815
+ }
816
+ static VALUE
817
+ glu_TessBeginContour(obj, arg1)
818
+ VALUE obj, arg1;
819
+ {
820
+ struct tessdata* tdata;
821
+ GetTESS(arg1, tdata);
822
+ gluTessBeginContour(tdata->tobj);
823
+
824
+ return Qnil;
825
+ }
826
+ static VALUE
827
+ glu_TessEndContour(obj, arg1)
828
+ VALUE obj, arg1;
829
+ {
830
+ struct tessdata* tdata;
831
+ GetTESS(arg1, tdata);
832
+ gluTessEndContour(tdata->tobj);
833
+
834
+ return Qnil;
835
+ }
836
+
837
+ #define TESS_CALLBACK_CASE(_type_,_function_) \
838
+ case GLU_##_type_: \
839
+ rb_ary_store(tdata->t_ref, _type_, arg3); \
840
+ if (NIL_P(arg3)) \
841
+ gluTessCallback(tdata->tobj, type, NULL); \
842
+ else \
843
+ gluTessCallback(tdata->tobj, type, _function_); \
844
+ break;
845
+
846
+ static VALUE
847
+ glu_TessCallback(obj, arg1, arg2, arg3)
848
+ VALUE obj, arg1, arg2, arg3;
849
+ {
850
+ struct tessdata* tdata;
851
+ GLenum type;
852
+ GetTESS(arg1, tdata);
853
+ type = (GLenum)NUM2INT(arg2);
854
+ if (!rb_obj_is_kind_of(arg3,rb_cProc) && !NIL_P(arg3))
855
+ rb_raise(rb_eTypeError, "gluTessCallback needs Proc Object:%s",rb_class2name(CLASS_OF(arg3)));
856
+
857
+ switch (type) {
858
+ TESS_CALLBACK_CASE(TESS_BEGIN,t_begin)
859
+ TESS_CALLBACK_CASE(TESS_BEGIN_DATA,t_begin_data)
860
+ TESS_CALLBACK_CASE(TESS_EDGE_FLAG,t_edgeFlag)
861
+ TESS_CALLBACK_CASE(TESS_EDGE_FLAG_DATA,t_edgeFlag_data)
862
+ TESS_CALLBACK_CASE(TESS_VERTEX,t_vertex)
863
+ TESS_CALLBACK_CASE(TESS_VERTEX_DATA,t_vertex_data)
864
+ TESS_CALLBACK_CASE(TESS_END,t_end)
865
+ TESS_CALLBACK_CASE(TESS_END_DATA,t_end_data)
866
+ TESS_CALLBACK_CASE(TESS_ERROR,t_error)
867
+ TESS_CALLBACK_CASE(TESS_ERROR_DATA,t_error_data)
868
+ TESS_CALLBACK_CASE(TESS_COMBINE,t_combine)
869
+ TESS_CALLBACK_CASE(TESS_COMBINE_DATA,t_combine_data)
870
+ }
871
+
872
+ return Qnil;
873
+ }
874
+ #undef TESS_CALLBACK_CASE
875
+
876
+ static VALUE
877
+ glu_BeginPolygon(obj, arg1)
878
+ VALUE obj, arg1;
879
+ {
880
+ struct tessdata* tdata;
881
+ GetTESS(arg1, tdata);
882
+ rb_ary_store(tdata->t_ref, TESS_DATA, rb_ary_new());
883
+ rb_ary_push(t_current, arg1);
884
+ gluBeginPolygon(tdata->tobj);
885
+
886
+ return Qnil;
887
+ }
888
+ static VALUE
889
+ glu_TessVertex(obj, arg1, arg2, arg3)
890
+ VALUE obj, arg1, arg2, arg3;
891
+ {
892
+ struct tessdata* tdata;
893
+ GLdouble v[3] = {0.0,0.0,0.0};
894
+ GetTESS(arg1, tdata);
895
+ rb_ary_push(rb_ary_entry(tdata->t_ref, TESS_DATA), arg3);
896
+ Check_Type(arg2,T_ARRAY);
897
+ ary2cdbl(arg2, v, 3);
898
+ gluTessVertex(tdata->tobj, v,(void *)arg3);
899
+
900
+ return Qnil;
901
+ }
902
+ static VALUE
903
+ glu_NextContour(obj, arg1, arg2)
904
+ VALUE obj, arg1, arg2;
905
+ {
906
+ struct tessdata* tdata;
907
+ GLenum type;
908
+ GetTESS(arg1, tdata);
909
+ type = (GLenum)NUM2INT(arg2);
910
+ gluNextContour(tdata->tobj, type);
911
+
912
+ return Qnil;
913
+ }
914
+ static VALUE
915
+ glu_EndPolygon(obj, arg1)
916
+ VALUE obj, arg1;
917
+ {
918
+ struct tessdata* tdata;
919
+ GetTESS(arg1, tdata);
920
+ gluEndPolygon(tdata->tobj);
921
+ rb_ary_store(tdata->t_ref, TESS_DATA, Qnil);
922
+ rb_ary_pop(t_current);
923
+
924
+ return Qnil;
925
+ }
926
+
927
+ /*
928
+ * Quadric API
929
+ */
930
+ static VALUE q_current;
931
+
932
+ static void CALLBACK
933
+ q_error(errorno)
934
+ GLenum errorno;
935
+ {
936
+ VALUE quad;
937
+ struct quaddata *qdata;
938
+ quad = rb_ary_entry(q_current, -1);
939
+ if (quad == Qnil)
940
+ return;
941
+ GetQUAD(quad, qdata);
942
+ rb_funcall(rb_ary_entry(qdata->q_ref, GLU_ERROR), callId, 1, INT2NUM(errorno));
943
+ }
944
+
945
+ static VALUE
946
+ glu_QuadricCallback(obj, arg1, arg2, arg3)
947
+ VALUE obj, arg1, arg2, arg3;
948
+ {
949
+ struct quaddata* qdata;
950
+ GLenum type;
951
+ GetQUAD(arg1, qdata);
952
+ type = (GLenum)NUM2INT(arg2);
953
+ if (!rb_obj_is_kind_of(arg3,rb_cProc) && !NIL_P(arg3))
954
+ rb_raise(rb_eTypeError, "gluQuadricCallback needs Proc Object:%s",rb_class2name(CLASS_OF(arg3)));
955
+
956
+
957
+ if (type!=GLU_ERROR)
958
+ return Qnil;
959
+
960
+ rb_ary_store(qdata->q_ref, type, arg3);
961
+ if (NIL_P(arg3))
962
+ gluQuadricCallback(qdata->qobj, type, NULL);
963
+ else
964
+ gluQuadricCallback(qdata->qobj, type, q_error);
965
+
966
+
967
+ return Qnil;
968
+ }
969
+
970
+ static void
971
+ free_quad(qdata)
972
+ struct quaddata *qdata;
973
+ {
974
+ if (qdata->qobj) gluDeleteQuadric(qdata->qobj);
975
+ qdata->qobj = NULL;
976
+ qdata->q_ref = Qnil;
977
+ }
978
+ static void
979
+ mark_quad(qdata)
980
+ struct quaddata* qdata;
981
+ {
982
+ if (qdata->qobj)
983
+ rb_gc_mark(qdata->q_ref);
984
+ }
985
+ static VALUE
986
+ glu_NewQuadric(obj)
987
+ VALUE obj;
988
+ {
989
+ VALUE ret;
990
+ struct quaddata *qdata;
991
+ ret = Data_Make_Struct(cQuad, struct quaddata, mark_quad, free_quad, qdata);
992
+ qdata->qobj = gluNewQuadric();
993
+ qdata->q_ref = rb_ary_new2(REF_LAST);
994
+
995
+ return ret;
996
+ }
997
+ static VALUE
998
+ glu_DeleteQuadric(obj, arg1)
999
+ VALUE obj, arg1;
1000
+ {
1001
+ struct quaddata *qdata;
1002
+ GetQUAD(arg1, qdata);
1003
+ free_quad(qdata);
1004
+
1005
+ return Qnil;
1006
+ }
1007
+ static VALUE
1008
+ glu_QuadricNormals(obj, arg1, arg2)
1009
+ VALUE obj, arg1, arg2;
1010
+ {
1011
+ struct quaddata* qdata;
1012
+ GLenum normals;
1013
+ GetQUAD(arg1, qdata);
1014
+ normals = (GLenum)NUM2INT(arg2);
1015
+ gluQuadricNormals(qdata->qobj, normals);
1016
+
1017
+ return Qnil;
1018
+ }
1019
+ static VALUE
1020
+ glu_QuadricTexture(obj, arg1, arg2)
1021
+ VALUE obj, arg1, arg2;
1022
+ {
1023
+ struct quaddata* qdata;
1024
+ GLboolean textureCoords;
1025
+ GetQUAD(arg1, qdata);
1026
+ textureCoords = (GLboolean)RUBYBOOL2GL(arg2);
1027
+ gluQuadricTexture(qdata->qobj, textureCoords);
1028
+
1029
+ return Qnil;
1030
+ }
1031
+ static VALUE
1032
+ glu_QuadricOrientation(obj, arg1, arg2)
1033
+ VALUE obj, arg1, arg2;
1034
+ {
1035
+ struct quaddata* qdata;
1036
+ GLenum orientation;
1037
+ GetQUAD(arg1, qdata);
1038
+ orientation = (GLenum)NUM2INT(arg2);
1039
+ gluQuadricOrientation(qdata->qobj, orientation);
1040
+
1041
+ return Qnil;
1042
+ }
1043
+ static VALUE
1044
+ glu_QuadricDrawStyle(obj, arg1, arg2)
1045
+ VALUE obj, arg1, arg2;
1046
+ {
1047
+ struct quaddata* qdata;
1048
+ GLenum drawStyle;
1049
+ GetQUAD(arg1, qdata);
1050
+ drawStyle = (GLenum)NUM2INT(arg2);
1051
+ gluQuadricDrawStyle(qdata->qobj, drawStyle);
1052
+
1053
+ return Qnil;
1054
+ }
1055
+ static VALUE
1056
+ glu_Cylinder(obj, arg1, arg2, arg3, arg4, arg5, arg6)
1057
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6;
1058
+ {
1059
+ struct quaddata* qdata;
1060
+ GLdouble baseRadius;
1061
+ GLdouble topRadius;
1062
+ GLdouble height;
1063
+ GLint slices;
1064
+ GLint stacks;
1065
+
1066
+ GetQUAD(arg1, qdata);
1067
+ baseRadius = (GLdouble)NUM2DBL(arg2);
1068
+ topRadius = (GLdouble)NUM2DBL(arg3);
1069
+ height = (GLdouble)NUM2DBL(arg4);
1070
+ slices = (GLint)NUM2INT(arg5);
1071
+ stacks = (GLint)NUM2INT(arg6);
1072
+
1073
+ rb_ary_push(q_current, arg1);
1074
+ gluCylinder(qdata->qobj, baseRadius, topRadius, height, slices, stacks);
1075
+ rb_ary_pop(q_current);
1076
+
1077
+ return Qnil;
1078
+ }
1079
+ static VALUE
1080
+ glu_Disk(obj, arg1, arg2, arg3, arg4, arg5)
1081
+ VALUE obj, arg1, arg2, arg3, arg4, arg5;
1082
+ {
1083
+ struct quaddata* qdata;
1084
+ GLdouble innerRadius;
1085
+ GLdouble outerRadius;
1086
+ GLint slices;
1087
+ GLint loops;
1088
+
1089
+ GetQUAD(arg1, qdata);
1090
+ innerRadius = (GLdouble)NUM2DBL(arg2);
1091
+ outerRadius = (GLdouble)NUM2DBL(arg3);
1092
+ slices = (GLint)NUM2INT(arg4);
1093
+ loops = (GLint)NUM2INT(arg5);
1094
+
1095
+ rb_ary_push(q_current, arg1);
1096
+
1097
+ gluDisk(qdata->qobj, innerRadius, outerRadius, slices, loops);
1098
+ rb_ary_pop(q_current);
1099
+
1100
+ return Qnil;
1101
+ }
1102
+ static VALUE
1103
+ glu_PartialDisk(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
1104
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
1105
+ {
1106
+ struct quaddata* qdata;
1107
+ GLdouble innerRadius;
1108
+ GLdouble outerRadius;
1109
+ GLint slices;
1110
+ GLint loops;
1111
+ GLdouble startAngle;
1112
+ GLdouble sweepAngle;
1113
+
1114
+ GetQUAD(arg1, qdata);
1115
+ innerRadius = (GLdouble)NUM2DBL(arg2);
1116
+ outerRadius = (GLdouble)NUM2DBL(arg3);
1117
+ slices = (GLint)NUM2INT(arg4);
1118
+ loops = (GLint)NUM2INT(arg5);
1119
+ startAngle = (GLdouble)NUM2DBL(arg6);
1120
+ sweepAngle = (GLdouble)NUM2DBL(arg7);
1121
+
1122
+ rb_ary_push(q_current, arg1);
1123
+ gluPartialDisk(qdata->qobj, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle);
1124
+ rb_ary_pop(q_current);
1125
+
1126
+ return Qnil;
1127
+ }
1128
+ static VALUE
1129
+ glu_Sphere(obj, arg1, arg2, arg3, arg4)
1130
+ VALUE obj, arg1, arg2, arg3, arg4;
1131
+ {
1132
+ struct quaddata* qdata;
1133
+ GLdouble radius;
1134
+ GLint slices;
1135
+ GLint stacks;
1136
+
1137
+ GetQUAD(arg1, qdata);
1138
+ radius = (GLdouble)NUM2DBL(arg2);
1139
+ slices = (GLint)NUM2INT(arg3);
1140
+ stacks = (GLint)NUM2INT(arg4);
1141
+
1142
+ rb_ary_push(q_current, arg1);
1143
+ gluSphere(qdata->qobj, radius, slices, stacks);
1144
+ rb_ary_pop(q_current);
1145
+
1146
+ return Qnil;
1147
+ }
1148
+
1149
+ /* */
1150
+
1151
+ static VALUE
1152
+ glu_LookAt(obj,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)
1153
+ VALUE obj,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9;
1154
+ {
1155
+ GLdouble eyex;
1156
+ GLdouble eyey;
1157
+ GLdouble eyez;
1158
+ GLdouble centerx;
1159
+ GLdouble centery;
1160
+ GLdouble centerz;
1161
+ GLdouble upx;
1162
+ GLdouble upy;
1163
+ GLdouble upz;
1164
+ eyex = (GLdouble)NUM2DBL(arg1);
1165
+ eyey = (GLdouble)NUM2DBL(arg2);
1166
+ eyez = (GLdouble)NUM2DBL(arg3);
1167
+ centerx = (GLdouble)NUM2DBL(arg4);
1168
+ centery = (GLdouble)NUM2DBL(arg5);
1169
+ centerz = (GLdouble)NUM2DBL(arg6);
1170
+ upx = (GLdouble)NUM2DBL(arg7);
1171
+ upy = (GLdouble)NUM2DBL(arg8);
1172
+ upz = (GLdouble)NUM2DBL(arg9);
1173
+ gluLookAt( eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz );
1174
+
1175
+ return Qnil;
1176
+ }
1177
+ static VALUE
1178
+ glu_Ortho2D(obj,arg1,arg2,arg3,arg4)
1179
+ VALUE obj,arg1,arg2,arg3,arg4;
1180
+ {
1181
+ GLdouble left;
1182
+ GLdouble right;
1183
+ GLdouble bottom;
1184
+ GLdouble top;
1185
+ left = (GLdouble)NUM2DBL(arg1);
1186
+ right = (GLdouble)NUM2DBL(arg2);
1187
+ bottom = (GLdouble)NUM2DBL(arg3);
1188
+ top = (GLdouble)NUM2DBL(arg4);
1189
+ gluOrtho2D(left,right,bottom,top);
1190
+
1191
+ return Qnil;
1192
+ }
1193
+ static VALUE
1194
+ glu_Perspective(obj,arg1,arg2,arg3,arg4)
1195
+ VALUE obj,arg1,arg2,arg3,arg4;
1196
+ {
1197
+ GLdouble fovy;
1198
+ GLdouble aspect;
1199
+ GLdouble zNear;
1200
+ GLdouble zFar;
1201
+ fovy = (GLdouble)NUM2DBL(arg1);
1202
+ aspect = (GLdouble)NUM2DBL(arg2);
1203
+ zNear = (GLdouble)NUM2DBL(arg3);
1204
+ zFar = (GLdouble)NUM2DBL(arg4);
1205
+ gluPerspective(fovy,aspect,zNear,zFar);
1206
+
1207
+ return Qnil;
1208
+ }
1209
+ static VALUE
1210
+ glu_PickMatrix(argc,argv,obj)
1211
+ int argc;
1212
+ VALUE* argv;
1213
+ VALUE obj;
1214
+ {
1215
+ GLdouble x;
1216
+ GLdouble y;
1217
+ GLdouble width;
1218
+ GLdouble height;
1219
+ GLint viewport[4];
1220
+
1221
+ VALUE args[5];
1222
+
1223
+ switch (rb_scan_args(argc, argv, "23", &args[0], &args[1], &args[2], &args[3], &args[4])) {
1224
+ case 2:
1225
+ width = 5.0f;
1226
+ height = 5.0f;
1227
+ glGetIntegerv(GL_VIEWPORT, viewport);
1228
+ break;
1229
+ case 4:
1230
+ width = (GLdouble)NUM2DBL(args[2]);
1231
+ height = (GLdouble)NUM2DBL(args[3]);
1232
+ glGetIntegerv(GL_VIEWPORT, viewport);
1233
+ break;
1234
+ case 5:
1235
+ width = (GLdouble)NUM2DBL(args[2]);
1236
+ height = (GLdouble)NUM2DBL(args[3]);
1237
+ ary2cint(args[4], viewport, 4);
1238
+ break;
1239
+ default:
1240
+ rb_raise(rb_eArgError, "gluPickMatrix needs 2,4 or 5 parameters");
1241
+ }
1242
+ x = (GLdouble)NUM2DBL(args[0]);
1243
+ y = (GLdouble)NUM2DBL(args[1]);
1244
+ gluPickMatrix(x, y, width, height, viewport);
1245
+
1246
+ return Qnil;
1247
+ }
1248
+
1249
+ static VALUE
1250
+ glu_Project(argc,argv,obj)
1251
+ int argc;
1252
+ VALUE* argv;
1253
+ VALUE obj;
1254
+ {
1255
+ GLdouble ox;
1256
+ GLdouble oy;
1257
+ GLdouble oz;
1258
+ GLdouble mdl_mtx[4*4];
1259
+ GLdouble prj_mtx[4*4];
1260
+ GLint vport[4];
1261
+ GLdouble wx;
1262
+ GLdouble wy;
1263
+ GLdouble wz;
1264
+
1265
+ VALUE args[6];
1266
+
1267
+ switch (rb_scan_args(argc, argv, "33", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5])) {
1268
+ case 3:
1269
+ glGetDoublev(GL_MODELVIEW_MATRIX, mdl_mtx);
1270
+ glGetDoublev(GL_PROJECTION_MATRIX, prj_mtx);
1271
+ glGetIntegerv(GL_VIEWPORT, vport);
1272
+ break;
1273
+ case 6:
1274
+ ary2cmatdouble(args[3], mdl_mtx, 4, 4);
1275
+ ary2cmatdouble(args[4], prj_mtx, 4, 4);
1276
+ ary2cint(args[5], vport, 4);
1277
+ break;
1278
+ default:
1279
+ rb_raise(rb_eArgError, "gluProject needs 3 or 6 parameters");
1280
+ }
1281
+ ox = (GLdouble)NUM2DBL(args[0]);
1282
+ oy = (GLdouble)NUM2DBL(args[1]);
1283
+ oz = (GLdouble)NUM2DBL(args[2]);
1284
+
1285
+ if (gluProject(ox, oy, oz, mdl_mtx, prj_mtx, vport, &wx, &wy, &wz) == GL_TRUE) {
1286
+
1287
+ return rb_ary_new3(3, rb_float_new(wx), rb_float_new(wy), rb_float_new(wz));
1288
+ } else {
1289
+
1290
+ check_for_gluerror(GLU_INVALID_VALUE);
1291
+ return Qnil; /* not reached */
1292
+ }
1293
+ }
1294
+ static VALUE
1295
+ glu_UnProject(argc,argv,obj)
1296
+ int argc;
1297
+ VALUE* argv;
1298
+ VALUE obj;
1299
+ {
1300
+ GLdouble wx;
1301
+ GLdouble wy;
1302
+ GLdouble wz;
1303
+ GLdouble mdl_mtx[4*4];
1304
+ GLdouble prj_mtx[4*4];
1305
+ GLint vport[4];
1306
+ GLdouble ox;
1307
+ GLdouble oy;
1308
+ GLdouble oz;
1309
+
1310
+ VALUE args[6];
1311
+
1312
+ switch (rb_scan_args(argc, argv, "33", &args[0], &args[1], &args[2], &args[3], &args[4], &args[5])) {
1313
+ case 3:
1314
+ glGetDoublev(GL_MODELVIEW_MATRIX, mdl_mtx);
1315
+ glGetDoublev(GL_PROJECTION_MATRIX, prj_mtx);
1316
+ glGetIntegerv(GL_VIEWPORT, vport);
1317
+ break;
1318
+ case 6:
1319
+ ary2cmatdouble(args[3], mdl_mtx, 4, 4);
1320
+ ary2cmatdouble(args[4], prj_mtx, 4, 4);
1321
+ ary2cint(args[5], vport, 4);
1322
+ break;
1323
+ default:
1324
+ rb_raise(rb_eArgError, "gluUnProject needs 3 or 6 parameters");
1325
+ }
1326
+ wx = (GLdouble)NUM2DBL(args[0]);
1327
+ wy = (GLdouble)NUM2DBL(args[1]);
1328
+ wz = (GLdouble)NUM2DBL(args[2]);
1329
+
1330
+ if (gluUnProject(wx, wy, wz, mdl_mtx, prj_mtx, vport, &ox, &oy, &oz) == GL_TRUE) {
1331
+
1332
+ return rb_ary_new3(3, rb_float_new(ox), rb_float_new(oy), rb_float_new(oz));
1333
+ } else {
1334
+
1335
+ check_for_gluerror(GLU_INVALID_VALUE);
1336
+ return Qnil; /* not reached */
1337
+ }
1338
+ }
1339
+
1340
+ static VALUE
1341
+ glu_Build1DMipmaps(obj, arg1, arg2, arg3, arg4, arg5, arg6)
1342
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6;
1343
+ {
1344
+ GLenum target;
1345
+ GLint components;
1346
+ GLint width;
1347
+ GLenum format;
1348
+ GLenum type;
1349
+ int ret;
1350
+
1351
+ target = (GLenum)NUM2INT(arg1);
1352
+ components = (GLint)NUM2INT(arg2);
1353
+ width = (GLint)NUM2INT(arg3);
1354
+ format = (GLenum)NUM2INT(arg4);
1355
+ type = (GLenum)NUM2INT(arg5);
1356
+ Check_Type(arg6,T_STRING);
1357
+ CheckDataSize(type,format,width,arg6);
1358
+
1359
+ ret = gluBuild1DMipmaps(target, components, width, format, type, RSTRING_PTR(arg6));
1360
+ check_for_gluerror(ret);
1361
+
1362
+ return INT2NUM(ret);
1363
+ }
1364
+
1365
+ static VALUE
1366
+ glu_Build2DMipmaps(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
1367
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
1368
+ {
1369
+ GLenum target;
1370
+ GLint components;
1371
+ GLint width;
1372
+ GLint height;
1373
+ GLenum format;
1374
+ GLenum type;
1375
+ int ret;
1376
+
1377
+ target = (GLenum)NUM2INT(arg1);
1378
+ components = (GLint)NUM2INT(arg2);
1379
+ width = (GLint)NUM2INT(arg3);
1380
+ height = (GLint)NUM2INT(arg4);
1381
+ format = (GLenum)NUM2INT(arg5);
1382
+ type = (GLenum)NUM2INT(arg6);
1383
+ Check_Type(arg7,T_STRING);
1384
+ CheckDataSize(type,format,width*height,arg7);
1385
+
1386
+ ret = gluBuild2DMipmaps(target, components, width, height, format, type, RSTRING_PTR(arg7));
1387
+ check_for_gluerror(ret);
1388
+
1389
+ return INT2NUM(ret);
1390
+ }
1391
+
1392
+ static VALUE
1393
+ glu_ScaleImage(obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
1394
+ VALUE obj, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
1395
+ {
1396
+ GLenum format;
1397
+ GLint widthin;
1398
+ GLint heightin;
1399
+ GLenum typein;
1400
+ void* datain;
1401
+ GLint widthout;
1402
+ GLint heightout;
1403
+ GLenum typeout;
1404
+ VALUE ret;
1405
+ GLint retcode;
1406
+
1407
+ format = (GLenum)NUM2INT(arg1);
1408
+ widthin = (GLint)NUM2INT(arg2);
1409
+ heightin = (GLint)NUM2INT(arg3);
1410
+ typein = (GLenum)NUM2INT(arg4);
1411
+ Check_Type(arg5,T_STRING);
1412
+ CheckDataSize(typein,format,heightin*widthin,arg5);
1413
+ datain = RSTRING_PTR(arg5);
1414
+ widthout = (GLint)NUM2INT(arg6);
1415
+ heightout = (GLint)NUM2INT(arg7);
1416
+ typeout = (GLenum)NUM2INT(arg8);
1417
+ ret = allocate_buffer_with_string(GetDataSize(typeout,format,widthout*heightout));
1418
+ retcode = gluScaleImage(format, widthin, heightin, typein, datain,
1419
+ widthout, heightout, typeout, (GLvoid*)RSTRING_PTR(ret));
1420
+
1421
+ check_for_gluerror(retcode);
1422
+
1423
+ return ret;
1424
+ }
1425
+
1426
+ static VALUE
1427
+ glu_ErrorString(obj, arg1)
1428
+ VALUE obj, arg1;
1429
+ {
1430
+ GLenum errorCode;
1431
+ GLubyte* error;
1432
+ errorCode = (GLenum)NUM2INT(arg1);
1433
+ error = (GLubyte*)gluErrorString(errorCode);
1434
+
1435
+ if (error)
1436
+ return rb_str_new2((char *)error);
1437
+ else
1438
+ return Qnil;
1439
+ }
1440
+ static VALUE
1441
+ glu_GetString(obj, arg1)
1442
+ VALUE obj, arg1;
1443
+ {
1444
+ GLenum name;
1445
+ GLubyte* str;
1446
+ name = (GLenum)NUM2INT(arg1);
1447
+ str = (GLubyte*)gluGetString(name);
1448
+
1449
+ if (str)
1450
+ return rb_str_new2((char *)str);
1451
+ else
1452
+ return Qnil;
1453
+ }
1454
+
1455
+ static VALUE module;
1456
+
1457
+ DLLEXPORT void Init_glu()
1458
+ {
1459
+ callId = rb_intern("call");
1460
+ refId = rb_intern("[]");
1461
+ module = rb_define_module("Glu");
1462
+
1463
+ glu_init_enums(module);
1464
+
1465
+ rb_define_module_function(module, "gluNewNurbsRenderer", glu_NewNurbsRenderer, 0);
1466
+ rb_define_module_function(module, "gluDeleteNurbsRenderer", glu_DeleteNurbsRenderer, 1);
1467
+ rb_define_module_function(module, "gluNurbsProperty", glu_NurbsProperty, 3);
1468
+ rb_define_module_function(module, "gluGetNurbsProperty", glu_GetNurbsProperty, 2);
1469
+ rb_define_module_function(module, "gluBeginCurve", glu_BeginCurve, 1);
1470
+ rb_define_module_function(module, "gluEndCurve", glu_EndCurve, 1);
1471
+ rb_define_module_function(module, "gluNurbsCurve", glu_NurbsCurve, -1);
1472
+ rb_define_module_function(module, "gluBeginSurface", glu_BeginSurface, 1);
1473
+ rb_define_module_function(module, "gluEndSurface", glu_EndSurface, 1);
1474
+ rb_define_module_function(module, "gluNurbsSurface", glu_NurbsSurface, -1);
1475
+ rb_define_module_function(module, "gluBeginTrim", glu_BeginTrim, 1);
1476
+ rb_define_module_function(module, "gluEndTrim", glu_EndTrim, 1);
1477
+ rb_define_module_function(module, "gluPwlCurve", glu_PwlCurve, -1);
1478
+ rb_define_module_function(module, "gluNewTess", glu_NewTess, 0);
1479
+ rb_define_module_function(module, "gluDeleteTess", glu_DeleteTess, 1);
1480
+ rb_define_module_function(module, "gluTessCallback", glu_TessCallback, 3);
1481
+ rb_define_module_function(module, "gluBeginPolygon", glu_BeginPolygon, 1);
1482
+ rb_define_module_function(module, "gluTessVertex", glu_TessVertex, 3);
1483
+ rb_define_module_function(module, "gluNextContour", glu_NextContour, 2);
1484
+ rb_define_module_function(module, "gluEndPolygon", glu_EndPolygon, 1);
1485
+ rb_define_module_function(module, "gluTessBeginPolygon", glu_TessBeginPolygon, 2);
1486
+ rb_define_module_function(module, "gluTessBeginContour", glu_TessBeginContour, 1);
1487
+ rb_define_module_function(module, "gluTessEndContour", glu_TessEndContour, 1);
1488
+ rb_define_module_function(module, "gluTessEndPolygon", glu_TessEndPolygon, 1);
1489
+ rb_define_module_function(module, "gluTessProperty", glu_TessProperty, 3);
1490
+ rb_define_module_function(module, "gluTessNormal", glu_TessNormal, 4);
1491
+ rb_define_module_function(module, "gluGetTessProperty", glu_GetTessProperty, 2);
1492
+ rb_define_module_function(module, "gluNewQuadric", glu_NewQuadric, 0);
1493
+ rb_define_module_function(module, "gluDeleteQuadric", glu_DeleteQuadric, 1);
1494
+ rb_define_module_function(module, "gluQuadricNormals", glu_QuadricNormals, 2);
1495
+ rb_define_module_function(module, "gluQuadricTexture", glu_QuadricTexture, 2);
1496
+ rb_define_module_function(module, "gluQuadricOrientation", glu_QuadricOrientation, 2);
1497
+ rb_define_module_function(module, "gluQuadricDrawStyle", glu_QuadricDrawStyle, 2);
1498
+ rb_define_module_function(module, "gluCylinder", glu_Cylinder, 6);
1499
+ rb_define_module_function(module, "gluDisk", glu_Disk, 5);
1500
+ rb_define_module_function(module, "gluPartialDisk", glu_PartialDisk, 7);
1501
+ rb_define_module_function(module, "gluSphere", glu_Sphere, 4);
1502
+
1503
+ rb_define_module_function(module, "gluLookAt", glu_LookAt, 9);
1504
+ rb_define_module_function(module, "gluOrtho2D", glu_Ortho2D, 4);
1505
+ rb_define_module_function(module, "gluPerspective", glu_Perspective, 4);
1506
+ rb_define_module_function(module, "gluPickMatrix", glu_PickMatrix, -1);
1507
+ rb_define_module_function(module, "gluProject", glu_Project, -1);
1508
+ rb_define_module_function(module, "gluUnProject", glu_UnProject, -1);
1509
+ rb_define_module_function(module, "gluBuild1DMipmaps", glu_Build1DMipmaps, 6);
1510
+ rb_define_module_function(module, "gluBuild2DMipmaps", glu_Build2DMipmaps, 7);
1511
+ rb_define_module_function(module, "gluScaleImage", glu_ScaleImage, 8);
1512
+ rb_define_module_function(module, "gluErrorString", glu_ErrorString, 1);
1513
+ rb_define_module_function(module, "gluGetString", glu_GetString, 1);
1514
+
1515
+ rb_define_module_function(module, "gluLoadSamplingMatrices",glu_LoadSamplingMatrices,4);
1516
+ rb_define_module_function(module, "gluQuadricCallback", glu_QuadricCallback, 3);
1517
+ rb_define_module_function(module, "gluNurbsCallback", glu_NurbsCallback, 3);
1518
+
1519
+ Class_GLUError = rb_define_class_under(module, "Error", rb_eStandardError);
1520
+
1521
+ rb_define_method(Class_GLUError, "initialize", GLUError_initialize, 2);
1522
+ rb_define_attr(Class_GLUError, "id", 1, 0);
1523
+
1524
+ cNurbs = rb_define_class("Nurbs", rb_cObject);
1525
+ cTess = rb_define_class("Tess", rb_cObject);
1526
+ cQuad = rb_define_class("Quadric", rb_cObject);
1527
+
1528
+ rb_global_variable(&t_current); /* current active tesselator, nurbs and quadric, used for callbacks */
1529
+ t_current = rb_ary_new();
1530
+ rb_global_variable(&n_current);
1531
+ n_current = rb_ary_new();
1532
+ rb_global_variable(&q_current);
1533
+ q_current = rb_ary_new();
1534
+ }