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 void ml_raise_gl(const char *errmsg
)
32 static value
const * gl_exn
;
34 gl_exn
= caml_named_value("glerror");
35 caml_raise_with_string(*gl_exn
, (char*)errmsg
);
38 value
copy_string_check (const char *str
)
40 if (!str
) ml_raise_gl("Null string");
41 return caml_copy_string ((char*) str
);
49 static struct record input_table
[] = {
53 static struct record
*tag_table
= NULL
;
55 #define TABLE_SIZE (TAG_NUMBER*2+1)
57 CAMLprim value
ml_gl_make_table (value unit
)
62 tag_table
= caml_stat_alloc (TABLE_SIZE
* sizeof(struct record
));
63 memset ((char *) tag_table
, 0, TABLE_SIZE
* sizeof(struct record
));
64 for (i
= 0; i
< TAG_NUMBER
; i
++) {
65 hash
= (unsigned long) input_table
[i
].key
% TABLE_SIZE
;
66 while (tag_table
[hash
].key
!= 0) {
68 if (hash
== TABLE_SIZE
) hash
= 0;
70 tag_table
[hash
].key
= input_table
[i
].key
;
71 tag_table
[hash
].data
= input_table
[i
].data
;
76 GLenum
GLenum_val(value tag
)
78 unsigned int hash
= (unsigned long) tag
% TABLE_SIZE
;
80 if (!tag_table
) ml_gl_make_table (Val_unit
);
81 while (tag_table
[hash
].key
!= tag
) {
82 if (tag_table
[hash
].key
== 0) ml_raise_gl ("Unknown tag");
84 if (hash
== TABLE_SIZE
) hash
= 0;
87 fprintf(stderr, "Converted %ld to %d", Int_val(tag), tag_table[hash].data);
89 return tag_table
[hash
].data
;
93 GLenum GLenum_val(value tag)
99 ml_raise_gl("Unknown tag");
103 ML_2 (glAccum
, GLenum_val
, Float_val
)
104 ML_2 (glAlphaFunc
, GLenum_val
, Float_val
)
106 ML_1 (glBegin
, GLenum_val
)
108 ML_5 (glBitmap
, Int_val
, Int_val
, Pair(arg3
,Float_val
,Float_val
),
109 Pair(arg4
,Float_val
,Float_val
), Void_raw
)
111 ML_2 (glBlendFunc
, GLenum_val
, GLenum_val
)
113 CAMLprim value
ml_glClipPlane(value plane
, value equation
) /* ML */
118 for (i
= 0; i
< 4; i
++)
119 eq
[i
] = Double_val (Field(equation
,i
));
120 glClipPlane (GL_CLIP_PLANE0
+ Int_val(plane
), eq
);
124 CAMLprim value
ml_glClear(value bit_list
) /* ML */
128 while (bit_list
!= Val_int(0)) {
129 switch (Field (bit_list
, 0)) {
131 accu
|= GL_COLOR_BUFFER_BIT
; break;
133 accu
|= GL_DEPTH_BUFFER_BIT
; break;
135 accu
|= GL_ACCUM_BUFFER_BIT
; break;
137 accu
|= GL_STENCIL_BUFFER_BIT
; break;
139 bit_list
= Field (bit_list
, 1);
144 ML_4 (glClearAccum
, Float_val
, Float_val
, Float_val
, Float_val
)
145 ML_4 (glClearColor
, Double_val
, Double_val
, Double_val
, Double_val
)
146 ML_1 (glClearDepth
, Double_val
)
147 ML_1 (glClearIndex
, Float_val
)
148 ML_1 (glClearStencil
, Int_val
)
149 ML_4 (glColor4d
, Double_val
, Double_val
, Double_val
, Double_val
)
150 ML_4 (glColorMask
, Int_val
, Int_val
, Int_val
, Int_val
)
151 ML_2 (glColorMaterial
, GLenum_val
, GLenum_val
)
152 ML_5 (glCopyPixels
, Int_val
, Int_val
, Int_val
, Int_val
, GLenum_val
)
153 ML_1 (glCullFace
, GLenum_val
)
155 ML_1 (glDisable
, GLenum_val
)
156 ML_1 (glDepthFunc
, GLenum_val
)
157 ML_1 (glDepthMask
, Int_val
)
158 ML_2 (glDepthRange
, Double_val
, Double_val
)
160 CAMLprim value
ml_glDrawBuffer (value buffer
)
162 if (Is_block(buffer
)) {
163 int n
= Int_val (Field(buffer
,1));
164 if (n
>= GL_AUX_BUFFERS
)
165 ml_raise_gl ("GlFunc.draw_buffer : no such auxiliary buffer");
166 glDrawBuffer (GL_AUX0
+ n
);
168 else glDrawBuffer (GLenum_val(buffer
));
172 ML_4 (glDrawPixels
, Int_val
, Int_val
, GLenum_val
, Type_void_raw
)
174 ML_1 (glEdgeFlag
, Int_val
)
175 ML_1 (glEnable
, GLenum_val
)
177 ML_1 (glEvalCoord1d
, Double_val
)
178 ML_2 (glEvalCoord2d
, Double_val
, Double_val
)
179 ML_3 (glEvalMesh1
, GLenum_val
, Int_val
, Int_val
)
180 ML_5 (glEvalMesh2
, GLenum_val
, Int_val
, Int_val
, Int_val
, Int_val
)
181 ML_1 (glEvalPoint1
, Int_val
)
182 ML_2 (glEvalPoint2
, Int_val
, Int_val
)
185 ML_3 (glFeedbackBuffer
, Int_val
, GLenum_val
, (GLfloat
*)Addr_raw
)
187 CAMLprim value
ml_glFog (value param
) /* ML */
192 switch (Field(param
,0))
195 glFogi(GL_FOG_MODE
, GLenum_val(Field(param
,1)));
198 glFogf(GL_FOG_DENSITY
, Float_val(Field(param
,1)));
201 glFogf(GL_FOG_START
, Float_val(Field(param
,1)));
204 glFogf(GL_FOG_END
, Float_val(Field(param
,1)));
207 glFogf(GL_FOG_INDEX
, Float_val(Field(param
,1)));
210 for (i
= 0; i
< 4; i
++) params
[i
] = Float_val(Field(Field(param
,1),i
));
211 glFogfv(GL_FOG_COLOR
, params
);
219 ML_1 (glFrontFace
, GLenum_val
)
220 ML_3 (glFrustum
, Pair(arg1
,Double_val
,Double_val
),
221 Pair(arg2
,Double_val
,Double_val
), Pair(arg3
,Double_val
,Double_val
))
223 ML_1_ (glGetString
, GLenum_val
, copy_string_check
)
224 ML_2 (glGetDoublev
, GLenum_val
, Double_raw
)
226 CAMLprim value
ml_glGetError(value unit
)
228 switch (glGetError()) {
229 case GL_NO_ERROR
: return MLTAG_no_error
;
230 case GL_INVALID_ENUM
: return MLTAG_invalid_enum
;
231 case GL_INVALID_VALUE
: return MLTAG_invalid_value
;
232 case GL_INVALID_OPERATION
: return MLTAG_invalid_operation
;
233 case GL_STACK_OVERFLOW
: return MLTAG_stack_overflow
;
234 case GL_STACK_UNDERFLOW
: return MLTAG_stack_underflow
;
235 case GL_OUT_OF_MEMORY
: return MLTAG_out_of_memory
;
236 #if defined(GL_VERSION_1_2) || defined(GL_TABLE_TOO_LARGE)
237 case GL_TABLE_TOO_LARGE
: return MLTAG_table_too_large
;
239 default: ml_raise_gl("glGetError: unknown error");
243 CAMLprim value
ml_glHint (value target
, value hint
)
248 case MLTAG_fog
: targ
= GL_FOG_HINT
; break;
249 case MLTAG_line_smooth
: targ
= GL_LINE_SMOOTH_HINT
; break;
250 case MLTAG_perspective_correction
:
251 targ
= GL_PERSPECTIVE_CORRECTION_HINT
; break;
252 case MLTAG_point_smooth
: targ
= GL_POINT_SMOOTH_HINT
; break;
253 case MLTAG_polygon_smooth
: targ
= GL_POLYGON_SMOOTH_HINT
; break;
255 glHint (targ
, GLenum_val(hint
));
259 ML_1 (glIndexMask
, Int_val
)
260 ML_1 (glIndexd
, Double_val
)
262 ML_1_ (glIsEnabled
, GLenum_val
, Val_int
)
264 CAMLprim value
ml_glLight (value n
, value param
) /* ML */
269 if (Int_val(n
) >= GL_MAX_LIGHTS
) caml_invalid_argument ("Gl.light");
270 switch (Field(param
,0))
276 for (i
= 0; i
< 4; i
++)
277 params
[i
] = Float_val (Field(Field(param
, 1), i
));
279 case MLTAG_spot_direction
:
280 for (i
= 0; i
< 3; i
++)
281 params
[i
] = Float_val (Field(Field(param
, 1), i
));
284 params
[0] = Float_val (Field(param
, 1));
286 glLightfv (GL_LIGHT0
+ Int_val(n
), GLenum_val(Field(param
,0)), params
);
290 CAMLprim value
ml_glLightModel (value param
) /* ML */
295 switch (Field(param
,0))
298 for (i
= 0; i
< 4; i
++)
299 params
[i
] = Float_val (Field(Field(param
,1),i
));
300 glLightModelfv (GL_LIGHT_MODEL_AMBIENT
, params
);
302 case MLTAG_local_viewer
:
303 glLightModelf (GL_LIGHT_MODEL_LOCAL_VIEWER
,
304 Int_val(Field(param
,1)));
307 glLightModeli (GL_LIGHT_MODEL_TWO_SIDE
,
308 Int_val(Field(param
,1)));
310 case MLTAG_color_control
:
311 #ifdef GL_VERSION_1_2
312 switch (Field(param
,1))
314 case MLTAG_separate_specular_color
:
315 glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL
,
316 GL_SEPARATE_SPECULAR_COLOR
);
318 case MLTAG_single_color
:
319 glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL
,
324 ml_raise_gl ("Parameter: GL_LIGHT_MODEL_COLOR_CONTROL not available");
331 ML_1 (glLineWidth
, Float_val
)
332 ML_2 (glLineStipple
, Int_val
, Int_val
)
333 ML_1 (glLoadName
, Int_val
)
334 ML_0 (glLoadIdentity
)
335 ML_1 (glLoadMatrixd
, Double_raw
)
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_1 (glMultMatrixd
, Double_raw
)
441 #ifdef GL_VERSION_1_3
442 ML_1 (glMultTransposeMatrixd
, Double_raw
)
444 CAMLprim
void ml_glMultTransposeMatrixd (value raw
)
446 ml_raise_gl ("Function: glMultTransposeMatrixd not available");
450 ML_3 (glNormal3d
, Double_val
, Double_val
, Double_val
)
452 ML_1 (glPassThrough
, Float_val
)
454 CAMLprim value
ml_glPixelMapfv (value map
, value raw
)
456 glPixelMapfv (GLenum_val(map
), Int_val(Size_raw(raw
))/sizeof(GLfloat
),
461 ML_3 (glOrtho
, Pair(arg1
,Double_val
,Double_val
),
462 Pair(arg2
,Double_val
,Double_val
), Pair(arg3
,Double_val
,Double_val
))
464 ML_1 (glPixelStorei
, Pair(arg1
,GLenum_val
,Int_val
))
466 CAMLprim value
ml_glPixelTransfer (value param
)
468 GLenum pname
= GLenum_val (Field(param
,0));
474 case GL_INDEX_OFFSET
:
475 glPixelTransferi (pname
, Int_val (Field(param
,1)));
478 glPixelTransferf (pname
, Float_val (Field(param
,1)));
483 ML_2 (glPixelZoom
, Float_val
, Float_val
)
484 ML_1 (glPointSize
, Float_val
)
485 ML_2 (glPolygonOffset
, Float_val
, Float_val
)
486 ML_2 (glPolygonMode
, GLenum_val
, GLenum_val
)
487 ML_1 (glPolygonStipple
, (unsigned char *)Byte_raw
)
492 CAMLprim value
ml_glPushAttrib (value list
)
496 while (list
!= Val_int(0)) {
497 switch (Field(list
,0)) {
498 case MLTAG_accum_buffer
:mask
|= GL_ACCUM_BUFFER_BIT
; break;
499 case MLTAG_color_buffer
:mask
|= GL_COLOR_BUFFER_BIT
; break;
500 case MLTAG_current
: mask
|= GL_CURRENT_BIT
; break;
501 case MLTAG_depth_buffer
:mask
|= GL_DEPTH_BUFFER_BIT
; break;
502 case MLTAG_enable
: mask
|= GL_ENABLE_BIT
; break;
503 case MLTAG_eval
: mask
|= GL_EVAL_BIT
; break;
504 case MLTAG_fog
: mask
|= GL_FOG_BIT
; break;
505 case MLTAG_hint
: mask
|= GL_HINT_BIT
; break;
506 case MLTAG_lighting
: mask
|= GL_LIGHTING_BIT
; break;
507 case MLTAG_line
: mask
|= GL_LINE_BIT
; break;
508 case MLTAG_list
: mask
|= GL_LIST_BIT
; break;
509 case MLTAG_pixel_mode
: mask
|= GL_PIXEL_MODE_BIT
; break;
510 case MLTAG_point
: mask
|= GL_POINT_BIT
; break;
511 case MLTAG_polygon
: mask
|= GL_POLYGON_BIT
; break;
512 case MLTAG_polygon_stipple
:mask
|= GL_POLYGON_STIPPLE_BIT
; break;
513 case MLTAG_scissor
: mask
|= GL_SCISSOR_BIT
; break;
514 case MLTAG_stencil_buffer
:mask
|= GL_STENCIL_BUFFER_BIT
; break;
515 case MLTAG_texture
: mask
|= GL_TEXTURE_BIT
; break;
516 case MLTAG_transform
: mask
|= GL_TRANSFORM_BIT
; break;
517 case MLTAG_viewport
: mask
|= GL_VIEWPORT_BIT
; break;
519 list
= Field(list
,1);
526 ML_1 (glPushName
, Int_val
)
528 CAMLprim value
ml_glRasterPos(value x
, value y
, value z
, value w
) /* ML */
530 if (z
== Val_int(0)) glRasterPos2d (Double_val(x
), Double_val(y
));
531 else if (w
== Val_int(0))
532 glRasterPos3d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)));
534 glRasterPos4d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)),
535 Double_val(Field(w
, 0)));
539 CAMLprim value
ml_glReadBuffer (value buffer
)
541 if (Is_block(buffer
)) {
542 int n
= Int_val (Field(buffer
,1));
543 if (n
>= GL_AUX_BUFFERS
)
544 ml_raise_gl ("GlFunc.read_buffer : no such auxiliary buffer");
545 glReadBuffer (GL_AUX0
+ n
);
547 else glReadBuffer (GLenum_val(buffer
));
551 CAMLprim value
ml_glReadPixels(value x
, value y
, value w
, value h
, value format
, value raw
) /* ML */
553 glPixelStorei(GL_PACK_SWAP_BYTES
, 0);
554 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
555 glReadPixels(Int_val(x
),Int_val(y
),Int_val(w
),Int_val(h
),GLenum_val(format
),
560 ML_bc6 (ml_glReadPixels
)
561 ML_2 (glRectd
, Pair(arg1
,Double_val
,Double_val
),
562 Pair(arg2
,Double_val
,Double_val
))
563 ML_1_ (glRenderMode
, GLenum_val
, Val_int
)
564 ML_4 (glRotated
, Double_val
, Double_val
, Double_val
, Double_val
)
565 ML_3 (glScaled
, Double_val
, Double_val
, Double_val
)
567 ML_4 (glScissor
, Int_val
, Int_val
, Int_val
, Int_val
)
568 ML_2 (glSelectBuffer
, Int_val
, (GLuint
*)Addr_raw
)
569 ML_1 (glShadeModel
, GLenum_val
)
570 ML_3 (glStencilFunc
, GLenum_val
, Int_val
, Int_val
)
571 ML_1 (glStencilMask
, Int_val
)
572 ML_3 (glStencilOp
, GLenum_val
, GLenum_val
, GLenum_val
)
574 ML_1 (glTexCoord1d
, Double_val
)
575 ML_2 (glTexCoord2d
, Double_val
, Double_val
)
576 ML_3 (glTexCoord3d
, Double_val
, Double_val
, Double_val
)
577 ML_4 (glTexCoord4d
, Double_val
, Double_val
, Double_val
, Double_val
)
579 CAMLprim value
ml_glTexEnv (value param
)
581 value params
= Field(param
,1);
585 switch (Field(param
,0)) {
587 glTexEnvi (GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GLenum_val(params
));
590 for (i
= 0; i
< 4; i
++) color
[i
] = Float_val(Field(params
,i
));
591 glTexEnvfv (GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, color
);
597 CAMLprim value
ml_glTexGen (value coord
, value param
)
599 value params
= Field(param
,1);
603 if (Field(param
,0) == MLTAG_mode
)
604 glTexGeni (GLenum_val(coord
), GL_TEXTURE_GEN_MODE
, GLenum_val(params
));
606 for (i
= 0; i
< 4; i
++) point
[i
] = Double_val(Field(params
,i
));
607 glTexGendv (GLenum_val(coord
), GLenum_val(Field(param
,0)), point
);
612 CAMLprim value
ml_glTexImage1D (value proxy
, value level
, value internal
,
613 value width
, value border
, value format
,
616 glTexImage1D (proxy
== Val_int(1)
617 ? GL_PROXY_TEXTURE_1D
: GL_TEXTURE_1D
,
618 Int_val(level
), Int_val(internal
), Int_val(width
),
619 Int_val(border
), GLenum_val(format
),
620 Type_raw(data
), Void_raw(data
));
624 ML_bc7 (ml_glTexImage1D
)
626 CAMLprim value
ml_glTexImage2D (value proxy
, value level
, value internal
,
627 value width
, value height
, value border
,
628 value format
, value data
)
630 /* printf("p=%x,l=%d,i=%d,w=%d,h=%d,b=%d,f=%x,t=%x,d=%x\n", */
631 glTexImage2D (proxy
== Val_int(1)
632 ? GL_PROXY_TEXTURE_2D
: GL_TEXTURE_2D
,
633 Int_val(level
), Int_val(internal
), Int_val(width
),
634 Int_val(height
), Int_val(border
), GLenum_val(format
),
635 Type_raw(data
), Void_raw(data
));
640 ML_bc8 (ml_glTexImage2D
)
642 CAMLprim value
ml_glTexParameter (value target
, value param
)
644 GLenum targ
= GLenum_val(target
);
645 GLenum pname
= GLenum_val(Field(param
,0));
646 value params
= Field(param
,1);
651 case GL_TEXTURE_BORDER_COLOR
:
652 for (i
= 0; i
< 4; i
++) color
[i
] = Float_val(Field(params
,i
));
653 glTexParameterfv (targ
, pname
, color
);
655 case GL_TEXTURE_PRIORITY
:
656 glTexParameterf (targ
, pname
, Float_val(params
));
658 case GL_GENERATE_MIPMAP
:
659 #ifdef GL_VERSION_1_4
660 glTexParameteri (targ
, pname
, Int_val(params
));
662 ml_raise_gl ("Parameter: GL_GENERATE_MIPMAP not available");
666 glTexParameteri (targ
, pname
, GLenum_val(params
));
672 ML_2 (glGenTextures
, Int_val
, Int_raw
)
673 ML_2 (glBindTexture
, GLenum_val
, Nativeint_val
)
675 CAMLprim value
ml_glDeleteTexture (value texture_id
)
677 GLuint id
= Nativeint_val(texture_id
);
678 glDeleteTextures(1,&id
);
682 ML_3 (glTranslated
, Double_val
, Double_val
, Double_val
)
684 CAMLprim value
ml_glVertex(value x
, value y
, value z
, value w
) /* ML */
686 if (z
== Val_int(0)) glVertex2d (Double_val(x
), Double_val(y
));
687 else if (w
== Val_int(0))
688 glVertex3d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)));
690 glVertex4d (Double_val(x
), Double_val(y
), Double_val(Field(z
, 0)),
691 Double_val(Field(w
, 0)));
695 ML_4 (glViewport
, Int_val
, Int_val
, Int_val
, Int_val
)
700 ML_1_ (glIsList
, Int_val
, Val_int
)
701 ML_2 (glDeleteLists
, Int_val
, Int_val
)
702 ML_1_ (glGenLists
, Int_val
, Val_int
)
703 ML_2 (glNewList
, Int_val
, GLenum_val
)
705 ML_1 (glCallList
, Int_val
)
706 ML_1 (glListBase
, Int_val
)
708 CAMLprim value
ml_glCallLists (value indexes
) /* ML */
713 switch (Field(indexes
,0)) {
715 glCallLists (caml_string_length(Field(indexes
,1)),
717 String_val(Field(indexes
,1)));
720 len
= Wosize_val (indexes
);
721 table
= calloc (len
, sizeof (GLint
));
722 for (i
= 0; i
< len
; i
++) table
[i
] = Int_val (Field(indexes
,i
));
723 glCallLists (len
, GL_INT
, table
);