/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.35 from the
 * contents of pogl_glu.xs. Do not edit this file, edit pogl_glu.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "pogl_glu.xs"
/*  Last saved: Wed 17 Dec 2014 03:14:02 PM */

/*  Copyright (c) 1998 Kenneth Albanowski. All rights reserved.
 *  Copyright (c) 2007 Bob Free. All rights reserved.
 *  Copyright (c) 2009 Chris Marshall. All rights reserved.
 *  Copyright (c) 2011 Paul Seamons. All rights reserved.
 *  This program is free software; you can redistribute it and/or
 *  modify it under the same terms as Perl itself.
 */

/* OpenGL GLU bindings */
#define IN_POGL_GLU_XS

#include <stdio.h>

#include "pgopogl.h"

#ifdef HAVE_GL
#include "gl_util.h"
#endif

#ifdef HAVE_GLX
#include "glx_util.h"
#endif

#ifdef HAVE_GLU
#include "glu_util.h"
#endif


#ifdef IN_POGL_GLU_XS

#ifndef CALLBACK
#define CALLBACK
#endif

struct PGLUtess {
	GLUtesselator * triangulator;
#ifdef GLU_VERSION_1_2
	SV * begin_callback;
	SV * edgeFlag_callback;
	SV * vertex_callback;
	SV * end_callback;
	SV * error_callback;
	SV * combine_callback;
#endif
        bool do_colors;
        bool do_normals;
        bool use_vertex_data;
        GLdouble * vertex_data; /* used during non-GLU_TESS_VERTEX_DATA */
	SV * polygon_data;
	AV * vertex_datas;
	AV * tess_datas;
};

typedef struct PGLUtess PGLUtess;

#define delete_vertex_datas() \
		if (tess->vertex_datas) {                    \
                  AV * vds = tess->vertex_datas;             \
                  SV** svp;                                  \
                  I32 i;                                     \
                  for (i=0; i<=av_len(vds); i++) {           \
                    svp = av_fetch(vds, i, FALSE);           \
                    free(INT2PTR(GLdouble*, SvIV(*svp)));    \
                  }                                          \
                  SvREFCNT_dec(tess->vertex_datas);          \
                  tess->vertex_datas = 0;                    \
                }

#define delete_tess_datas() \
		if (tess->tess_datas) {                      \
                  AV * tds = tess->tess_datas;               \
                  SV** svp;                                  \
                  I32 i;                                     \
                  for (i=0; i<=av_len(tds); i++) {           \
                    svp = av_fetch(tds, i, FALSE);           \
                    free(INT2PTR(PGLUtess*, SvIV(*svp)));    \
                  }                                          \
                  SvREFCNT_dec(tess->tess_datas);            \
                  tess->tess_datas = 0;                      \
                }

#define delete_polygon_data()                             \
		if (tess->polygon_data) {                 \
			SvREFCNT_dec(tess->polygon_data); \
			tess->polygon_data = 0;           \
		}



#ifdef GLU_VERSION_1_2


/* Begin a named callback handler */
#define begin_tess_marshaller(name, type, params, croak_msg, default_handler) \
void CALLBACK _s_marshal_glu_t_callback_ ## name params			\
{                                                                       \
    dSP;                                                                \
    int i; int j = 3;                                                   \
    PGLUtess * t = (PGLUtess*)gl_polygon_data;                          \
    SV * handler = t-> type ## _callback;                               \
    if (!handler) croak(croak_msg);                                     \
    if (! SvROK(handler)) { /* default */                               \
      default_handler;                                                  \
      return;                                                           \
    }                                                                   \
    PUSHMARK(sp);

/* End a gluTess callback handler */
#define end_tess_marshaller()                                           \
	PUTBACK;                                                        \
	perl_call_sv(handler, G_DISCARD);                               \
}


/* Declare gluTess BEGIN */
begin_tess_marshaller(begin, begin, (GLenum type, void * gl_polygon_data), "Missing tess callback for begin", glBegin(type))
	XPUSHs(sv_2mortal(newSViv(type)));
end_tess_marshaller()

/* Declare gluTess BEGIN_DATA */
begin_tess_marshaller(begin_data, begin, (GLenum type, void * gl_polygon_data), "Missing tess callback for begin_data", glBegin(type))
	XPUSHs(sv_2mortal(newSViv(type)));
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
end_tess_marshaller()

/* Declare gluTess END */
begin_tess_marshaller(end, end, (void * gl_polygon_data), "Missing tess callback for end", glEnd())
end_tess_marshaller()

/* Declare gluTess END_DATA */
begin_tess_marshaller(end_data, end, (void * gl_polygon_data), "Missing tess callback for end_data", glEnd())
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
end_tess_marshaller()

/* Declare gluTess EDGEFLAG */
begin_tess_marshaller(edgeFlag, edgeFlag, (GLboolean flag, void * gl_polygon_data), "Missing tess callback for edgeFlag", glEdgeFlag(flag))
	XPUSHs(sv_2mortal(newSViv(flag)));
end_tess_marshaller()

/* Declare gluTess EDGEFLAG_DATA */
begin_tess_marshaller(edgeFlag_data, edgeFlag, (GLboolean flag, void * gl_polygon_data), "Missing tess callback for edgeFlag_data", glEdgeFlag(flag))
	XPUSHs(sv_2mortal(newSViv(flag)));
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
end_tess_marshaller()

/* Declare gluTess VERTEX */
begin_tess_marshaller(vertex, vertex, (void * gl_polygon_data), "Missing tess callback for vertex", \
                      GLdouble * vd = t->vertex_data;                                   \
                      if (t->do_colors) { \
                         glColor4f(vd[j], vd[j+1], vd[j+2], vd[j+3]); \
                         j += 4; \
                      } \
                      if (t->do_normals) glNormal3f(vd[j], vd[j+1], vd[j+2]);           \
                      glVertex3f(vd[0], vd[1], vd[2]);                                  \
                      )
{
    GLdouble * vd = (GLdouble*) t->vertex_data;
    for (i = 0; i < 3; i++)
      XPUSHs(sv_2mortal(newSVnv(vd[i])));
    if (t->do_colors) {
      int J = j + 4;
      for ( ; j < J; j++)
        XPUSHs(sv_2mortal(newSVnv(vd[j])));
    }
    if (t->do_normals)
      for (i = 0; i < 3; i++)
        XPUSHs(sv_2mortal(newSVnv(vd[j++])));
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
}
end_tess_marshaller()

