Acme-MITHALDU-BleedingOpenGL
view release on metacpan or search on metacpan
pogl_rpn.xs view on Meta::CPAN
mat = (GLfloat *)oga_mat->data;
}
else
{
count = items - 1;
free_mat = 1;
}
if (!count) croak("No matrix values");
/* Currently only support GLfloat */
for (i=0;i<oga->type_count;i++)
{
if (oga->types[i] != GL_FLOAT)
croak("Unsupported datatype");
}
/* Scalar Multiply */
if (count == 1)
{
GLfloat scalar = mat ? mat[0] : (GLfloat)SvNV(ST(1));
for (i=0;i<len;i++) data[i] *= scalar;
XSRETURN_EMPTY;
}
/* Calc matrix dimension from sqrt of array size */
dim = (int)sqrt(count);
if (count != dim*dim) croak("Not a square matrix");
/* Affine matrix dimension is one element larger than vector data */
cols = dim - 1;
if (len % cols)
croak("Matrix does not match array vector size");
/* Grab affine matrix */
if (!mat)
{
mat = malloc(sizeof(GLfloat) * count);
for (i=0; i<count; i++)
mat[i] = (GLfloat)SvNV(ST(i+1));
}
#if 0 /* Need to figure out why this is slower than CPU calcs */
/* Use GPU if FBOs and Fragment Programs are supported */
fbo_width = gpgpu_width(len);
if (dim == 4 && fbo_width)
{
GLuint target = GL_TEXTURE_RECTANGLE_ARB;
int w = fbo_width;
int h = len / (w*3);
/* Setup and enable FBO */
enable_fbo(oga,w,h,target,GL_RGB32F_ARB,GL_RGB,GL_FLOAT);
/* Pass affine matrix to shader */
enable_affine(oga);
for (i=0;i<4;i++)
{
glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
i,&mat[i<<2]);
}
/* Render to FBO via fragment shader */
glBegin(GL_QUADS);
{
glTexCoord2i(0,0); glVertex2i(0,0);
glTexCoord2i(w,0); glVertex2i(w,0);
glTexCoord2i(w,h); glVertex2i(w,h);
glTexCoord2i(0,h); glVertex2i(0,h);
}
glEnd();
/* Done rendering */
disable_affine(oga);
/* Save back to OGA */
//glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0,0,w,h,GL_RGB,GL_FLOAT,oga->data);
disable_fbo(oga);
}
/* Use CPU to do transform */
else
#endif
{
int s = sizeof(GLfloat) * cols;
GLfloat *vec = malloc(s);
int k,r;
/* Iterate each data row */
for (i=0; i < len; i+=cols)
{
/* Iterate each result column */
for (j=0,r=0; j<cols; j++,r+=dim)
{
vec[j] = 0.0;
/* Iterate each matrix column */
for (k=0; k<cols; k++)
{
vec[j] += data[i+k] * mat[r+k];
}
/* Matrix translate column */
vec[j] += mat[r+cols];
}
memcpy(data+i,vec,s);
}
free(vec);
}
if (free_mat) free(mat);
}
#//# @dimensions = $oga->get_dimensions();
#//- Get OGA data array, by offset and length
void
get_dimensions(oga)
OpenGL::Array oga
PPCODE:
{
int end = oga->dimension_count;
int i = 0;
EXTEND(sp, end);
for (;i<end;i++) {
PUSHs(sv_2mortal(newSViv( oga->dimensions[i] )));
}
}
#// OGA Destructor
void
DESTROY(oga)
OpenGL::Array oga
CODE:
{
#if 0 /* Cleanup for GPU-based affine calcs */
#ifdef GL_ARB_fragment_program
if (oga->affine_handle)
{
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
glDeleteProgramsARB(1,&oga->affine_handle);
}
#endif
#ifdef GL_EXT_framebuffer_object
release_fbo(oga);
#endif
#endif
#if 0
#ifdef GL_ARB_vertex_buffer_object
if (oga->bind)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
glDeleteBuffersARB(1,&oga->bind);
}
#endif
#endif
if (oga->free_data)
{
/* To make sure dangling pointers will be obvious */
memset(oga->data, '\0', oga->data_length);
free(oga->data);
}
free(oga->types);
free(oga->type_offset);
free(oga);
}
#endif /* End IN_POGL_ARRAY_XS */
##################### GLU #########################
############################## GLUT #########################
# /* This is assigned to GLX for now. The glp*() functions should be split out */
( run in 1.358 second using v1.01-cache-2.11-cpan-b16cb0d3907 )