Acme-MITHALDU-BleedingOpenGL
view release on metacpan or search on metacpan
pogl_glu.xs view on Meta::CPAN
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 */
MODULE = Acme::MITHALDU::BleedingOpenGL::GLU PACKAGE = Acme::MITHALDU::BleedingOpenGL
( run in 1.528 second using v1.01-cache-2.11-cpan-d80b1682f3f )