/* Declare gluTess VERTEX_DATA */
begin_tess_marshaller(vertex_data, vertex, (void * vertex_data, void * gl_polygon_data), "Missing tess callback for vertex_data", \
                      GLdouble * vd = (GLdouble*) vertex_data;                          \
                      if (t->do_colors) { \
                         glColor4f(vd[j], vd[j+1], vd[j+2], vd[j+3]); \
                         j += 4; \
                      } \
                      if (t->do_normals) glNormal3f(vd[j], vd[j+1], vd[j+2]);           \
                      glVertex3f(vd[0], vd[1], vd[2]);                                  \
                     )
    if (! vertex_data) croak("Missing vertex data in tess vertex_data callback");
{
    GLdouble * vd = (GLdouble*) vertex_data;
    for (i = 0; i < 3; i++)
      XPUSHs(sv_2mortal(newSVnv(vd[i])));
    if (t->do_colors) {
      int J = j + 4;
      for ( ; j < J; j++)
        XPUSHs(sv_2mortal(newSVnv(vd[j])));
    }
    if (t->do_normals)
      for (i = 0; i < 3; i++)
        XPUSHs(sv_2mortal(newSVnv(vd[j++])));
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
}
end_tess_marshaller()

/* Declare gluTess ERROR */
begin_tess_marshaller(error, error, (GLenum errno_, void * gl_polygon_data), "Missing tess callback for error", \
                      warn("Tesselation error: %s", gluErrorString(errno_)); \
                     )
	XPUSHs(sv_2mortal(newSViv(errno_)));
end_tess_marshaller()

/* Declare gluTess ERROR_DATA */
begin_tess_marshaller(error_data, error, (GLenum errno_, void * gl_polygon_data), "Missing tess callback for error_data", \
                      warn("Tesselation error: %s", gluErrorString(errno_)); \
                     )
	XPUSHs(sv_2mortal(newSViv(errno_)));
    if (t->polygon_data) XPUSHs((SV*)t->polygon_data);
end_tess_marshaller()

/* Declare gluTess COMBINE AND COMBINE_DATA */
void CALLBACK _s_marshal_glu_t_callback_combine (GLdouble coords[3], void * vertex_data[4],
                                                 GLfloat weight[4], void ** out_data,
                                                 void * gl_polygon_data)
{
        SV * handler;
	AV * vds;
        SV * item;
        I32 n;
	int i, j = 3;
	dSP;
        GLdouble *vd[4];
	PGLUtess *t = (PGLUtess*)gl_polygon_data;
        bool has_data = FALSE;
        int size = 3 + (t->do_colors ? 4 : 0) + (t->do_normals ? 3 : 0);
        GLdouble *vertex = malloc(sizeof(GLdouble) * size);
        if (vertex == NULL) croak("Couldn't allocate combination vertex during tesselation");
        vds = t->vertex_datas;
        if (!vds) croak("Missing vertex data storage");
	av_push(vds, newSViv(PTR2IV(vertex)));

	handler = t->combine_callback;
        if (!handler) croak("Missing tess callback for combine_data");

	if (t->use_vertex_data) {
            PGLUtess * opaque = malloc(sizeof(PGLUtess));
            if (!opaque) croak("Couldn't allocate storage for vertex opaque data");
	    opaque->triangulator     = t->triangulator;
            opaque->vertex_datas     = t->vertex_datas;
            opaque->vertex_callback  = t->vertex_callback;
            opaque->combine_callback = t->combine_callback;
            opaque->vertex_data      = vertex;
            opaque->polygon_data     = &PL_sv_undef;
            opaque->use_vertex_data  = TRUE;
            opaque->do_colors        = t->do_colors;
            opaque->do_normals       = t->do_normals;
            if (! t->tess_datas) t->tess_datas = newAV();
            av_push(t->tess_datas, newSViv(PTR2IV(opaque)));
            *out_data = opaque;
            for (i = 0; i < 4; i++) {
                PGLUtess* ot = (PGLUtess*)vertex_data[i];
                vd[i] = (GLdouble*)ot->vertex_data;
            }
	} else {
            *out_data = vertex;
            for (i = 0; i < 4; i++)
               vd[i] = (GLdouble*)vertex_data[i];
        }

        if (! SvROK(handler)) { /* default */
          vertex[0] = coords[0];
          vertex[1] = coords[1];
          vertex[2] = coords[2];
          if (t->do_colors) {
            int J = j + 4;
            for ( ; j < J; j++) {
              vertex[j] = 0;
              for (i = 0; i < 4; i++)
                if (weight[i]) vertex[j] += weight[i] * vd[i][j];
            }
          }
          if (t->do_normals) {
            int J = j + 3;
            for ( ; j < J; j++) {
              vertex[j] = 0;
              for (i = 0; i < 4; i++)
                if (weight[i]) vertex[j] += weight[i] * vd[i][j];
            }
          }
        } else {
          PUSHMARK(sp);
          for (i = 0; i < 3; i++)
            XPUSHs(sv_2mortal(newSVnv(coords[i])));
          for (i = 0; i < 4; i++) {
            AV* vec = (AV*)sv_2mortal((SV*)newAV());
            XPUSHs(newRV_inc((SV*)vec));
            for (j = 0 ; j < 3; j++)
                av_push(vec, sv_2mortal(newSVnv(weight[i] ? vd[i][j] : 0)));
            if (t->do_colors) {
              int J = j + 4;
              for ( ; j < J; j++)
                av_push(vec, sv_2mortal(newSVnv(weight[i] ? vd[i][j] : 0)));
            }
            if (t->do_normals) {
              int J = j + 3;
              for ( ; j < J; j++)
                av_push(vec, sv_2mortal(newSVnv(weight[i] ? vd[i][j] : 0)));
            }
            if (t->use_vertex_data) {
              PGLUtess* ot = (PGLUtess*)vertex_data[i];
              av_push(vec, ot->polygon_data ? ot->polygon_data : &PL_sv_undef);
            }
          }
          for (i = 0; i < 4; i++)
            XPUSHs(sv_2mortal(newSVnv(weight[i])));
          XPUSHs(t->polygon_data ? t->polygon_data : &PL_sv_undef); /* would be nice to have the option to only do this on COMBINE_DATA */

	  PUTBACK;

          n = perl_call_sv(handler, G_ARRAY);

          SPAGAIN;

          if (t->do_colors) {
              if (t->do_normals) {
                  if (n == 11 && t->use_vertex_data) has_data = TRUE;
                  else if (n != 10) {
                    if (t->use_vertex_data) croak("Callback expects (x,y,z, r,g,b,a, nx,ny,nz [,polygon_data])");
                    else  croak("Callback expects (x,y,z, r,g,b,a, nx,ny,nz)");
                  }
              } else {
                  if (n == 8 && t->use_vertex_data) has_data = TRUE;
                  else if (n != 7) {
                    if (t->use_vertex_data) croak("Callback expects (x,y,z, r,g,b,a [,polygon_data])");
                    else  croak("Callback expects (x,y,z, r,g,b,a)");
                  }
              }
          } else {
              if (t->do_normals) {
                  if (n == 7 && t->use_vertex_data) has_data = TRUE;
                  else if (n != 6) {
                    if (t->use_vertex_data) croak("Callback expects (x,y,z, nx,ny,nz [,polygon_data])");
                    else  croak("Callback expects (x,y,z, nx,ny,nz)");
                  }
              } else {
                  if (n == 4 && t->use_vertex_data) has_data = TRUE;
                  else if (n != 3) {
                    if (t->use_vertex_data) croak("Callback expects (x,y,z [,polygon_data])");
                    else  croak("Callback expects (x,y,z)");
                  }
              }
          }

          if (t->use_vertex_data) {
              PGLUtess* opaque = (PGLUtess*)*out_data;
              opaque->polygon_data = (has_data) ? POPs : 0;
          }

          for (i = n - (has_data ? 2 : 1); i >= 0; i--) {
              GLdouble val;
              item = POPs;
              if (! item || (! SvIOK(item) && ! SvNOK(item)))
                  croak("Value returned in index %d was not a valid number", i);
              val = (GLdouble)SvNV(item);
              vertex[i] = val;
          }
	  PUTBACK;
        }
}

