Acme-MITHALDU-BleedingOpenGL
view release on metacpan or search on metacpan
pogl_rpn.xs view on Meta::CPAN
break;
}
}
}
}
r += ctx->cols;
}
}
#endif /* End IN_POGL_RPN_XS */
MODULE = Acme::MITHALDU::BleedingOpenGL::RPN PACKAGE = OpenGL::Array
#ifdef IN_POGL_ARRAY_XS
#//# $oga = OpenGL::Array->new($count, @types);
#//- Constructor for multi-type OGA - unpopulated
OpenGL::Array
new(Class, count, type, ...)
GLsizei count
GLenum type
CODE:
{
int oga_len = sizeof(oga_struct);
oga_struct * oga = malloc(oga_len);
int i,j;
memset(oga,0,oga_len);
oga->dimension_count = 1;
oga->dimensions[0] = count;
oga->type_count = items - 2;
oga->item_count = count * (items - 2);
oga->types = malloc(sizeof(GLenum) * oga->type_count);
oga->type_offset = malloc(sizeof(GLint) * oga->type_count);
for(i=0,j=0;i<oga->type_count;i++) {
oga->types[i] = SvIV(ST(i+2));
oga->type_offset[i] = j;
j += gl_type_size(oga->types[i]);
}
oga->total_types_width = j;
oga->data_length = oga->total_types_width *
// ((count + oga->type_count-1) / oga->type_count); # vas is das?
count;
oga->data = malloc(oga->data_length);
memset(oga->data,0,oga->data_length);
oga->free_data = 1;
RETVAL = oga;
}
OUTPUT:
RETVAL
#//# $oga = OpenGL::Array->new_list($type, @data);
#//- Constructor for mono-type OGA - populated
OpenGL::Array
new_list(Class, type, ...)
GLenum type
CODE:
{
int oga_len = sizeof(oga_struct);
oga_struct * oga = malloc(oga_len);
int count = items - 2;
memset(oga,0,oga_len);
oga->dimension_count = 1;
oga->dimensions[0] = count;
oga->type_count = 1;
oga->item_count = count;
oga->total_types_width = gl_type_size(type);
oga->data_length = oga->total_types_width * oga->item_count;
oga->types = malloc(sizeof(GLenum) * oga->type_count);
oga->type_offset = malloc(sizeof(GLint) * oga->type_count);
oga->data = malloc(oga->data_length);
oga->free_data = 1;
oga->type_offset[0] = 0;
oga->types[0] = type;
SvItems(type,2,(GLuint)oga->item_count,oga->data);
RETVAL = oga;
}
OUTPUT:
RETVAL
#//# $oga = OpenGL::Array->new_scalar($type, (PACKED)data, $length);
#//- Constructor for mono-type OGA - populated by string
OpenGL::Array
new_scalar(Class, type, data, length)
GLenum type
SV * data
GLsizei length
CODE:
{
int width = gl_type_size(type);
void * data_s = EL(data, width*length);
int oga_len = sizeof(oga_struct);
oga_struct * oga = malloc(oga_len);
int count = length / width;
memset(oga,0,oga_len);
oga->dimension_count = 1;
oga->dimensions[0] = count;
oga->type_count = 1;
oga->item_count = count;
oga->total_types_width = width;
oga->data_length = length;
oga->types = malloc(sizeof(GLenum) * oga->type_count);
oga->type_offset = malloc(sizeof(GLint) * oga->type_count);
oga->data = malloc(oga->data_length);
oga->free_data = 1;
oga->type_offset[0] = 0;
oga->types[0] = type;
memcpy(oga->data,data_s,oga->data_length);
RETVAL = oga;
}
OUTPUT:
RETVAL
#//# $oga = OpenGL::Array->new_pointer($type, (CPTR)ptr, $elements);
#//- Constructor for mono-type OGA wrapper over a C pointer
OpenGL::Array
new_pointer(Class, type, ptr, elements)
GLenum type
void * ptr
GLsizei elements
CODE:
{
int width = gl_type_size(type);
int oga_len = sizeof(oga_struct);
oga_struct * oga = malloc(sizeof(oga_struct));
memset(oga,0,oga_len);
oga->dimension_count = 1;
oga->dimensions[0] = elements;
oga->type_count = 1;
oga->item_count = elements;
oga->types = malloc(sizeof(GLenum) * oga->type_count);
oga->type_offset = malloc(sizeof(GLint) * oga->type_count);
oga->types[0] = type;
oga->type_offset[0] = 0;
oga->total_types_width = width;
oga->data_length = elements * width;
oga->data = ptr;
oga->free_data = 0;
RETVAL = oga;
}
OUTPUT:
RETVAL
#//# $oga = OpenGL::Array->new_from_pointer((CPTR)ptr, $length);
#//- Constructor for GLubyte OGA wrapper over a C pointer
OpenGL::Array
new_from_pointer(Class, ptr, length)
void * ptr
GLsizei length
CODE:
{
int oga_len = sizeof(oga_struct);
oga_struct * oga = malloc(sizeof(oga_struct));
memset(oga,0,oga_len);
oga->dimension_count = 1;
oga->dimensions[0] = length;
oga->type_count = 1;
oga->item_count = length;
oga->types = malloc(sizeof(GLenum) * oga->type_count);
oga->type_offset = malloc(sizeof(GLint) * oga->type_count);
oga->types[0] = GL_UNSIGNED_BYTE;
oga->type_offset[0] = 0;
oga->total_types_width = 1;
oga->data_length = oga->item_count;
oga->data = ptr;
oga->free_data = 0;
RETVAL = oga;
}
OUTPUT:
RETVAL
#//# $oga->update_pointer((CPTR)ptr);
#//- Replace OGA's C pointer - old one is not released
GLboolean
update_pointer(oga, ptr)
OpenGL::Array oga
void * ptr
CODE:
{
RETVAL = (oga->data != ptr);
oga->data = ptr;
}
OUTPUT:
RETVAL
#//# $oga->bind($vboID);
#//- Bind a VBO to an OGA
void
bind(oga, bind)
OpenGL::Array oga
GLint bind
INIT:
#ifdef GL_ARB_vertex_buffer_object
loadProc(glBindBufferARB,"glBindBufferARB");
#endif
CODE:
{
#ifdef GL_ARB_vertex_buffer_object
oga->bind = bind;
glBindBufferARB(GL_ARRAY_BUFFER_ARB,bind);
#else
croak("OpenGL::Array::bind requires GL_ARB_vertex_buffer_object");
#endif
}
#//# $vboID = $oga->bound();
#//- Return OGA's bound VBO ID
GLint
bound(oga)
OpenGL::Array oga
CODE:
RETVAL = oga->bind;
OUTPUT:
RETVAL
#//# $oga->calc([@(OGA)moreOGAs,]@rpnOPs);
#//- Execute RPN instructions on one or more OGAs
void
calc(...)
CODE:
{
rpn_context * ctx;
oga_struct ** oga_list;
int oga_count = 0;
int ops_count,i;
char ** ops;
/* Determine number of OGAs passed in */
for (i=0; i<items; i++)
{
SV * sv = ST(i);
if (sv == &PL_sv_undef ||
!sv_derived_from(sv,"OpenGL::Array")) break;
oga_count++;
}
/* Grab OGA data buffers */
if (!oga_count) croak("Missing OGA parameters");
ops_count = items - oga_count;
oga_list = malloc(sizeof(oga_struct *) * oga_count);
if (!oga_list) croak("Unable to alloc oga_list");
for (i=0; i<oga_count; i++)
{
IV ref = SvIV((SV*)SvRV(ST(i)));
oga_list[i] = INT2PTR(OpenGL__Array,ref);
}
ops = malloc(sizeof(char *) * ops_count);
if (!ops) croak("Unable to alloc ops");
/* Parse parameters */
for (i=0;i<ops_count;i++)
{
SV * sv = ST(i+oga_count);
char * op = (sv != &PL_sv_undef) ?
(char *)SvPV(sv,PL_na) : "";
ops[i] = op;
}
/* Instantiate RPN context */
ctx = rpn_init(oga_count,oga_list,ops_count,ops);
rpn_exec(ctx);
rpn_term(ctx);
/* Delete lists */
free(ops);
free(oga_list);
}
#//# $oga->assign($pos,@data);
#//- Set OGA values starting from offset
pogl_rpn.xs view on Meta::CPAN
#endif
case GL_UNSIGNED_BYTE:
case GL_BITMAP:
PUSHs(sv_2mortal(newSViv( (*(GLubyte*)offset) )));
offset += sizeof(GLubyte);
break;
case GL_BYTE:
PUSHs(sv_2mortal(newSViv( (*(GLbyte*)offset) )));
offset += sizeof(GLbyte);
break;
case GL_UNSIGNED_SHORT:
PUSHs(sv_2mortal(newSViv( (*(GLushort*)offset) )));
offset += sizeof(GLushort);
break;
case GL_SHORT:
PUSHs(sv_2mortal(newSViv( (*(GLshort*)offset) )));
offset += sizeof(GLshort);
break;
case GL_UNSIGNED_INT:
PUSHs(sv_2mortal(newSViv( (*(GLuint*)offset) )));
offset += sizeof(GLuint);
break;
case GL_INT:
PUSHs(sv_2mortal(newSViv( (*(GLint*)offset) )));
offset += sizeof(GLint);
break;
case GL_FLOAT:
PUSHs(sv_2mortal(newSVnv( (*(GLfloat*)offset) )));
offset += sizeof(GLfloat);
break;
case GL_DOUBLE:
PUSHs(sv_2mortal(newSVnv( (*(GLdouble*)offset) )));
offset += sizeof(GLdouble);
break;
case GL_2_BYTES:
case GL_3_BYTES:
case GL_4_BYTES:
default:
croak("unknown type");
}
}
}
#//# $data = $oga->retrieve_data($pos,$len);
#//- Get OGA data as packed string, by offset and length
SV *
retrieve_data(oga, ...)
OpenGL::Array oga
CODE:
{
GLint pos = (items > 1) ? SvIV(ST(1)) : 0;
GLint len = (items > 2) ? SvIV(ST(2)) : (oga->item_count - pos);
void * offset;
offset = ((char*)oga->data) +
(pos / oga->type_count * oga->total_types_width) +
oga->type_offset[pos % oga->type_count];
RETVAL = newSVpv((char*)offset, len);
}
OUTPUT:
RETVAL
#//# $count = $oga->elements();
#//- Get number of OGA elements
GLsizei
elements(oga)
OpenGL::Array oga
CODE:
RETVAL = oga->item_count;
OUTPUT:
RETVAL
#//# $len = $oga->length();
#//- Get size of OGA in bytes
GLsizei
length(oga)
OpenGL::Array oga
CODE:
RETVAL = oga->data_length;
OUTPUT:
RETVAL
#//# (CPTR)ptr = $oga->ptr();
#//- Get C pointer to OGA data
void *
ptr(oga)
OpenGL::Array oga
CODE:
RETVAL = oga->data;
OUTPUT:
RETVAL
#//# (CPTR)ptr = $oga->offset($pos);
#//- Get C pointer to OGA data, by element offset
void *
offset(oga, pos)
OpenGL::Array oga
GLint pos
CODE:
RETVAL = ((char*)oga->data) +
(pos / oga->type_count * oga->total_types_width) +
oga->type_offset[pos % oga->type_count];
OUTPUT:
RETVAL
#//# $oga->affine((OGA)matrix|@matrix|$scalar);
#//- Perform affine transform on an OGA
void
affine(oga, ...)
OpenGL::Array oga
CODE:
{
GLfloat * data = (GLfloat *)oga->data;
GLfloat * mat = NULL;
int len = oga->item_count;
int fbo_width = 0;
int i,j,count,dim,cols;
SV * sv = ST(1);
int free_mat = 0;
/* Get transform matrix OGA */
if (sv != &PL_sv_undef && sv_derived_from(sv,"OpenGL::Array"))
{
IV ref = SvIV((SV*)SvRV(sv));
oga_struct *oga_mat = INT2PTR(OpenGL__Array,ref);
count = oga_mat->item_count;
for (i=0;i<oga_mat->type_count;i++)
{
if (oga_mat->types[i] != GL_FLOAT)
croak("Unsupported datatype in affine matrix");
}
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;
( run in 0.959 second using v1.01-cache-2.11-cpan-97f6503c9c8 )