1 /* $Id: ml_gl.c,v 1.51 2007-04-13 02:48:43 garrigue Exp $ */
16 #include <caml/misc.h>
17 #include <caml/mlvalues.h>
18 #include <caml/callback.h>
19 #include <caml/memory.h>
20 #include <caml/alloc.h>
21 #include <caml/fail.h>
26 #if !defined(GL_VERSION_1_4)
27 #define GL_GENERATE_MIPMAP 0x8191
30 /* #include <stdio.h> */
32 void ml_raise_gl(const char *errmsg
)
34 static value
* gl_exn
= NULL
;
36 gl_exn
= caml_named_value("glerror");
37 raise_with_string(*gl_exn
, (char*)errmsg
);
40 value
copy_string_check (const char *str
)
42 if (!str
) ml_raise_gl("Null string");
43 return copy_string ((char*) str
);
51 static struct record input_table
[] = {
55 static struct record
*tag_table
= NULL
;
57 #define TABLE_SIZE (TAG_NUMBER*2+1)
59 CAMLprim value
ml_gl_make_table (value unit
)
64 tag_table
= stat_alloc (TABLE_SIZE
* sizeof(struct record
));
65 memset ((char *) tag_table
, 0, TABLE_SIZE
* sizeof(struct record
));
66 for (i
= 0; i
< TAG_NUMBER
; i
++) {
67 hash
= (unsigned long) input_table
[i
].key
% TABLE_SIZE
;
68 while (tag_table
[hash
].key
!= 0) {
70 if (hash
== TABLE_SIZE
) hash
= 0;
72 tag_table
[hash
].key
= input_table
[i
].key
;
73 tag_table
[hash
].data
= input_table
[i
].data
;
78 GLenum
GLenum_val(value tag
)
80 unsigned int hash
= (unsigned long) tag
% TABLE_SIZE
;
82 if (!tag_table
) ml_gl_make_table (Val_unit
);
83 while (tag_table
[hash
].key
!= tag
) {
84 if (tag_table
[hash
].key
== 0) ml_raise_gl ("Unknown tag");
86 if (hash
== TABLE_SIZE
) hash
= 0;
89 fprintf(stderr, "Converted %ld to %d", Int_val(tag), tag_table[hash].data);
91 return tag_table
[hash
].data
;
95 GLenum GLenum_val(value tag)
101 ml_raise_gl("Unknown tag");
105 ML_2 (glAccum
, GLenum_val
, Float_val
)
106 ML_2 (glAlphaFunc
, GLenum_val
, Float_val
)
108 ML_1 (glBegin
, GLenum_val
)
110 ML_5 (glBitmap
, Int_val
, Int_val
, Pair(arg3
,Float_val
,Float_val
),
111 Pair(arg4
,Float_val
,Float_val
), Void_raw
)
113 ML_2 (glBlendFunc
, GLenum_val
, GLenum_val
)
115 CAMLprim value
ml_glClipPlane(value plane
, value equation
) /* ML */
120 for (i
= 0; i
< 4; i
++)
121 eq
[i
] = Double_val (Field(equation
,i
));
122 glClipPlane (GL_CLIP_PLANE0
+ Int_val(plane
), eq
);
126 CAMLprim value
ml_glClear(value bit_list
) /* ML */
130 while (bit_list
!= Val_int(0)) {
131 switch (Field (bit_list
, 0)) {
133 accu
|= GL_COLOR_BUFFER_BIT
; break;
135 accu
|= GL_DEPTH_BUFFER_BIT
; break;
137 accu
|= GL_ACCUM_BUFFER_BIT
; break;
139 accu
|= GL_STENCIL_BUFFER_BIT
; break;
141 bit_list
= Field (bit_list
, 1);
146 ML_4 (glClearAccum
, Float_val
, Float_val
, Float_val
, Float_val
)
147 ML_4 (glClearColor
, Double_val
, Double_val
, Double_val
, Double_val
)
148 ML_1 (glClearDepth
, Double_val
)
149 ML_1 (glClearIndex
, Float_val
)
150 ML_1 (glClearStencil
, Int_val
)
151 ML_4 (glColor4d
, Double_val
, Double_val
, Double_val
, Double_val
)
152 ML_4 (glColorMask
, Int_val
, Int_val
, Int_val
, Int_val
)
153 ML_2 (glColorMaterial
, GLenum_val
, GLenum_val
)
154 ML_5 (glCopyPixels
, Int_val
, Int_val
, Int_val
, Int_val
, GLenum_val
)
155 ML_1 (glCullFace
, GLenum_val
)
157 ML_1 (glDisable
, GLenum_val
)
158 ML_1 (glDepthFunc
, GLenum_val
)
159 ML_1 (glDepthMask
, Int_val
)
160 ML_2 (glDepthRange
, Double_val
, Double_val
)
162 CAMLprim value
ml_glDrawBuffer (value buffer
)
164 if (Is_block(buffer
)) {
165 int n
= Int_val (Field(buffer
,1));
166 if (n
>= GL_AUX_BUFFERS
)
167 ml_raise_gl ("GlFunc.draw_buffer : no such auxiliary buffer");
168 glDrawBuffer (GL_AUX0
+ n
);
170 else glDrawBuffer (GLenum_val(buffer
));
174 ML_4 (glDrawPixels
, Int_val
, Int_val
, GLenum_val
, Type_void_raw
)
176 ML_1 (glEdgeFlag
, Int_val
)
177 ML_1 (glEnable
, GLenum_val
)
179 ML_1 (glEvalCoord1d
, Double_val
)
180 ML_2 (glEvalCoord2d
, Double_val
, Double_val
)
181 ML_3 (glEvalMesh1
, GLenum_val
, Int_val
, Int_val
)
182 ML_5 (glEvalMesh2
, GLenum_val
, Int_val
, Int_val
, Int_val
, Int_val
)
183 ML_1 (glEvalPoint1
, Int_val
)
184 ML_2 (glEvalPoint2
, Int_val
, Int_val
)
187 ML_3 (glFeedbackBuffer
, Int_val
, GLenum_val
, (GLfloat
*)Addr_raw
)
189 CAMLprim value
ml_glFog (value param
) /* ML */
194 switch (Field(param
,0))
197 glFogi(GL_FOG_MODE
, GLenum_val(Field(param
,1)));
200 glFogf(GL_FOG_DENSITY
, Float_val(Field(param
,1)));
203 glFogf(GL_FOG_START
, Float_val(Field(param
,1)));
206 glFogf(GL_FOG_END
, Float_val(Field(param
,1)));
209 glFogf(GL_FOG_INDEX
, Float_val(Field(param
,1)));
212 for (i
= 0; i
< 4; i
++) params
[i
] = Float_val(Field(Field(param
,1),i
));
213 glFogfv(GL_FOG_COLOR
, params
);
221 ML_1 (glFrontFace
, GLenum_val
)
222 ML_3 (glFrustum
, Pair(arg1
,Double_val
,Double_val
),
223 Pair(arg2
,Double_val
,Double_val
), Pair(arg3
,Double_val
,Double_val
))
225 ML_1_ (glGetString
, GLenum_val
, copy_string_check
)
226 ML_2 (glGetDoublev
, GLenum_val
, Double_raw
)
228 CAMLprim value
ml_glGetError(value unit
)
230 switch (glGetError()) {
231 case GL_NO_ERROR
: return MLTAG_no_error
;
232 case GL_INVALID_ENUM
: return MLTAG_invalid_enum
;
233 case GL_INVALID_VALUE
: return MLTAG_invalid_value
;
234 case GL_INVALID_OPERATION
: return MLTAG_invalid_operation
;
235 case GL_STACK_OVERFLOW
: return MLTAG_stack_overflow
;
236 case GL_STACK_UNDERFLOW
: return MLTAG_stack_underflow
;
237 case GL_OUT_OF_MEMORY
: return MLTAG_out_of_memory
;
238 #if defined(GL_VERSION_1_2) || defined(GL_TABLE_TOO_LARGE)
239 case GL_TABLE_TOO_LARGE
: return MLTAG_table_too_large
;
241 default: ml_raise_gl("glGetError: unknown error");
245 CAMLprim value
ml_glHint (value target
, value hint
)
250 case MLTAG_fog
: targ
= GL_FOG_HINT
; break;
251 case MLTAG_line_smooth
: targ
= GL_LINE_SMOOTH_HINT
; break;
252 case MLTAG_perspective_correction
:
253 targ
= GL_PERSPECTIVE_CORRECTION_HINT
; break;
254 case MLTAG_point_smooth
: targ
= GL_POINT_SMOOTH_HINT
; break;
255 case MLTAG_polygon_smooth
: targ
= GL_POLYGON_SMOOTH_HINT
; break;
257 glHint (targ
, GLenum_val(hint
));
261 ML_1 (glIndexMask
, Int_val
)
262 ML_1 (glIndexd
, Double_val
)
264 ML_1_ (glIsEnabled
, GLenum_val
, Val_int
)
266 CAMLprim value
ml_glLight (value n
, value param
) /* ML */
271 if (Int_val(n
) >= GL_MAX_LIGHTS
) invalid_argument ("Gl.light");
272 switch (Field(param
,0))
278 for (i
= 0; i
< 4; i
++)
279 params
[i
] = Float_val (Field(Field(param
, 1), i
));
281 case MLTAG_spot_direction
:
282 for (i
= 0; i
< 3; i
++)
283 params
[i
] = Float_val (Field(Field(param
, 1), i
));
286 params
[0] = Float_val (Field(param
, 1));
288 glLightfv (GL_LIGHT0
+ Int_val(n
), GLenum_val(Field(param
,0)), params
);
292 CAMLprim value
ml_glLightModel (value param
) /* ML */
297 switch (Field(param
,0))
300 for (i
= 0; i
< 4; i
++)
301 params
[i
] = Float_val (Field(Field(param
,1),i
));
302 glLightModelfv (GL_LIGHT_MODEL_AMBIENT
, params
);
304 case MLTAG_local_viewer
:
305 glLightModelf (GL_LIGHT_MODEL_LOCAL_VIEWER
,
306 Int_val(Field(param
,1)));
309 glLightModeli (GL_LIGHT_MODEL_TWO_SIDE
,
310 Int_val(Field(param
,1)));
312 case MLTAG_color_control
:
313 #ifdef GL_VERSION_1_2
314 switch (Field(param
,1))
316 case MLTAG_separate_specular_color
:
317 glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL
,
318 GL_SEPARATE_SPECULAR_COLOR
);
320 case MLTAG_single_color
:
321 glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL
,
326 ml_raise_gl ("Parameter: GL_LIGHT_MODEL_COLOR_CONTROL not available");
333 ML_1 (glLineWidth
, Float_val
)
334 ML_1 (glLoadName
, Int_val
)
335 ML_0 (glLoadIdentity
)
337 #ifdef GL_VERSION_1_3
338 ML_1 (glLoadTransposeMatrixd
, Double_raw
)
340 CAMLprim
void ml_glLoadTransposeMatrixd (value raw
)
342 ml_raise_gl ("Function: glLoadTransposeMatrixd not available");
345 ML_1 (glLogicOp
, GLenum_val
)
347 CAMLprim value
ml_glMap1d (value target
, value
*u
, value order
, value raw
)
354 targ
= GL_MAP1_VERTEX_3
; ustride
= 3; break;
356 targ
= GL_MAP1_VERTEX_4
; ustride
= 4; break;
358 targ
= GL_MAP1_INDEX
; ustride
= 1; break;
360 targ
= GL_MAP1_COLOR_4
; ustride
= 4; break;
362 targ
= GL_MAP1_NORMAL
; ustride
= 3; break;
363 case MLTAG_texture_coord_1
:
364 targ
= GL_MAP1_TEXTURE_COORD_1
; ustride
= 1; break;
365 case MLTAG_texture_coord_2
:
366 targ
= GL_MAP1_TEXTURE_COORD_2
; ustride
= 2; break;
367 case MLTAG_texture_coord_3
:
368 targ
= GL_MAP1_TEXTURE_COORD_3
; ustride
= 3; break;
369 case MLTAG_texture_coord_4
:
370 targ
= GL_MAP1_TEXTURE_COORD_4
; ustride
= 4; break;
372 glMap1d (targ
, Double_val(u
[0]), Double_val(u
[1]),
373 ustride
, Int_val(order
), Double_raw(raw
));
377 CAMLprim value
ml_glMap2d (value target
, value u
, value uorder
,
378 value v
, value vorder
, value raw
)
385 targ
= GL_MAP2_VERTEX_3
; ustride
= 3; break;
387 targ
= GL_MAP2_VERTEX_4
; ustride
= 4; break;
389 targ
= GL_MAP2_INDEX
; ustride
= 1; break;
391 targ
= GL_MAP2_COLOR_4
; ustride
= 4; break;
393 targ
= GL_MAP2_NORMAL
; ustride
= 3; break;
394 case MLTAG_texture_coord_1
:
395 targ
= GL_MAP2_TEXTURE_COORD_1
; ustride
= 1; break;
396 case MLTAG_texture_coord_2
:
397 targ
= GL_MAP2_TEXTURE_COORD_2
; ustride
= 2; break;
398 case MLTAG_texture_coord_3
:
399 targ
= GL_MAP2_TEXTURE_COORD_3
; ustride
= 3; break;
400 case MLTAG_texture_coord_4
:
401 targ
= GL_MAP2_TEXTURE_COORD_4
; ustride
= 4; break;
403 glMap2d (targ
, Double_val(Field(u
,0)), Double_val(Field(u
,1)), ustride
,
404 Int_val(uorder
), Double_val(Field(v
,0)), Double_val(Field(v
,1)),
405 Int_val(uorder
)*ustride
, Int_val(vorder
), Double_raw(raw
));
411 ML_2 (glMapGrid1d
, Int_val
, Pair(arg2
,Double_val
,Double_val
))
412 ML_4 (glMapGrid2d
, Int_val
, Pair(arg2
,Double_val
,Double_val
),
413 Int_val
, Pair(arg4
,Double_val
,Double_val
))
415 CAMLprim value
ml_glMaterial (value face
, value param
) /* ML */
420 switch (Field(param
,0))
422 case MLTAG_shininess
:
423 params
[0] = Float_val (Field(param
, 1));
425 case MLTAG_color_indexes
:
426 for (i
= 0; i
< 3; i
++)
427 params
[i
] = Float_val (Field(Field(param
, 1), i
));
430 for (i
= 0; i
< 4; i
++)
431 params
[i
] = Float_val (Field(Field(param
, 1), i
));
434 glMaterialfv (GLenum_val(face
), GLenum_val(Field(param
,0)), params
);
438 ML_1 (glMatrixMode
, GLenum_val
)
439 ML_3 (glNormal3d
, Double_val
, Double_val
, Double_val
)
440 ML_1 (glPassThrough
, Float_val
)
442 CAMLprim value
ml_glPixelMapfv (value map
, value raw
)
444 glPixelMapfv (GLenum_val(map
), Int_val(Size_raw(raw
))/sizeof(GLfloat
),
449 ML_1 (glPixelStorei
, Pair(arg1
,GLenum_val
,Int_val
))
451 CAMLprim value
ml_glPixelTransfer (value param
)
453 GLenum pname
= GLenum_val (Field(param
,0));
459 case GL_INDEX_OFFSET
:
460 glPixelTransferi (pname
, Int_val (Field(param
,1)));
463 glPixelTransferf (pname
, Float_val (Field(param
,1)));
468 ML_2 (glPixelZoom
, Float_val
, Float_val
)
473 CAMLprim value
ml_glPushAttrib (value list
)
477 while (list
!= Val_int(0)) {
478 switch (Field(list
,0)) {
479 case MLTAG_accum_buffer
:mask
|= GL_ACCUM_BUFFER_BIT
; break;
480 case MLTAG_color_buffer
:mask
|= GL_COLOR_BUFFER_BIT
; break;
481 case MLTAG_current
: mask
|= GL_CURRENT_BIT
; break;
482 case MLTAG_depth_buffer
:mask
|= GL_DEPTH_BUFFER_BIT
; break;
483 case MLTAG_enable
: mask
|= GL_ENABLE_BIT
; break;
484 case MLTAG_eval
: mask
|= GL_EVAL_BIT
; break;
485 case MLTAG_fog
: mask
|= GL_FOG_BIT
; break;
486 case MLTAG_hint
: mask
|= GL_HINT_BIT
; break;
487 case MLTAG_lighting
: mask
|= GL_LIGHTING_BIT
; break;
488 case MLTAG_line
: mask
|= GL_LINE_BIT
; break;
489 case MLTAG_list
: mask
|= GL_LIST_BIT
; break;
490 case MLTAG_pixel_mode
: mask
|= GL_PIXEL_MODE_BIT
; break;
491 case MLTAG_point
: mask
|= GL_POINT_BIT
; break;
492 case MLTAG_polygon
: mask
|= GL_POLYGON_BIT
; break;
493 case MLTAG_polygon_stipple
:mask
|= GL_POLYGON_STIPPLE_BIT
; break;
494 case MLTAG_scissor
: mask
|= GL_SCISSOR_BIT
; break;
495 case MLTAG_stencil_buffer
:mask
|= GL_STENCIL_BUFFER_BIT
; break;
496 case MLTAG_texture
: mask
|= GL_TEXTURE_BIT
; break;
497 case MLTAG_transform
: mask
|= GL_TRANSFORM_BIT
; break;
498 case MLTAG_viewport
: mask
|= GL_VIEWPORT_BIT
; break;
500 list
= Field(list
,1);
507 ML_1 (glPushName
, Int_val
)
509 CAMLprim value
ml_glRasterPos(value x
, value y
, value z
, value w
) /* ML */
511 if (z
== Val_int(0)) glRasterPos2d (Double_val(x
), Double_val(y
));
512 else if (w
== Val_int(0))
513 glRasterPos3d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)));
515 glRasterPos4d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)),
516 Double_val(Field(w
, 0)));
520 CAMLprim value
ml_glReadBuffer (value buffer
)
522 if (Is_block(buffer
)) {
523 int n
= Int_val (Field(buffer
,1));
524 if (n
>= GL_AUX_BUFFERS
)
525 ml_raise_gl ("GlFunc.read_buffer : no such auxiliary buffer");
526 glReadBuffer (GL_AUX0
+ n
);
528 else glReadBuffer (GLenum_val(buffer
));
532 CAMLprim value
ml_glReadPixels(value x
, value y
, value w
, value h
, value format
, value raw
) /* ML */
534 glPixelStorei(GL_PACK_SWAP_BYTES
, 0);
535 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
536 glReadPixels(Int_val(x
),Int_val(y
),Int_val(w
),Int_val(h
),GLenum_val(format
),
541 ML_bc6 (ml_glReadPixels
)
542 ML_2 (glRectd
, Pair(arg1
,Double_val
,Double_val
),
543 Pair(arg2
,Double_val
,Double_val
))
544 ML_1_ (glRenderMode
, GLenum_val
, Val_int
)
545 ML_4 (glRotated
, Double_val
, Double_val
, Double_val
, Double_val
)
546 ML_3 (glScaled
, Double_val
, Double_val
, Double_val
)
548 ML_4 (glScissor
, Int_val
, Int_val
, Int_val
, Int_val
)
549 ML_2 (glSelectBuffer
, Int_val
, (GLuint
*)Addr_raw
)
550 ML_1 (glShadeModel
, GLenum_val
)
551 ML_3 (glStencilFunc
, GLenum_val
, Int_val
, Int_val
)
552 ML_1 (glStencilMask
, Int_val
)
553 ML_3 (glStencilOp
, GLenum_val
, GLenum_val
, GLenum_val
)
555 ML_1 (glTexCoord1d
, Double_val
)
556 ML_2 (glTexCoord2d
, Double_val
, Double_val
)
557 ML_3 (glTexCoord3d
, Double_val
, Double_val
, Double_val
)
558 ML_4 (glTexCoord4d
, Double_val
, Double_val
, Double_val
, Double_val
)
560 CAMLprim value
ml_glTexEnv (value param
)
562 value params
= Field(param
,1);
566 switch (Field(param
,0)) {
568 glTexEnvi (GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GLenum_val(params
));
571 for (i
= 0; i
< 4; i
++) color
[i
] = Float_val(Field(params
,i
));
572 glTexEnvfv (GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, color
);
578 CAMLprim value
ml_glTexGen (value coord
, value param
)
580 value params
= Field(param
,1);
584 if (Field(param
,0) == MLTAG_mode
)
585 glTexGeni (GLenum_val(coord
), GL_TEXTURE_GEN_MODE
, GLenum_val(params
));
587 for (i
= 0; i
< 4; i
++) point
[i
] = Double_val(Field(params
,i
));
588 glTexGendv (GLenum_val(coord
), GLenum_val(Field(param
,0)), point
);
593 CAMLprim value
ml_glTexImage1D (value proxy
, value level
, value internal
,
594 value width
, value border
, value format
,
597 glTexImage1D (proxy
== Val_int(1)
598 ? GL_PROXY_TEXTURE_1D
: GL_TEXTURE_1D
,
599 Int_val(level
), Int_val(internal
), Int_val(width
),
600 Int_val(border
), GLenum_val(format
),
601 Type_raw(data
), Void_raw(data
));
605 ML_bc7 (ml_glTexImage1D
)
607 CAMLprim value
ml_glTexImage2D (value proxy
, value level
, value internal
,
608 value width
, value height
, value border
,
609 value format
, value data
)
611 /* printf("p=%x,l=%d,i=%d,w=%d,h=%d,b=%d,f=%x,t=%x,d=%x\n", */
612 glTexImage2D (proxy
== Val_int(1)
613 ? GL_PROXY_TEXTURE_2D
: GL_TEXTURE_2D
,
614 Int_val(level
), Int_val(internal
), Int_val(width
),
615 Int_val(height
), Int_val(border
), GLenum_val(format
),
616 Type_raw(data
), Void_raw(data
));
621 ML_bc8 (ml_glTexImage2D
)
623 CAMLprim value
ml_glTexParameter (value target
, value param
)
625 GLenum targ
= GLenum_val(target
);
626 GLenum pname
= GLenum_val(Field(param
,0));
627 value params
= Field(param
,1);
632 case GL_TEXTURE_BORDER_COLOR
:
633 for (i
= 0; i
< 4; i
++) color
[i
] = Float_val(Field(params
,i
));
634 glTexParameterfv (targ
, pname
, color
);
636 case GL_TEXTURE_PRIORITY
:
637 glTexParameterf (targ
, pname
, Float_val(params
));
639 case GL_GENERATE_MIPMAP
:
640 #ifdef GL_VERSION_1_4
641 glTexParameteri (targ
, pname
, Int_val(params
));
643 ml_raise_gl ("Parameter: GL_GENERATE_MIPMAP not available");
647 glTexParameteri (targ
, pname
, GLenum_val(params
));
653 ML_2 (glGenTextures
, Int_val
, Int_raw
)
654 ML_2 (glBindTexture
, GLenum_val
, Nativeint_val
)
656 CAMLprim value
ml_glDeleteTexture (value texture_id
)
658 GLuint id
= Nativeint_val(texture_id
);
659 glDeleteTextures(1,&id
);
663 ML_3 (glTranslated
, Double_val
, Double_val
, Double_val
)
665 CAMLprim value
ml_glVertex(value x
, value y
, value z
, value w
) /* ML */
667 if (z
== Val_int(0)) glVertex2d (Double_val(x
), Double_val(y
));
668 else if (w
== Val_int(0))
669 glVertex3d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)));
671 glVertex4d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)),
672 Double_val(Field(w
, 0)));
676 ML_4 (glViewport
, Int_val
, Int_val
, Int_val
, Int_val
)
681 ML_1_ (glIsList
, Int_val
, Val_int
)
682 ML_2 (glDeleteLists
, Int_val
, Int_val
)
683 ML_1_ (glGenLists
, Int_val
, Val_int
)
684 ML_2 (glNewList
, Int_val
, GLenum_val
)
686 ML_1 (glCallList
, Int_val
)
687 ML_1 (glListBase
, Int_val
)
689 CAMLprim value
ml_glCallLists (value indexes
) /* ML */
694 switch (Field(indexes
,0)) {
696 glCallLists (string_length(Field(indexes
,1)),
698 String_val(Field(indexes
,1)));
701 len
= Wosize_val (indexes
);
702 table
= calloc (len
, sizeof (GLint
));
703 for (i
= 0; i
< len
; i
++) table
[i
] = Int_val (Field(indexes
,i
));
704 glCallLists (len
, GL_INT
, table
);