#endif

#endif /* End IN_POGL_GLU_XS */


#line 381 "pogl_glu.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
	    Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
        else
	    Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
	Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#define croak_xs_usage        S_croak_xs_usage

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#if PERL_VERSION_LE(5, 21, 5)
#  define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
#else
#  define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif

#line 525 "pogl_glu.c"
#ifdef IN_POGL_GLU_XS
#ifdef HAVE_GLU
#define XSubPPtmpAAAA 1


XS_EUPXS(XS_OpenGL_gluBeginCurve); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBeginCurve)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluBeginCurve",
			"nurb", "GLUnurbsObjPtr")
;

	gluBeginCurve(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluEndCurve); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluEndCurve)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluEndCurve",
			"nurb", "GLUnurbsObjPtr")
;

	gluEndCurve(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluBeginPolygon); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBeginPolygon)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluBeginPolygon",
			"tess", "PGLUtessPtr")
;
#line 395 "pogl_glu.xs"
	gluBeginPolygon(tess->triangulator);
#line 601 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluEndPolygon); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluEndPolygon)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluEndPolygon",
			"tess", "PGLUtessPtr")
;
#line 402 "pogl_glu.xs"
	gluEndPolygon(tess->triangulator);
#line 627 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluBeginSurface); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBeginSurface)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluBeginSurface",
			"nurb", "GLUnurbsObjPtr")
;

	gluBeginSurface(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluEndSurface); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluEndSurface)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluEndSurface",
			"nurb", "GLUnurbsObjPtr")
;

	gluEndSurface(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluBeginTrim); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBeginTrim)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluBeginTrim",
			"nurb", "GLUnurbsObjPtr")
;

	gluBeginTrim(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluEndTrim); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluEndTrim)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluEndTrim",
			"nurb", "GLUnurbsObjPtr")
;

	gluEndTrim(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluBuild1DMipmaps_c); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBuild1DMipmaps_c)
{
    dVAR; dXSARGS;
    if (items != 6)
       croak_xs_usage(cv,  "target, internalformat, width, format, type, data");
    {
	GLenum	target = (int)SvIV(ST(0))
;
	GLuint	internalformat = (unsigned int)SvUV(ST(1))
;
	GLsizei	width = (int)SvIV(ST(2))
;
	GLenum	format = (int)SvIV(ST(3))
;
	GLenum	type = (int)SvIV(ST(4))
;
	void *	data = INT2PTR(void *,SvIV(ST(5)))
;
	GLint	RETVAL;
	dXSTARG;
#line 434 "pogl_glu.xs"
	{
		RETVAL=gluBuild1DMipmaps(target, internalformat,
			width, format, type, data);
	}
#line 759 "pogl_glu.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluBuild1DMipmaps_s); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBuild1DMipmaps_s)
{
    dVAR; dXSARGS;
    if (items != 6)
       croak_xs_usage(cv,  "target, internalformat, width, format, type, data");
    {
	GLenum	target = (int)SvIV(ST(0))
;
	GLuint	internalformat = (unsigned int)SvUV(ST(1))
;
	GLsizei	width = (int)SvIV(ST(2))
;
	GLenum	format = (int)SvIV(ST(3))
;
	GLenum	type = (int)SvIV(ST(4))
;
	SV *	data = ST(5)
;
	GLint	RETVAL;
	dXSTARG;
#line 451 "pogl_glu.xs"
	{
	GLvoid * ptr = ELI(data, width, 1, format, type, gl_pixelbuffer_unpack);
	RETVAL=gluBuild1DMipmaps(target, internalformat, width, format, type, ptr);
	}
#line 792 "pogl_glu.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluBuild2DMipmaps_c); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBuild2DMipmaps_c)
{
    dVAR; dXSARGS;
    if (items != 7)
       croak_xs_usage(cv,  "target, internalformat, width, height, format, type, data");
    {
	GLenum	target = (int)SvIV(ST(0))
;
	GLuint	internalformat = (unsigned int)SvUV(ST(1))
;
	GLsizei	width = (int)SvIV(ST(2))
;
	GLsizei	height = (int)SvIV(ST(3))
;
	GLenum	format = (int)SvIV(ST(4))
;
	GLenum	type = (int)SvIV(ST(5))
;
	void *	data = INT2PTR(void *,SvIV(ST(6)))
;
	GLint	RETVAL;
	dXSTARG;
#line 469 "pogl_glu.xs"
	{
		RETVAL=gluBuild2DMipmaps(target, internalformat,
			width, height, format, type, data);
	}
#line 827 "pogl_glu.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluBuild2DMipmaps_s); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluBuild2DMipmaps_s)
{
    dVAR; dXSARGS;
    if (items != 7)
       croak_xs_usage(cv,  "target, internalformat, width, height, format, type, data");
    {
	GLenum	target = (int)SvIV(ST(0))
;
	GLuint	internalformat = (unsigned int)SvUV(ST(1))
;
	GLsizei	width = (int)SvIV(ST(2))
;
	GLsizei	height = (int)SvIV(ST(3))
;
	GLenum	format = (int)SvIV(ST(4))
;
	GLenum	type = (int)SvIV(ST(5))
;
	SV *	data = ST(6)
;
	GLint	RETVAL;
	dXSTARG;
#line 487 "pogl_glu.xs"
	{
	GLvoid * ptr = ELI(data, width, height, format, type, gl_pixelbuffer_unpack);
	RETVAL=gluBuild2DMipmaps(target, internalformat, width, height, format, type, ptr);
	}
#line 862 "pogl_glu.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluCylinder); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluCylinder)
{
    dVAR; dXSARGS;
    if (items != 6)
       croak_xs_usage(cv,  "quad, base, top, height, slices, stacks");
    {
	GLUquadricObj *	quad;
	GLdouble	base = (double)SvNV(ST(1))
;
	GLdouble	top = (double)SvNV(ST(2))
;
	GLdouble	height = (double)SvNV(ST(3))
;
	GLint	slices = (int)SvIV(ST(4))
;
	GLint	stacks = (int)SvIV(ST(5))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluCylinder",
			"quad", "GLUquadricObjPtr")
;

	gluCylinder(quad, base, top, height, slices, stacks);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluDeleteNurbsRenderer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluDeleteNurbsRenderer)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "nurb");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluDeleteNurbsRenderer",
			"nurb", "GLUnurbsObjPtr")
;

	gluDeleteNurbsRenderer(nurb);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluDeleteQuadric); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluDeleteQuadric)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "quad");
    {
	GLUquadricObj *	quad;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluDeleteQuadric",
			"quad", "GLUquadricObjPtr")
;

	gluDeleteQuadric(quad);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluDeleteTess); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluDeleteTess)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluDeleteTess",
			"tess", "PGLUtessPtr")
;
#line 519 "pogl_glu.xs"
	{
		if (tess->triangulator)
			gluDeleteTess(tess->triangulator);
#ifdef GLU_VERSION_1_2
		if (tess->begin_callback)
			SvREFCNT_dec(tess->begin_callback);
		if (tess->edgeFlag_callback)
			SvREFCNT_dec(tess->edgeFlag_callback);
		if (tess->vertex_callback)
			SvREFCNT_dec(tess->vertex_callback);
		if (tess->end_callback)
			SvREFCNT_dec(tess->end_callback);
		if (tess->error_callback)
			SvREFCNT_dec(tess->error_callback);
		if (tess->combine_callback)
			SvREFCNT_dec(tess->combine_callback);
#endif
delete_vertex_datas()
delete_tess_datas()
delete_polygon_data()
		free(tess);
	}
#line 995 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluDisk); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluDisk)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "quad, inner, outer, slices, loops");
    {
	GLUquadricObj *	quad;
	GLdouble	inner = (double)SvNV(ST(1))
;
	GLdouble	outer = (double)SvNV(ST(2))
;
	GLint	slices = (int)SvIV(ST(3))
;
	GLint	loops = (int)SvIV(ST(4))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluDisk",
			"quad", "GLUquadricObjPtr")
;

	gluDisk(quad, inner, outer, slices, loops);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluErrorString); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluErrorString)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "error");
    {
	GLenum	error = (int)SvIV(ST(0))
;
	char *	RETVAL;
	dXSTARG;
#line 556 "pogl_glu.xs"
	RETVAL = (char*)gluErrorString(error);
#line 1047 "pogl_glu.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluGetNurbsProperty_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluGetNurbsProperty_p)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "nurb, property");
    {
	GLUnurbsObj *	nurb;
	GLenum	property = (int)SvIV(ST(1))
;
	GLfloat	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluGetNurbsProperty_p",
			"nurb", "GLUnurbsObjPtr")
;
#line 566 "pogl_glu.xs"
	{
		GLfloat param;
		gluGetNurbsProperty(nurb, property, &param);
		RETVAL = param;
	}
#line 1082 "pogl_glu.c"
	XSprePUSH; PUSHn((double)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluNurbsProperty); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNurbsProperty)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "nurb, property, value");
    {
	GLUnurbsObj *	nurb;
	GLenum	property = (int)SvIV(ST(1))
;
	GLfloat	value = (float)SvNV(ST(2))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluNurbsProperty",
			"nurb", "GLUnurbsObjPtr")
;

	gluNurbsProperty(nurb, property, value);
    }
    XSRETURN_EMPTY;
}

#ifdef GLU_VERSION_1_1
#define XSubPPtmpAAAB 1


