Acme-MITHALDU-BleedingOpenGL

 view release on metacpan or  search on metacpan

pogl_rpn.xs  view on Meta::CPAN

      cur->op = RPN_FLR;
    }
    else if (!strcmp(pos,"colget"))
    {
      cur->op = RPN_CGT;
    }
    else if (!strcmp(pos,"colset"))
    {
      cur->op = RPN_CST;
    }
    else if (!strcmp(pos,"rowget"))
    {
      cur->op = RPN_RGT;
    }
    else if (!strcmp(pos,"rowset"))
    {
      cur->op = RPN_RST;
    }
    /* Default to a numeric push */
    else
    {
      cur->op = RPN_PSH;
      cur->value = (float)atof(pos);
      size++;
    }
  }

  /* release string copy */
  if (data) free(data);
  stack->data = malloc(sizeof(GLfloat)*size);
  stack->max_count = size;
  stack->ops = op;
  return(stack);
}

/* Instantiate an RPN Object */
rpn_context * rpn_init(int oga_count,oga_struct ** oga_list,int col_count,char ** col_ops)
{
  rpn_context * ctx = NULL;
  int elements = 0;
  int i,j;

  if (!oga_count) croak("Missing OGA count");
  if (!oga_list) croak("Missing OGA list");
  if (!col_count) croak("Missing column count");

  /* Validate OGAs */
  for (i=0; i<oga_count; i++)
  {
    if (!oga_list[i]) croak("Missing OGA %d",i);
    if (!oga_list[i]->item_count) croak("Empty OGA %d",i);

    /* Check that all OGAs have the same dimension */
    if (!i)
    {
      elements = oga_list[i]->item_count;
      if (elements % col_count) croak("Invalid OGA size for %d columns",col_count);
    }
    else if (elements != oga_list[i]->item_count)
    {
      croak("Invalid length in OGA %d",i);
    }

    /* Only supporting GLfloat for now */
    for (j=0; j<oga_list[i]->type_count; j++)
    {
      if (oga_list[i]->types[j] != GL_FLOAT)
        croak("Unsupported type in OGA %d",i);
    }
  }

  /* Alloc Object data */
  ctx = malloc(sizeof(rpn_context));
  if (!ctx) croak("Unable to alloc rpn context");

  /* Alloc current row store */
  ctx->store = malloc(sizeof(GLfloat) * col_count);
  if (!ctx->store) croak("Unable to alloc rpn store");

  /* Alloc column stack array */
  ctx->stacks = malloc(sizeof(rpn_stack *) * col_count);
  if (!ctx->stacks) croak("Unable to alloc rpn stacks");

  ctx->cols =col_count;
  ctx->rows = elements / col_count;
  ctx->oga_count = oga_count;
  ctx->oga_list = oga_list;

  /* Parse and populate column stacks */
  for (i=0; i<col_count; i++)
    ctx->stacks[i] = rpn_parse(oga_count,col_ops[i]);

  return(ctx);
}

/* Release OP link-list */
void rpn_delete_ops(rpn_op * ops)
{
  if (!ops) return;
  rpn_delete_ops(ops->next);
  free(ops);
}

/* Release OPS stack */
void rpn_delete_stack(rpn_stack * stack)
{
  if (!stack) return;
  rpn_delete_ops(stack->ops);
  free(stack->data);
  free(stack);
}

/* Release RPN Object */
void rpn_term(rpn_context * ctx)
{
  if (ctx)
  {
    int i;
    for (i=0; i<ctx->cols; i++)
      rpn_delete_stack(ctx->stacks[i]);

pogl_rpn.xs  view on Meta::CPAN

            break;
          }
          case RPNF_RETURNROW:
          {
            ((GLfloat *)ctx->oga_list[0]->data)[r+j] = rpn_pop(stack);
            j = ctx->cols;
            break;
          }
          case RPNF_ENDROW:
          {
            j = ctx->cols;
            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;

pogl_rpn.xs  view on Meta::CPAN

				unsigned long v = (unsigned long)SvIV(ST(j));
				(*(GLubyte*)offset) = (GLubyte)(v >> 8);
				offset++;
				(*(GLubyte*)offset) = (GLubyte)v & 0xff;
				offset++;
				break;
			}
			case GL_3_BYTES:
			{
				unsigned long v = (unsigned long)SvIV(ST(j));
				(*(GLubyte*)offset) = (GLubyte)(v >> 16)& 0xff;
				offset++;
				(*(GLubyte*)offset) = (GLubyte)(v >> 8) & 0xff;
				offset++;
				(*(GLubyte*)offset) = (GLubyte)(v >> 0) & 0xff;
				offset++;
				break;
			}
			case GL_4_BYTES:
			{
				unsigned long v = (unsigned long)SvIV(ST(j));
				(*(GLubyte*)offset) = (GLubyte)(v >> 24)& 0xff;
				offset++;
				(*(GLubyte*)offset) = (GLubyte)(v >> 16)& 0xff;
				offset++;
				(*(GLubyte*)offset) = (GLubyte)(v >> 8) & 0xff;
				offset++;
				(*(GLubyte*)offset) = (GLubyte)(v >> 0) & 0xff;
				offset++;
				break;
			}
			default:
				croak("unknown type");
			}
		}
	}

#//# $oga->assign_data($pos,(PACKED)data);
#//- Set OGA values by string, starting from offset
void
assign_data(oga, pos, data)
	OpenGL::Array	oga
	GLint	pos
	SV *	data
	CODE:
	{
		void * offset;
		void * src;
		STRLEN len;
		
		offset = ((char*)oga->data) +
			(pos / oga->type_count * oga->total_types_width) + 
			oga->type_offset[pos % oga->type_count];
		
		src = SvPV(data, len);
		
		memcpy(offset, src, len);
	}

#//# @data = $oga->retrieve($pos,$len);
#//- Get OGA data array, by offset and length
void
retrieve(oga, ...)	
	OpenGL::Array	oga
	PPCODE:
	{
		GLint	pos = (items > 1) ? SvIV(ST(1)) : 0;
		GLint	len = (items > 2) ? SvIV(ST(2)) : (oga->item_count - pos);
		char * offset;
		int end = pos + len;
		int i;

		offset = ((char*)oga->data) +
			(pos / oga->type_count * oga->total_types_width) + 
			oga->type_offset[pos % oga->type_count];
		
		if (end > oga->item_count)
			end = oga->item_count;
		
		EXTEND(sp, end-pos);
		
		i = pos;
		
		for (;i<end;i++) {
			GLenum t = oga->types[i % oga->type_count];
			switch (t) {
#ifdef GL_VERSION_1_2
			case GL_UNSIGNED_BYTE_3_3_2:
			case GL_UNSIGNED_BYTE_2_3_3_REV:
				PUSHs(sv_2mortal(newSViv( (*(GLubyte*)offset) )));
				offset += sizeof(GLubyte);
				break;
			case GL_UNSIGNED_SHORT_5_6_5:
			case GL_UNSIGNED_SHORT_5_6_5_REV:
			case GL_UNSIGNED_SHORT_4_4_4_4:
			case GL_UNSIGNED_SHORT_4_4_4_4_REV:
			case GL_UNSIGNED_SHORT_5_5_5_1:
			case GL_UNSIGNED_SHORT_1_5_5_5_REV:
				PUSHs(sv_2mortal(newSViv( (*(GLushort*)offset) )));
				offset += sizeof(GLushort);
				break;
			case GL_UNSIGNED_INT_8_8_8_8:
			case GL_UNSIGNED_INT_8_8_8_8_REV:
			case GL_UNSIGNED_INT_10_10_10_2:
			case GL_UNSIGNED_INT_2_10_10_10_REV:
				PUSHs(sv_2mortal(newSViv( (*(GLuint*)offset) )));
				offset += sizeof(GLuint);
				break;
#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;

pogl_rpn.xs  view on Meta::CPAN

			{
				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.119 second using v1.01-cache-2.11-cpan-9e1a9122474 )