#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 PROTOTYPES: DISABLE void glAccum(GLenum op, GLfloat value); void glAlphaFunc(GLenum func, GLclampf ref); void glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); void glClearIndex( GLfloat c ); void glClearStencil( GLint s ); void glEdgeFlag( GLboolean flag ); void glFogf( GLenum pname, GLfloat param); void glFogi( GLenum pname, GLint param); void glFog(...) CODE: if (2>items) { croak("Usage: glFog(pname, param)"); } if (GL_FOG_COLOR==SvIV(ST(0))) { if (5!=items) { croak("Usage: glFog(GL_FOG_COLOR,@color)"); } else { GLfloat col[4]; int i; for (i=0;i<4;i++) { col[i] = (GLfloat) SvNV(ST(1+i)); } glFogfv(GL_FOG_COLOR,col); } } else if (2==items) { glFogf(SvIV(ST(0)),(GLfloat)SvNV(ST(1))); } else { croak("Usage: glFog(pname, param)"); } void glIndexMask( GLuint mask); void glInitNames(); GLboolean glIsEnabled( GLenum cap ); void glLoadName( GLuint name ); void glPassThrough( GLfloat token ); void glPushName( GLuint name ); void glPopName(); GLint glRenderMode( GLenum mode ); void glScissor( GLint x, GLint y, GLsizei width, GLsizei height); void glStencilFunc( GLenum func, GLint ref, GLuint mask); void glStencilOp( GLenum fail, GLenum zfail, GLenum zpass); const 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 glClipPlane(...) PREINIT: GLenum plane; GLdouble equation[4]; CODE: if ((2==items) && (SvROK(ST(1)) && (SVt_PVAV == SvTYPE(SvRV(ST(1))))) ) { /* Two items, of which the second is an array ref. */ AV *array; int i; array =(AV *) SvRV(ST(1)); if (3!=av_len(array)) { croak("glClipPlane($scalar,\\@array)" "should be passed an array of " "exactly 4 elements, not %d.", 1+av_len(array)); } plane = (GLenum) SvIV(ST(0)); for (i=0;i<4;i++) { SV **svp; svp = av_fetch(array,i,0); equation[i] = (GLdouble) SvNV(*svp); } } else if (5==items) { /* assume args are (plane,a,b,c,d). */ int i; plane = (GLenum) SvIV(ST(0)); for (i=0;i<4;i++) { equation[i] = (GLdouble) SvNV(ST(1+i)); } } else { croak("Usage: glClipPlane($plane,\\@equation)"); } /* plane and equation[] are defined. */ glClipPlane(plane,equation); void glGetClipPlane(...) PREINIT: GLdouble equation[4]; int i; PPCODE: if (1==items) { /* Dump everything on the stack */ glGetClipPlane(SvIV(ST(0)),equation); EXTEND(sp,4); for (i=0;i<4;i++) { PUSHs(sv_2mortal(newSVnv(equation[i]))); } } else if (2==items) { /* Write through supplied array reference */ if ( (SvROK(ST(1))) &&(SVt_PVAV==SvTYPE(SvRV(ST(1)))) ) { AV *array=(AV *)SvRV(ST(1)); glGetClipPlane(SvIV(ST(0)),equation); for (i=0;i<4;i++) { av_store(array,i,newSVnv(equation[i])); } } } else { /* Your what's itchy? */ croak("glGetClipPlane() takes either one or two arguments."); } 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 glPushAttrib( GLbitfield mask); void glPopAttrib(); void glRotate(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) CODE: glRotated(angle,x,y,z); void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void glTranslate(GLfloat x, GLfloat y, GLfloat z) CODE: glTranslated(x,y,z); void glTranslatef(GLfloat x, GLfloat y, GLfloat z); void glTranslated(GLdouble x, GLdouble y, GLdouble 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 glCallLists(...) CODE: if (3==items) { /* Do it the clunky C-like way */ glCallLists( (GLsizei)SvIV(ST(0)), (GLenum)SvIV(ST(1)), (const GLvoid *)SvPV_nolen(ST(2)) ); } else if (1==items) { /* Do it the nice perl way */ int *lists=NULL; AV *array=NULL; GLsizei i,n=0; if (SVt_PVAV != SvTYPE(SvRV(ST(0)))) { croak("Must have array reference"); } array = (AV *)SvRV(ST(0)); n=1+av_len(array); if (NULL==(lists=malloc(sizeof(int)*n))) { croak("glCallLists: malloc failed"); } 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 realglTexSubImage2D( GLenum target,GLint level,GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 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); glTexSubImage2D( target,level, xoffset,yoffset, width,height, format,type,data ); void realglPolygonStipple( SV *pixels ) PREINIT: SV *pixdatasv; GLubyte *data; size_t plen; CODE: if (!SvPOK(pixels)) { croak("not a pointer value.."); } if (128 > SvLEN(pixels)) { croak("\"pixels\" should be 128 bytes (32x32 bits)."); } data=SvPV_nolen(pixels); glPolygonStipple(data); void realglReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,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); glReadPixels(x,y,width,height,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 glPixelStoref(GLenum pname, GLfloat param ); void glPixelTransferi(GLenum pname, GLint param); void glPixelTransferf(GLenum pname, GLfloat 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()"); } GLenum glGetError(); # ################ 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 ); const GLubyte *gluErrorString(GLenum error);