XS_EUPXS(XS_OpenGL_gluGetString); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluGetString)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "name");
    {
	GLenum	name = (int)SvIV(ST(0))
;
	char *	RETVAL;
	dXSTARG;
#line 588 "pogl_glu.xs"
	RETVAL = (char*)gluGetString(name);
#line 1134 "pogl_glu.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}

#endif

XS_EUPXS(XS_OpenGL_gluLoadSamplingMatrices_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluLoadSamplingMatrices_p)
{
    dVAR; dXSARGS;
    if (items != 37)
       croak_xs_usage(cv,  "nurb, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, v1, v2, v3, v4");
    {
	GLUnurbsObj *	nurb;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluLoadSamplingMatrices_p",
			"nurb", "GLUnurbsObjPtr")
;
#line 599 "pogl_glu.xs"
	{
		GLfloat m[16], p[16];
		GLint v[4];
		int i;
		for (i=0;i<16;i++)
			m[i] = (GLfloat)SvNV(ST(i+1));
		for (i=0;i<16;i++)
			p[i] = (GLfloat)SvNV(ST(i+1+16));
		for (i=0;i<4;i++)
			v[i] = SvIV(ST(i+1+16+16));
		gluLoadSamplingMatrices(nurb, m, p, v);
	}
#line 1173 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluLookAt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluLookAt)
{
    dVAR; dXSARGS;
    if (items != 9)
       croak_xs_usage(cv,  "eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ");
    {
	GLdouble	eyeX = (double)SvNV(ST(0))
;
	GLdouble	eyeY = (double)SvNV(ST(1))
;
	GLdouble	eyeZ = (double)SvNV(ST(2))
;
	GLdouble	centerX = (double)SvNV(ST(3))
;
	GLdouble	centerY = (double)SvNV(ST(4))
;
	GLdouble	centerZ = (double)SvNV(ST(5))
;
	GLdouble	upX = (double)SvNV(ST(6))
;
	GLdouble	upY = (double)SvNV(ST(7))
;
	GLdouble	upZ = (double)SvNV(ST(8))
;

	gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluNewNurbsRenderer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNewNurbsRenderer)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	GLUnurbsObj *	RETVAL;

	RETVAL = gluNewNurbsRenderer();
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "GLUnurbsObjPtr", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluNewQuadric); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNewQuadric)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	GLUquadricObj *	RETVAL;

	RETVAL = gluNewQuadric();
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "GLUquadricObjPtr", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluNewTess); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNewTess)
{
    dVAR; dXSARGS;
    PERL_UNUSED_VAR(cv); /* -W */
    {
	PGLUtess *	RETVAL;
#line 637 "pogl_glu.xs"
	{
		RETVAL = malloc(sizeof(PGLUtess));
		memset(RETVAL, 0, sizeof(PGLUtess));
                RETVAL->do_colors  = (items > 0) ? SvTRUE(ST(0)) : FALSE;
                RETVAL->do_normals = (items > 1) ? SvTRUE(ST(1)) : FALSE;
		RETVAL->triangulator = gluNewTess();
	}
#line 1268 "pogl_glu.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "PGLUtessPtr", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluNextContour); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNextContour)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "tess, type");
    {
	PGLUtess *	tess;
	GLenum	type = (int)SvIV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluNextContour",
			"tess", "PGLUtessPtr")
;
#line 653 "pogl_glu.xs"
	gluNextContour(tess->triangulator, type);
#line 1302 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluNurbsCurve_c); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNurbsCurve_c)
{
    dVAR; dXSARGS;
    if (items != 7)
       croak_xs_usage(cv,  "nurb, nknots, knot, stride, ctlarray, order, type");
    {
	GLUnurbsObj *	nurb;
	GLint	nknots = (int)SvIV(ST(1))
;
	void *	knot = INT2PTR(void *,SvIV(ST(2)))
;
	GLint	stride = (int)SvIV(ST(3))
;
	void *	ctlarray = INT2PTR(void *,SvIV(ST(4)))
;
	GLint	order = (int)SvIV(ST(5))
;
	GLenum	type = (int)SvIV(ST(6))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluNurbsCurve_c",
			"nurb", "GLUnurbsObjPtr")
;
#line 666 "pogl_glu.xs"
	gluNurbsCurve(nurb, nknots, knot, stride, ctlarray, order, type);
#line 1340 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluNurbsSurface_c); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluNurbsSurface_c)
{
    dVAR; dXSARGS;
    if (items != 11)
       croak_xs_usage(cv,  "nurb, sknot_count, sknot, tknot_count, tknot, s_stride, t_stride, ctrlarray, sorder, torder, type");
    {
	GLUnurbsObj *	nurb;
	GLint	sknot_count = (int)SvIV(ST(1))
;
	void *	sknot = INT2PTR(void *,SvIV(ST(2)))
;
	GLint	tknot_count = (int)SvIV(ST(3))
;
	void *	tknot = INT2PTR(void *,SvIV(ST(4)))
;
	GLint	s_stride = (int)SvIV(ST(5))
;
	GLint	t_stride = (int)SvIV(ST(6))
;
	void *	ctrlarray = INT2PTR(void *,SvIV(ST(7)))
;
	GLint	sorder = (int)SvIV(ST(8))
;
	GLint	torder = (int)SvIV(ST(9))
;
	GLenum	type = (int)SvIV(ST(10))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluNurbsSurface_c",
			"nurb", "GLUnurbsObjPtr")
;
#line 683 "pogl_glu.xs"
	gluNurbsSurface(nurb, sknot_count, sknot, tknot_count, tknot, s_stride, t_stride, ctrlarray, sorder, torder, type);
#line 1386 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluOrtho2D); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluOrtho2D)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "left, right, bottom, top");
    {
	GLdouble	left = (double)SvNV(ST(0))
;
	GLdouble	right = (double)SvNV(ST(1))
;
	GLdouble	bottom = (double)SvNV(ST(2))
;
	GLdouble	top = (double)SvNV(ST(3))
;

	gluOrtho2D(left, right, bottom, top);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluPartialDisk); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluPartialDisk)
{
    dVAR; dXSARGS;
    if (items != 7)
       croak_xs_usage(cv,  "quad, inner, outer, slices, loops, start, sweep");
    {
	GLUquadricObj*	quad;
	GLdouble	inner = (double)SvNV(ST(1))
;
	GLdouble	outer = (double)SvNV(ST(2))
;
	GLint	slices = (int)SvIV(ST(3))
;
	GLint	loops = (int)SvIV(ST(4))
;
	GLdouble	start = (double)SvNV(ST(5))
;
	GLdouble	sweep = (double)SvNV(ST(6))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluPartialDisk",
			"quad", "GLUquadricObjPtr")
;

	gluPartialDisk(quad, inner, outer, slices, loops, start, sweep);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluPerspective); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluPerspective)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "fovy, aspect, zNear, zFar");
    {
	GLdouble	fovy = (double)SvNV(ST(0))
;
	GLdouble	aspect = (double)SvNV(ST(1))
;
	GLdouble	zNear = (double)SvNV(ST(2))
;
	GLdouble	zFar = (double)SvNV(ST(3))
;

	gluPerspective(fovy, aspect, zNear, zFar);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluPickMatrix_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluPickMatrix_p)
{
    dVAR; dXSARGS;
    if (items != 8)
       croak_xs_usage(cv,  "x, y, delX, delY, m1, m2, m3, m4");
    {
	GLdouble	x = (double)SvNV(ST(0))
;
	GLdouble	y = (double)SvNV(ST(1))
;
	GLdouble	delX = (double)SvNV(ST(2))
;
	GLdouble	delY = (double)SvNV(ST(3))
;
#line 720 "pogl_glu.xs"
	{
		GLint m[4];
		int i;
		for (i=0;i<4;i++)
			m[i] = SvIV(ST(i+4));
		gluPickMatrix(x, y, delX, delY, &m[0]);
	}
#line 1496 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluProject_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluProject_p)
{
    dVAR; dXSARGS;
    if (items != 39)
       croak_xs_usage(cv,  "objx, objy, objz, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, v1, v2, v3, v4");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	GLdouble	objx = (double)SvNV(ST(0))
;
	GLdouble	objy = (double)SvNV(ST(1))
;
	GLdouble	objz = (double)SvNV(ST(2))
;
#line 735 "pogl_glu.xs"
	{
		GLdouble m[16], p[16], winx, winy, winz;
		GLint v[4];
		int i;
		for (i=0;i<16;i++)
			m[i] = SvNV(ST(i+3));
		for (i=0;i<16;i++)
			p[i] = SvNV(ST(i+3+16));
		for (i=0;i<4;i++)
			v[i] = SvIV(ST(i+3+16+16));
		i = gluProject(objx, objy, objz, m, p, v, &winx, &winy, &winz);
		if (i) {
			EXTEND(sp, 3);
			PUSHs(sv_2mortal(newSVnv(winx)));
			PUSHs(sv_2mortal(newSVnv(winy)));
			PUSHs(sv_2mortal(newSVnv(winz)));
		}
	}
#line 1536 "pogl_glu.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenGL_gluPwlCurve_c); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluPwlCurve_c)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "nurb, count, data, stride, type");
    {
	GLUnurbsObj *	nurb;
	GLint	count = (int)SvIV(ST(1))
;
	void *	data = INT2PTR(void *,SvIV(ST(2)))
;
	GLint	stride = (int)SvIV(ST(3))
;
	GLenum	type = (int)SvIV(ST(4))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUnurbsObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    nurb = INT2PTR(GLUnurbsObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluPwlCurve_c",
			"nurb", "GLUnurbsObjPtr")
;
#line 763 "pogl_glu.xs"
	gluPwlCurve(nurb, count, data, stride, type);
#line 1571 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluQuadricDrawStyle); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluQuadricDrawStyle)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "quad, draw");
    {
	GLUquadricObj *	quad;
	GLenum	draw = (int)SvIV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluQuadricDrawStyle",
			"quad", "GLUquadricObjPtr")
;

	gluQuadricDrawStyle(quad, draw);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluQuadricNormals); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluQuadricNormals)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "quad, normal");
    {
	GLUquadricObj *	quad;
	GLenum	normal = (int)SvIV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluQuadricNormals",
			"quad", "GLUquadricObjPtr")
;

	gluQuadricNormals(quad, normal);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluQuadricOrientation); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluQuadricOrientation)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "quad, orientation");
    {
	GLUquadricObj *	quad;
	GLenum	orientation = (int)SvIV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluQuadricOrientation",
			"quad", "GLUquadricObjPtr")
