#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifndef PERL_DARWIN #include #include #else #include #include #endif /* DARWIN */ #include "const-c.inc" /* Datatype to represent what glGet() can return: * BOOL1 = single boolean, INT2 = two integers, etc. */ enum toygl_rtype { BOOL, INT, FLOAT }; typedef enum toygl_rtype toygl_rtype; MODULE = OpenGL::Simple PACKAGE = OpenGL::Simple INCLUDE: const-xs.inc GLubyte *glGetString (GLenum name); void glBegin(GLenum mode); void glEnd(); void glEnable(GLenum cap); void glDisable (GLenum cap); void glFinish(); void glFlush(); void glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void glClear(GLbitfield mask); void glClearDepth(GLclampd depth); void glLoadIdentity(); void glMatrixMode(GLenum mode); void glLoadMatrix(...) PREINIT: GLdouble m[16]; int i; CODE: if (16!=items) { croak("glMatrixMode takes a 16-element array"); } else { /* Copy arguments into matrix */ for (i=0;i<16;i++) { m[i] = SvNV(ST(i)); } glLoadMatrixd(m); } void glMultMatrix(...) PREINIT: GLdouble m[16]; int i; CODE: if (16!=items) { croak( "glMultMatrix takes a 16-element array"); } else { /* Copy arguments into matrix */ for (i=0;i<16;i++) { m[i] = SvNV(ST(i)); } glMultMatrixd(m); } void glPushMatrix(); void glPopMatrix(); void glRotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) CODE: glRotated(angle,x,y,z); void glTranslate(GLdouble x, GLdouble y, GLdouble z) CODE: glTranslated(x,y,z); void glScale(GLdouble x, GLdouble y, GLdouble z) CODE: glScaled(x,y,z); void glRect(...) CODE: if (4!=items) { croak("glRect() takes 4 arguments, not %d",items); } glRectd( SvNV(ST(0)), SvNV(ST(1)), SvNV(ST(2)), SvNV(ST(3)) ); void glVertex2d (GLdouble x, GLdouble y); void glVertex2f (GLfloat x, GLfloat y); void glVertex2i (GLint x, GLint y); void glVertex2s (GLshort x, GLshort y); void glVertex3d (GLdouble x, GLdouble y, GLdouble z); void glVertex3f (GLfloat x, GLfloat y, GLfloat z); void glVertex3i (GLint x, GLint y, GLint z); void glVertex3s (GLshort x, GLshort y, GLshort z); void glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); void glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); void glVertex4i (GLint x, GLint y, GLint z, GLint w); # All-in-one easy-to-use shrink-to-fit version void glVertex(...) CODE: switch(items) { case 2: glVertex2d( SvNV(ST(0)),SvNV(ST(1)) ); break; case 3: glVertex3d( SvNV(ST(0)), SvNV(ST(1)), SvNV(ST(2)) ); break; case 4: glVertex4d( SvNV(ST(0)), SvNV(ST(1)), SvNV(ST(2)), SvNV(ST(3)) ); break; default: croak("glVertex() takes 2,3, or 4 arguments"); } void glNormal(GLdouble x, GLdouble y, GLdouble z) CODE: glNormal3d(x,y,z); void glNewList(GLuint list, GLenum mode); void glEndList(); void glCallList(GLuint list); void glIsList(GLuint list); GLuint glGenLists(GLsizei range); void glDeleteLists(GLuint list, GLsizei range); void glColor(...) CODE: switch(items) { case 3: glColor3d( SvNV(ST(0)), SvNV(ST(1)), SvNV(ST(2)) ); break; case 4: glColor4d( SvNV(ST(0)), SvNV(ST(1)), SvNV(ST(2)), SvNV(ST(3)) ); break; default: croak("glColor() takes 3 or 4 arguments"); } void glColorMaterial(GLenum face, GLenum mode); void glMaterial(GLenum face, GLenum pname, GLenum param) CODE: glMaterialf(face,pname,param); void glLightModel(...) PREINIT: GLenum pname; char *badargno="Bad number of arguments to glLightModel()"; CODE: if ( (2!=items) && (5!=items) ) { croak(badargno); } else { pname = (GLenum) SvIV(ST(0)); } switch(pname) { case GL_LIGHT_MODEL_LOCAL_VIEWER: case GL_LIGHT_MODEL_TWO_SIDE: if (2!=items) { croak(badargno); } glLightModelf(pname,SvNV(ST(1))); break; case GL_LIGHT_MODEL_AMBIENT: if (5!=items) { croak(badargno); } { GLfloat a[4]; int i; for (i=0;i<4;i++) { a[i] = SvNV(ST(i+1)); } glLightModelfv(pname,a); } break; default: croak("Bad pname passed to glLightModel()"); } void glLight(...) PREINIT: char *badargno="Bad number of arguments to glLightModel()"; GLenum light,pname; GLfloat a[4]; int i; CODE: if (items <= 2) { croak(badargno); } else { light = (GLenum) SvIV(ST(0)); pname = (GLenum) SvIV(ST(1)); } switch(pname) { case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION: /* Pop four further args off the stack */ if (6!=items) { croak(badargno); } for (i=0;i<4;i++) { a[i] = SvNV(ST(i+2)); } glLightfv(light,pname,a); break; case GL_SPOT_DIRECTION: /* Pop three further args off the stack */ if (5!=items) { croak(badargno); } for (i=0;i<3;i++) { a[i] = SvNV(ST(i+2)); } glLightfv(light,pname,a); break; case GL_SPOT_EXPONENT: case GL_SPOT_CUTOFF: case GL_CONSTANT_ATTENUATION: case GL_LINEAR_ATTENUATION: case GL_QUADRATIC_ATTENUATION: /* Just the one argument */ glLightf(light,pname,SvNV(ST(2))); break; default: croak("Bad pname passed to glLight()"); } void glShadeModel(GLenum mode); void glCullFace(GLenum mode); void glDepthFunc(GLenum func); void glDepthMask(GLboolean flag); void glDepthRange(GLclampd near, GLclampd far); void glPolygonMode( GLenum face, GLenum mode ); void glPolygonOffset( GLfloat factor, GLfloat units ); void glViewport( GLint x, GLint y, GLsizei width, GLsizei height ); void glBlendFunc( GLenum sfactor, GLenum dfactor); void glHint(GLenum target, GLenum mode); void glLineWidth(GLfloat width); void glPointSize( GLfloat size ); void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar ); void glFrontFace( GLenum mode ); void glGet(...) PREINIT: toygl_rtype rtype; GLenum pname; /* Dunno if this should really be allocated on the stack. */ GLdouble doublearr[16]; GLint intarr[4]; GLboolean boolarr[4]; int nvals; /* No of values returned by glGet() */ PPCODE: if ( (1!=items) && (2!=items) ) { croak("glGet() requires 1 or 2 arguments"); } if ( (2==items) && (!SvROK(ST(1))) ) { croak("Second argument to glGet() must be reference"); } pname = SvIV(ST(0)); /* Determine from the pname argument what glGet() is * going to hand us back. */ switch(pname) { case GL_ALPHA_TEST: case GL_AUTO_NORMAL: case GL_BLEND: case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: case GL_CLIP_PLANE2: case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: case GL_COLOR_ARRAY: case GL_COLOR_LOGIC_OP: case GL_COLOR_MATERIAL: case GL_CULL_FACE: case GL_CURRENT_RASTER_POSITION_VALID: case GL_DEPTH_TEST: case GL_DEPTH_WRITEMASK: case GL_DITHER: case GL_DOUBLEBUFFER: case GL_EDGE_FLAG: case GL_EDGE_FLAG_ARRAY: case GL_FOG: case GL_INDEX_ARRAY: case GL_INDEX_LOGIC_OP: case GL_INDEX_MODE: case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: case GL_LIGHT3: case GL_LIGHT4: case GL_LIGHTING: case GL_LIGHT_MODEL_LOCAL_VIEWER: case GL_LIGHT_MODEL_TWO_SIDE: case GL_LINE_SMOOTH: case GL_LINE_STIPPLE: case GL_MAP1_COLOR_4: case GL_MAP1_INDEX: case GL_MAP1_NORMAL: case GL_MAP1_TEXTURE_COORD_1: case GL_MAP1_TEXTURE_COORD_2: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP1_VERTEX_3: case GL_MAP1_VERTEX_4: case GL_MAP2_COLOR_4: case GL_MAP2_INDEX: case GL_MAP2_NORMAL: case GL_MAP2_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_TEXTURE_COORD_4: case GL_MAP2_VERTEX_3: case GL_MAP2_VERTEX_4: case GL_MAP_COLOR: case GL_MAP_STENCIL: case GL_NORMAL_ARRAY: case GL_NORMALIZE: case GL_PACK_LSB_FIRST: case GL_PACK_SWAP_BYTES: case GL_POINT_SMOOTH: case GL_POLYGON_OFFSET_FILL: case GL_POLYGON_OFFSET_LINE: case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_SMOOTH: case GL_POLYGON_STIPPLE: case GL_RGBA_MODE: case GL_SCISSOR_TEST: case GL_STENCIL_TEST: case GL_STEREO: case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_COORD_ARRAY: case GL_TEXTURE_GEN_Q: case GL_TEXTURE_GEN_R: case GL_TEXTURE_GEN_S: case GL_TEXTURE_GEN_T: case GL_UNPACK_LSB_FIRST: case GL_UNPACK_SWAP_BYTES: case GL_VERTEX_ARRAY: rtype = BOOL; nvals = 1; break; case GL_COLOR_WRITEMASK: rtype = BOOL; nvals = 4; break; case GL_ACCUM_ALPHA_BITS: case GL_ACCUM_BLUE_BITS: case GL_ACCUM_GREEN_BITS: case GL_ACCUM_RED_BITS : case GL_ALPHA_BITS: case GL_ALPHA_TEST_FUNC: case GL_ATTRIB_STACK_DEPTH: case GL_AUX_BUFFERS: case GL_BLEND_DST: case GL_BLEND_SRC: case GL_CLIENT_ATTRIB_STACK_DEPTH: case GL_COLOR_ARRAY_SIZE: case GL_COLOR_ARRAY_STRIDE: case GL_COLOR_ARRAY_TYPE: case GL_COLOR_MATERIAL_FACE: case GL_COLOR_MATERIAL_PARAMETER: case GL_CULL_FACE_MODE: case GL_CURRENT_INDEX: case GL_CURRENT_RASTER_INDEX: case GL_DEPTH_BITS: case GL_DEPTH_FUNC: case GL_DRAW_BUFFER: case GL_EDGE_FLAG_ARRAY_STRIDE: case GL_FOG_HINT: case GL_FOG_INDEX: case GL_FOG_MODE: case GL_FRONT_FACE: case GL_GREEN_BITS: case GL_INDEX_ARRAY_STRIDE: case GL_INDEX_ARRAY_TYPE: case GL_INDEX_BITS: case GL_INDEX_CLEAR_VALUE: case GL_INDEX_OFFSET: case GL_INDEX_SHIFT: case GL_INDEX_WRITEMASK: case GL_LINE_SMOOTH_HINT: case GL_LINE_STIPPLE_PATTERN: case GL_LINE_STIPPLE_REPEAT: case GL_LIST_BASE: case GL_LIST_INDEX: case GL_LIST_MODE: case GL_LOGIC_OP_MODE: case GL_MAP1_GRID_SEGMENTS: case GL_MATRIX_MODE: case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: case GL_MAX_ATTRIB_STACK_DEPTH: case GL_MAX_CLIP_PLANES: case GL_MAX_EVAL_ORDER: case GL_MAX_LIGHTS: case GL_MAX_LIST_NESTING: case GL_MAX_MODELVIEW_STACK_DEPTH: case GL_MAX_NAME_STACK_DEPTH: case GL_MAX_PIXEL_MAP_TABLE: case GL_MAX_PROJECTION_STACK_DEPTH: case GL_MAX_TEXTURE_SIZE: case GL_MAX_TEXTURE_STACK_DEPTH: case GL_MODELVIEW_STACK_DEPTH: case GL_NAME_STACK_DEPTH: case GL_NORMAL_ARRAY_STRIDE: case GL_NORMAL_ARRAY_TYPE: case GL_PACK_ALIGNMENT: case GL_PACK_ROW_LENGTH: case GL_PACK_SKIP_PIXELS: case GL_PACK_SKIP_ROWS: case GL_PERSPECTIVE_CORRECTION_HINT: case GL_PIXEL_MAP_A_TO_A_SIZE: case GL_PIXEL_MAP_B_TO_B_SIZE: case GL_PIXEL_MAP_G_TO_G_SIZE: case GL_PIXEL_MAP_I_TO_A_SIZE: case GL_PIXEL_MAP_I_TO_B_SIZE: case GL_PIXEL_MAP_I_TO_G_SIZE: case GL_PIXEL_MAP_I_TO_I_SIZE: case GL_PIXEL_MAP_I_TO_R_SIZE: case GL_PIXEL_MAP_R_TO_R_SIZE: case GL_PIXEL_MAP_S_TO_S_SIZE: case GL_POINT_SMOOTH_HINT: case GL_POLYGON_SMOOTH_HINT: case GL_PROJECTION_STACK_DEPTH: case GL_READ_BUFFER: case GL_RED_BITS: case GL_RENDER_MODE: case GL_SHADE_MODEL: case GL_STENCIL_BITS: case GL_STENCIL_CLEAR_VALUE: case GL_STENCIL_FAIL: case GL_STENCIL_FUNC: case GL_STENCIL_PASS_DEPTH_FAIL: case GL_STENCIL_PASS_DEPTH_PASS: case GL_STENCIL_REF: case GL_STENCIL_VALUE_MASK: case GL_STENCIL_WRITEMASK: case GL_SUBPIXEL_BITS: /* * These are defined as GL_TEXTURE_nD_BINDING_EXT * in my nvidia headers. Need to work it out * on the fly, I guess. case GL_TEXTURE_1D_BINDING: case GL_TEXTURE_2D_BINDING: */ case GL_TEXTURE_COORD_ARRAY_SIZE: case GL_TEXTURE_COORD_ARRAY_STRIDE: case GL_TEXTURE_COORD_ARRAY_TYPE: case GL_TEXTURE_STACK_DEPTH: case GL_UNPACK_ALIGNMENT: case GL_UNPACK_ROW_LENGTH: case GL_UNPACK_SKIP_PIXELS: case GL_UNPACK_SKIP_ROWS: case GL_VERTEX_ARRAY_SIZE: case GL_VERTEX_ARRAY_STRIDE: case GL_VERTEX_ARRAY_TYPE: rtype = INT; nvals = 1; break; case GL_MAP2_GRID_SEGMENTS: case GL_MAX_VIEWPORT_DIMS: case GL_POLYGON_MODE: rtype = INT; nvals = 2; break; case GL_SCISSOR_BOX: case GL_VIEWPORT: rtype = INT; nvals = 4; break; case GL_ALPHA_BIAS : case GL_ALPHA_SCALE: case GL_ALPHA_TEST_REF: case GL_BLUE_BIAS: case GL_BLUE_BITS: case GL_BLUE_SCALE: case GL_CURRENT_RASTER_DISTANCE: case GL_DEPTH_BIAS: case GL_DEPTH_CLEAR_VALUE: case GL_DEPTH_SCALE: case GL_FOG_DENSITY: case GL_FOG_END: case GL_FOG_START: case GL_GREEN_SCALE: case GL_GREEN_BIAS: case GL_LINE_WIDTH: case GL_LINE_WIDTH_GRANULARITY: case GL_LINE_WIDTH_RANGE: case GL_POINT_SIZE: case GL_POINT_SIZE_GRANULARITY: case GL_POLYGON_OFFSET_FACTOR: case GL_POLYGON_OFFSET_UNITS: case GL_RED_BIAS: case GL_RED_SCALE: case GL_ZOOM_X: case GL_ZOOM_Y: rtype = FLOAT; nvals = 1; break; case GL_DEPTH_RANGE: case GL_MAP1_GRID_DOMAIN: case GL_POINT_SIZE_RANGE: rtype = FLOAT; nvals = 2; break; case GL_CURRENT_NORMAL: rtype = FLOAT; nvals = 3; break; case GL_ACCUM_CLEAR_VALUE : case GL_COLOR_CLEAR_VALUE: case GL_CURRENT_COLOR: case GL_CURRENT_RASTER_COLOR: case GL_CURRENT_RASTER_POSITION: case GL_CURRENT_TEXTURE_COORDS: case GL_FOG_COLOR: case GL_LIGHT_MODEL_AMBIENT: case GL_MAP2_GRID_DOMAIN: rtype = FLOAT; nvals = 4; break; case GL_MODELVIEW_MATRIX: case GL_PROJECTION_MATRIX: case GL_TEXTURE_MATRIX: rtype = FLOAT; nvals = 16; break; default: croak("Unknown pname %d passed to glGet()", pname); } /* Now we know the return type. If necessary, check * whether the second argument, if it exists, is * a reference to the correct type */ if (2==items) { svtype reftype; reftype = SvTYPE(SvRV(ST(1))); if (1==nvals) { if (SvOK(SvRV(ST(1)))) { /* ok */ } else if (SVt_NULL==reftype) { /* ok */ } else if (SVt_PV==reftype) { /* ok */ } else { croak("Must have scalar reference"); } } else { if (SVt_PVAV != reftype) { croak("Must have array reference"); } } } /* Make the call to glGet() */ switch(rtype) { case BOOL: glGetBooleanv(pname,boolarr); break; case INT: glGetIntegerv(pname,intarr); break; case FLOAT: glGetDoublev(pname,doublearr); break; default: croak("Can't happen in rtype!"); } /* Now work out what to do with the data */ if (1==items) { int i; /* Just dump it onto the stack. */ EXTEND(sp,nvals); switch(rtype) { case BOOL: for (i=0;i\"%s\"\n",data); { unsigned char *p=data; int i; for (i=0;i<16;i++) { fprintf(stderr,"%02x",p[i]); } fprintf(stderr,"\n"); } fflush(stderr); */ glTexImage2D( target,level,internalformat, width,height,border, format,type,data ); void glDrawBuffer(GLenum mode); void glTexImage3D( GLenum target,GLint level,GLint internalformat, GLsizei width, GLsizei height,GLsizei depth, GLint border, GLenum format,GLenum type, SV *pixels ) PREINIT: SV *pixdatasv; GLvoid *data; CODE: /* Extract pixel data first */ if ( (!SvROK(pixels)) || (!SvPOK(pixdatasv=SvRV(pixels))) ) { croak("\"pixels\" should be a reference to scalar"); } data = SvPV_nolen(pixdatasv); glTexImage3D( target,level,internalformat, width,height,depth,border, format,type,data ); void glPixelStorei(GLenum pname, GLint param ); void glTexGen(...) PREINIT: char *badargno="Bad number of arguments to glTexGen()"; GLenum coord, pname; GLfloat a[4]; int i; CODE: if (items <= 2) { croak(badargno); } else { coord = (GLenum) SvIV(ST(0)); pname = (GLenum) SvIV(ST(1)); } switch(pname) { case GL_AMBIENT: /* Pop four further args off the stack */ if (6!=items) { croak(badargno); } for (i=0;i<4;i++) { a[i] = SvNV(ST(i+2)); } glTexGenfv(coord,pname,a); break; case GL_TEXTURE_GEN_MODE: /* Just the one argument */ a[0] = SvNV(ST(2)); glTexGenfv(coord,pname,a); break; default: croak("Bad pname passed to glLight()"); } # ################ GLU calls void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar); void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top ); void gluLookAt( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ );