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 )