;

	gluQuadricOrientation(quad, orientation);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluQuadricTexture); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluQuadricTexture)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "quad, texture");
    {
	GLUquadricObj *	quad;
	GLboolean	texture = (bool)SvTRUE(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluQuadricTexture",
			"quad", "GLUquadricObjPtr")
;

	gluQuadricTexture(quad, texture);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluScaleImage_s); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluScaleImage_s)
{
    dVAR; dXSARGS;
    if (items != 9)
       croak_xs_usage(cv,  "format, wIn, hIn, typeIn, dataIn, wOut, hOut, typeOut, dataOut");
    {
	GLenum	format = (int)SvIV(ST(0))
;
	GLsizei	wIn = (int)SvIV(ST(1))
;
	GLsizei	hIn = (int)SvIV(ST(2))
;
	GLenum	typeIn = (int)SvIV(ST(3))
;
	SV *	dataIn = ST(4)
;
	GLsizei	wOut = (int)SvIV(ST(5))
;
	GLsizei	hOut = (int)SvIV(ST(6))
;
	GLenum	typeOut = (int)SvIV(ST(7))
;
	SV *	dataOut = ST(8)
;
	GLint	RETVAL;
	dXSTARG;
#line 803 "pogl_glu.xs"
	{
		GLvoid * inptr, * outptr;
		STRLEN discard;
		ELI(dataIn, wIn, hIn, format, typeIn, gl_pixelbuffer_unpack);
		ELI(dataOut, wOut, hOut, format, typeOut, gl_pixelbuffer_pack);
		inptr = SvPV(dataIn, discard);
		outptr = SvPV(dataOut, discard);
		RETVAL = gluScaleImage(format, wIn, hIn, typeIn, inptr, wOut, hOut, typeOut, outptr);
	}
#line 1722 "pogl_glu.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluSphere); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluSphere)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "quad, radius, slices, stacks");
    {
	GLUquadricObj *	quad;
	GLdouble	radius = (double)SvNV(ST(1))
;
	GLint	slices = (int)SvIV(ST(2))
;
	GLint	stacks = (int)SvIV(ST(3))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GLUquadricObjPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    quad = INT2PTR(GLUquadricObj *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluSphere",
			"quad", "GLUquadricObjPtr")
;

	gluSphere(quad, radius, slices, stacks);
    }
    XSRETURN_EMPTY;
}

#ifdef GLU_VERSION_1_2
#define XSubPPtmpAAAC 1


XS_EUPXS(XS_OpenGL_gluGetTessProperty_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluGetTessProperty_p)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "tess, property");
    {
	PGLUtess *	tess;
	GLenum	property = (int)SvIV(ST(1))
;
	GLdouble	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluGetTessProperty_p",
			"tess", "PGLUtessPtr")
;
#line 831 "pogl_glu.xs"
	{
		GLdouble param;
		gluGetTessProperty(tess->triangulator, property, &param);
		RETVAL = param;
	}
#line 1791 "pogl_glu.c"
	XSprePUSH; PUSHn((double)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenGL_gluTessBeginContour); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessBeginContour)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessBeginContour",
			"tess", "PGLUtessPtr")
;
#line 856 "pogl_glu.xs"
	gluTessBeginContour(tess->triangulator);
#line 1818 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessEndContour); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessEndContour)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessEndContour",
			"tess", "PGLUtessPtr")
;
#line 863 "pogl_glu.xs"
	gluTessEndContour(tess->triangulator);
#line 1844 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessBeginPolygon); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessBeginPolygon)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "tess, ...");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessBeginPolygon",
			"tess", "PGLUtessPtr")
;
#line 870 "pogl_glu.xs"
	{
delete_polygon_data()
		if (items > 1) {
			tess->polygon_data = newSVsv(ST(1));
		}
              	if (!tess->vertex_datas)
			tess->vertex_datas = newAV();
                gluTessBeginPolygon(tess->triangulator, tess);
	}
#line 1878 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessEndPolygon); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessEndPolygon)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "tess");
    {
	PGLUtess *	tess;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessEndPolygon",
			"tess", "PGLUtessPtr")
;
#line 885 "pogl_glu.xs"
	{
                gluTessEndPolygon(tess->triangulator);
delete_vertex_datas()
delete_tess_datas()
delete_polygon_data()
	}
#line 1909 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessNormal); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessNormal)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "tess, valueX, valueY, valueZ");
    {
	PGLUtess *	tess;
	GLdouble	valueX = (double)SvNV(ST(1))
;
	GLdouble	valueY = (double)SvNV(ST(2))
;
	GLdouble	valueZ = (double)SvNV(ST(3))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessNormal",
			"tess", "PGLUtessPtr")
;
#line 900 "pogl_glu.xs"
	gluTessNormal(tess->triangulator, valueX, valueY, valueZ);
#line 1941 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessProperty); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessProperty)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "tess, which, data");
    {
	PGLUtess *	tess;
	GLenum	which = (int)SvIV(ST(1))
;
	GLdouble	data = (double)SvNV(ST(2))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessProperty",
			"tess", "PGLUtessPtr")
;
#line 909 "pogl_glu.xs"
	gluTessProperty(tess->triangulator, which, data);
#line 1971 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluTessCallback); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessCallback)
{
    dVAR; dXSARGS;
    if (items < 2)
       croak_xs_usage(cv,  "tess, which, ...");
    {
	PGLUtess *	tess;
	GLenum	which = (int)SvIV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessCallback",
			"tess", "PGLUtessPtr")
;
#line 917 "pogl_glu.xs"
	{
		switch (which) {
		case GLU_TESS_BEGIN:
		case GLU_TESS_BEGIN_DATA:
			if (tess->begin_callback) {
				SvREFCNT_dec(tess->begin_callback);
				tess->begin_callback = 0;
			}
			break;
		case GLU_TESS_END:
		case GLU_TESS_END_DATA:
			if (tess->end_callback) {
				SvREFCNT_dec(tess->end_callback);
				tess->end_callback = 0;
			}
			break;
		case GLU_TESS_VERTEX:
		case GLU_TESS_VERTEX_DATA:
			if (tess->vertex_callback) {
				SvREFCNT_dec(tess->vertex_callback);
				tess->vertex_callback = 0;
			}
			break;
		case GLU_TESS_ERROR:
		case GLU_TESS_ERROR_DATA:
			if (tess->error_callback) {
				SvREFCNT_dec(tess->error_callback);
				tess->error_callback = 0;
			}
			break;
		case GLU_TESS_COMBINE:
		case GLU_TESS_COMBINE_DATA:
			if (tess->combine_callback) {
				SvREFCNT_dec(tess->combine_callback);
				tess->combine_callback = 0;
			}
			break;
		case GLU_TESS_EDGE_FLAG:
		case GLU_TESS_EDGE_FLAG_DATA:
			if (tess->edgeFlag_callback) {
				SvREFCNT_dec(tess->edgeFlag_callback);
				tess->edgeFlag_callback = 0;
			}
			break;
		}

                if (items > 2) {
			SV * callback;
                        if (SvPOK(ST(2))
                            && sv_eq(ST(2), sv_2mortal(newSVpv("DEFAULT", 0)))) {
				callback = newSViv(1);
				switch (which) {
				case GLU_TESS_BEGIN_DATA:
					which = GLU_TESS_BEGIN; break;
				case GLU_TESS_END_DATA:
					which = GLU_TESS_END; break;
				case GLU_TESS_ERROR_DATA:
					which = GLU_TESS_ERROR; break;
				case GLU_TESS_EDGE_FLAG_DATA:
					which = GLU_TESS_EDGE_FLAG; break;
                                case GLU_TESS_VERTEX:
					which = GLU_TESS_VERTEX_DATA; break; /* vertex data handler has less overhead and both pass opaque pointers anyway */
                                }
                        } else if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVCV) {
                            croak("3rd argument to gluTessCallback must be a perl code ref");
                        } else {
                            callback = newSVsv(ST(2));
                        }
			switch (which) {
			case GLU_TESS_BEGIN:
				tess->begin_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_begin);
				break;
			case GLU_TESS_BEGIN_DATA:
				tess->begin_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_begin_data);
				break;
			case GLU_TESS_END:
				tess->end_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_END_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_end);
				break;
			case GLU_TESS_END_DATA:
				tess->end_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_END_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_end_data);
				break;
			case GLU_TESS_VERTEX:
                                tess->use_vertex_data = TRUE;
				tess->vertex_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_VERTEX, (void (CALLBACK*)()) _s_marshal_glu_t_callback_vertex);
				break;
			case GLU_TESS_VERTEX_DATA:
                                tess->use_vertex_data = FALSE;
				tess->vertex_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_VERTEX_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_vertex_data);
				break;
			case GLU_TESS_ERROR:
				tess->error_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_ERROR_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_error);
				break;
			case GLU_TESS_ERROR_DATA:
				tess->error_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_ERROR_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_error_data);
				break;
			case GLU_TESS_COMBINE:
			case GLU_TESS_COMBINE_DATA:
				tess->combine_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_COMBINE_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_combine);
				break;
			case GLU_TESS_EDGE_FLAG:
				tess->edgeFlag_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_EDGE_FLAG_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_edgeFlag);
				break;
			case GLU_TESS_EDGE_FLAG_DATA:
				tess->edgeFlag_callback = callback;
				gluTessCallback(tess->triangulator, GLU_TESS_EDGE_FLAG_DATA, (void (CALLBACK*)()) _s_marshal_glu_t_callback_edgeFlag_data);
				break;
			}
		}
	}
#line 2117 "pogl_glu.c"
    }
    XSRETURN(1);
}

#endif

XS_EUPXS(XS_OpenGL_gluTessVertex_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluTessVertex_p)
{
    dVAR; dXSARGS;
    if (items < 4)
       croak_xs_usage(cv,  "tess, x, y, z, ...");
    {
	PGLUtess *	tess;
	GLdouble	x = (double)SvNV(ST(1))
;
	GLdouble	y = (double)SvNV(ST(2))
;
	GLdouble	z = (double)SvNV(ST(3))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "PGLUtessPtr")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    tess = INT2PTR(PGLUtess *,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenGL::gluTessVertex_p",
			"tess", "PGLUtessPtr")
;
#line 1048 "pogl_glu.xs"
	{
                int i;
                int j = 3;
                AV * vds = tess->vertex_datas;
                int size = 3 + (tess->do_colors ? 4 : 0) + (tess->do_normals ? 3 : 0);
		GLdouble* data = malloc(sizeof(GLdouble) * size);
                if (!vds) croak("Missing vertex data storage during gluTessVertex");
                if (data == NULL) croak("Couldn't allocate vertex during gluTessVertex");
		data[0] = x;
		data[1] = y;
		data[2] = z;
                av_push(vds, newSViv(PTR2IV(data))); /* store for freeing later */
                if (tess->do_colors) {
                    int J = j + 4;
                    if (tess->do_normals) {
                        if (items != 12 && items != 11) croak("gluTessVertex_p(tess, x,y,z, r,g,b,a, nx,ny,nz [,polygon_data])");
                    } else {
                        if (items != 9  && items != 8 ) croak("gluTessVertex_p(tess, x,y,z, r,g,b,a [,polygon_data])");
                    }
                    for ( ; j < J; j++) data[j] = (GLdouble)SvNV(ST(j+1));
                } else {
                    if (tess->do_normals) {
                        if (items != 8 && items != 7) croak("gluTessVertex_p(tess, x,y,z, nx,ny,nz [,polygon_data])");
                    } else {
                        if (items != 5 && items != 4) croak("gluTessVertex_p(tess, x,y,z [,polygon_data])");
                    }
                }
                if (tess->do_normals) {
                    int J = j + 3;
                    for ( ; j < J; j++) data[j] = (GLdouble)SvNV(ST(j+1));
                }
		if (tess->use_vertex_data) {
                    PGLUtess * opaque = malloc(sizeof(PGLUtess));
                    if (!opaque) croak("Couldn't allocate storage for vertex opaque data");
		    opaque->triangulator     = tess->triangulator;
                    opaque->vertex_datas     = tess->vertex_datas;
                    opaque->vertex_callback  = tess->vertex_callback;
                    opaque->combine_callback = tess->combine_callback;
                    opaque->vertex_data      = data;
                    opaque->polygon_data     = (items > j+1) ? newSVsv(ST(j+1)) : 0;
                    opaque->use_vertex_data  = TRUE;
                    opaque->do_colors        = tess->do_colors;
                    opaque->do_normals       = tess->do_normals;
                    if (! tess->tess_datas) tess->tess_datas = newAV();
                    av_push(tess->tess_datas, newSViv(PTR2IV(opaque)));
                    gluTessVertex(tess->triangulator, data, (void*)opaque);
		} else {
                    gluTessVertex(tess->triangulator, data, data);
                }
	}
#line 2199 "pogl_glu.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenGL_gluUnProject_p); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenGL_gluUnProject_p)
{
    dVAR; dXSARGS;
    if (items != 39)
       croak_xs_usage(cv,  "winx, winy, winz, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15, o16, v1, v2, v3, v4");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	GLdouble	winx = (double)SvNV(ST(0))
;
	GLdouble	winy = (double)SvNV(ST(1))
;
	GLdouble	winz = (double)SvNV(ST(2))
;
#line 1106 "pogl_glu.xs"
	{
		GLdouble m[16], p[16], objx, objy, objz;
		GLint v[4];
		int i;

		for (i=0;i<16;i++)
			m[i] = SvNV(ST(i+3));
		for (i=0;i<16;i++)
			p[i] = SvNV(ST(i+3+16));
		for (i=0;i<4;i++)
			v[i] = SvIV(ST(i+3+16+16));

		i = gluUnProject(winx,winy,winz, m, p, v, &objx,&objy,&objz);

		if (i) {
			EXTEND(sp, 3);
			PUSHs(sv_2mortal(newSVnv(objx)));
			PUSHs(sv_2mortal(newSVnv(objy)));
			PUSHs(sv_2mortal(newSVnv(objz)));
		}
	}
#line 2242 "pogl_glu.c"
	PUTBACK;
	return;
    }
}

#endif
#endif /* End IN_POGL_GLU_XS */
#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_OpenGL__GLU); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_OpenGL__GLU)
{
#if PERL_VERSION_LE(5, 21, 5)
    dVAR; dXSARGS;
#else
    dVAR; dXSBOOTARGSXSAPIVERCHK;
#endif
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

#if XSubPPtmpAAAA
        newXS_deffile("OpenGL::gluBeginCurve", XS_OpenGL_gluBeginCurve);
        newXS_deffile("OpenGL::gluEndCurve", XS_OpenGL_gluEndCurve);
        newXS_deffile("OpenGL::gluBeginPolygon", XS_OpenGL_gluBeginPolygon);
        newXS_deffile("OpenGL::gluEndPolygon", XS_OpenGL_gluEndPolygon);
        newXS_deffile("OpenGL::gluBeginSurface", XS_OpenGL_gluBeginSurface);
        newXS_deffile("OpenGL::gluEndSurface", XS_OpenGL_gluEndSurface);
        newXS_deffile("OpenGL::gluBeginTrim", XS_OpenGL_gluBeginTrim);
        newXS_deffile("OpenGL::gluEndTrim", XS_OpenGL_gluEndTrim);
        newXS_deffile("OpenGL::gluBuild1DMipmaps_c", XS_OpenGL_gluBuild1DMipmaps_c);
        newXS_deffile("OpenGL::gluBuild1DMipmaps_s", XS_OpenGL_gluBuild1DMipmaps_s);
        newXS_deffile("OpenGL::gluBuild2DMipmaps_c", XS_OpenGL_gluBuild2DMipmaps_c);
        newXS_deffile("OpenGL::gluBuild2DMipmaps_s", XS_OpenGL_gluBuild2DMipmaps_s);
        newXS_deffile("OpenGL::gluCylinder", XS_OpenGL_gluCylinder);
        newXS_deffile("OpenGL::gluDeleteNurbsRenderer", XS_OpenGL_gluDeleteNurbsRenderer);
        newXS_deffile("OpenGL::gluDeleteQuadric", XS_OpenGL_gluDeleteQuadric);
        newXS_deffile("OpenGL::gluDeleteTess", XS_OpenGL_gluDeleteTess);
        newXS_deffile("OpenGL::gluDisk", XS_OpenGL_gluDisk);
        newXS_deffile("OpenGL::gluErrorString", XS_OpenGL_gluErrorString);
        newXS_deffile("OpenGL::gluGetNurbsProperty_p", XS_OpenGL_gluGetNurbsProperty_p);
        newXS_deffile("OpenGL::gluNurbsProperty", XS_OpenGL_gluNurbsProperty);
#if XSubPPtmpAAAB
        newXS_deffile("OpenGL::gluGetString", XS_OpenGL_gluGetString);
#endif
        newXS_deffile("OpenGL::gluLoadSamplingMatrices_p", XS_OpenGL_gluLoadSamplingMatrices_p);
        newXS_deffile("OpenGL::gluLookAt", XS_OpenGL_gluLookAt);
        newXS_deffile("OpenGL::gluNewNurbsRenderer", XS_OpenGL_gluNewNurbsRenderer);
        newXS_deffile("OpenGL::gluNewQuadric", XS_OpenGL_gluNewQuadric);
        newXS_deffile("OpenGL::gluNewTess", XS_OpenGL_gluNewTess);
        newXS_deffile("OpenGL::gluNextContour", XS_OpenGL_gluNextContour);
        newXS_deffile("OpenGL::gluNurbsCurve_c", XS_OpenGL_gluNurbsCurve_c);
        newXS_deffile("OpenGL::gluNurbsSurface_c", XS_OpenGL_gluNurbsSurface_c);
        newXS_deffile("OpenGL::gluOrtho2D", XS_OpenGL_gluOrtho2D);
        newXS_deffile("OpenGL::gluPartialDisk", XS_OpenGL_gluPartialDisk);
        newXS_deffile("OpenGL::gluPerspective", XS_OpenGL_gluPerspective);
        newXS_deffile("OpenGL::gluPickMatrix_p", XS_OpenGL_gluPickMatrix_p);
        newXS_deffile("OpenGL::gluProject_p", XS_OpenGL_gluProject_p);
        newXS_deffile("OpenGL::gluPwlCurve_c", XS_OpenGL_gluPwlCurve_c);
        newXS_deffile("OpenGL::gluQuadricDrawStyle", XS_OpenGL_gluQuadricDrawStyle);
        newXS_deffile("OpenGL::gluQuadricNormals", XS_OpenGL_gluQuadricNormals);
        newXS_deffile("OpenGL::gluQuadricOrientation", XS_OpenGL_gluQuadricOrientation);
        newXS_deffile("OpenGL::gluQuadricTexture", XS_OpenGL_gluQuadricTexture);
        newXS_deffile("OpenGL::gluScaleImage_s", XS_OpenGL_gluScaleImage_s);
        newXS_deffile("OpenGL::gluSphere", XS_OpenGL_gluSphere);
#if XSubPPtmpAAAC
        newXS_deffile("OpenGL::gluGetTessProperty_p", XS_OpenGL_gluGetTessProperty_p);
        newXS_deffile("OpenGL::gluTessBeginContour", XS_OpenGL_gluTessBeginContour);
        newXS_deffile("OpenGL::gluTessEndContour", XS_OpenGL_gluTessEndContour);
        newXS_deffile("OpenGL::gluTessBeginPolygon", XS_OpenGL_gluTessBeginPolygon);
        newXS_deffile("OpenGL::gluTessEndPolygon", XS_OpenGL_gluTessEndPolygon);
        newXS_deffile("OpenGL::gluTessNormal", XS_OpenGL_gluTessNormal);
        newXS_deffile("OpenGL::gluTessProperty", XS_OpenGL_gluTessProperty);
        newXS_deffile("OpenGL::gluTessCallback", XS_OpenGL_gluTessCallback);
#endif
        newXS_deffile("OpenGL::gluTessVertex_p", XS_OpenGL_gluTessVertex_p);
        newXS_deffile("OpenGL::gluUnProject_p", XS_OpenGL_gluUnProject_p);
#endif

    /* Initialisation Section */

#if XSubPPtmpAAAA
#if XSubPPtmpAAAB
#endif
#if XSubPPtmpAAAC
#endif
#endif
#line 2344 "pogl_glu.c"

    /* End of Initialisation Section */

#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

