Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /examples/iso2d-spatial/utils/circle.c
ViewVC logotype

View of /examples/iso2d-spatial/utils/circle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2950 - (download) (as text) (annotate)
Wed Mar 4 20:52:35 2015 UTC (4 years, 6 months ago) by lamonts
File size: 4460 byte(s)
Adding the iso2d demo with particle interaction
#include "circle.h"

static void initVertices(Circle * circle, float,int,vec4 color); 
static void circle_initMesh(Circle * circle, GLint); 
static int circle_getNumCircleSegments(float r); 

/* Create an array of circles given a size and radius */ 
Circle * circle_create(int size, float radius, 	vec4 color){
	
	Circle * circles = NULL; 

	if((circles = malloc(sizeof(Circle))) == NULL){
		fprintf(stderr, "Could not allocate space for Circle\n");
		exit(EXIT_FAILURE); 
	}
	if((circles->models = malloc(sizeof(mat4x4) * size)) == NULL){
		fprintf(stderr, "Could not allocate space for Circle\n");
		exit(EXIT_FAILURE); 
	}
	int num_segments = circle_getNumCircleSegments(radius); 
	if((circles->vertices = malloc(sizeof(Vertex) * (num_segments + 2))) == NULL){
		fprintf(stderr, "Could not allocate space for vertices\n");
		exit(EXIT_FAILURE); 
	}
	circles->count = size;
	circles->radius = radius; 
	circles->num_segments = num_segments; 
	initVertices(circles,radius,num_segments,color);
	for(int i = 0; i < size; i++){
		mat4x4_identity(circles->models[i]); 
	}
	return circles; 
}
static void circle_initMesh(Circle * circle,GLint modelLoc) {

	//generate the vertex array object for this mesh (i.e. the simple cube)
    GL_CHECK(glGenVertexArrays (1, &(circle->vaoId)));
    GL_CHECK(glBindVertexArray (circle->vaoId));
	
	//Generate a name for the vertices VBO 
	GL_CHECK(glGenBuffers(1,&circle->vbufId)); 

	//Bind the vertices buffer to the context using the GL_ARRAY_BUFFER target 
	GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,circle->vbufId)); 
	
	// Specify the amount of storage we want to use for the vertices buffer 
	GL_CHECK(glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex) * (circle->num_segments + 2) ,circle->vertices,GL_STATIC_DRAW));

	//Generate a name for the vertices VBO 
	GL_CHECK(glGenBuffers(1,&circle->mbufId)); 
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,circle->mbufId));

    for (unsigned int i = 0; i < 4 ; i++) {
        glEnableVertexAttribArray(modelLoc + i);
        glVertexAttribPointer(modelLoc + i, 4, GL_FLOAT, GL_FALSE, sizeof(mat4x4), 
                                (const GLvoid*)(sizeof(GLfloat) * i * 4));
        glVertexAttribDivisor(modelLoc + i, 1);
    }
}
/* Render a Circle to the screen */ 
void circle_render (Circle * circle, GLint posLoc, GLint colorLoc, GLint modelLoc){
	static bool isInited = false; 

	if(!isInited){
		circle_initMesh(circle,modelLoc); 
		isInited = true; 
	}
	//Bind the meshes VAO id to get the state information 
    GL_CHECK(glBindVertexArray (circle->vaoId));

	//update the circle locations 
	glBindBuffer(GL_ARRAY_BUFFER, circle->mbufId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(mat4x4) *  circle->count, &circle->models[0][0], GL_DYNAMIC_DRAW);

	//Bind our VBO (vertex buffer object) to the GL_ARRAY_BUFFER target 
	GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,circle->vbufId)); 

	//Describe the data that will fill each vertex attribute. In this case, it will be vertices and colors. 
	GL_CHECK(glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(circle->vertices[0]), (GLvoid*)0));
	GL_CHECK(glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, sizeof(circle->vertices[0]), (GLvoid*)sizeof(circle->vertices[0].pos))); 

	//Enable our vertex attributes using the data from the GL_ARRAY_BUFFER 
	GL_CHECK(glEnableVertexAttribArray(posLoc)); 
	GL_CHECK(glEnableVertexAttribArray(colorLoc)); 

	//Render the cube 
	GL_CHECK(glDrawArraysInstanced(GL_TRIANGLE_FAN,0,circle->num_segments + 2,circle->count)); 
	GL_CHECK(glDisableVertexAttribArray(posLoc));
	GL_CHECK(glDisableVertexAttribArray(colorLoc));
}
static void initVertices(Circle * circle, float radius,int num_segments,vec4 color) { 
	
	Vertex v =  {{0.0,0.0,0.0f},{color[0],color[1],color[2],color[3]}}; 
	circle->vertices[0] = v; 

	float theta = 2 * 3.1415926 / (float)num_segments; 
	float c = cosf(theta);//precalculate the sine and cosine
	float s = sinf(theta);
	float t;

	float x = radius;//we start at angle = 0 
	float y = 0; 

	for(int ii = 0; ii < num_segments; ii++) 
	{ 
	    Vertex v = {{x,y,0.0f},{color[0],color[1],color[2],color[3]}}; 
		circle->vertices[ii + 1] = v; 

		//apply the rotation matrix
		t = x;
		x = c * x - s * y;
		y = s * t + c * y;
	}
	Vertex end = {{radius,0,0.0f},{color[0],color[1],color[2],color[3]}}; 
	circle->vertices[num_segments] = end; 
}
static int circle_getNumCircleSegments(float r) 
{ 
	return 500 * sqrtf(r);//change the 10 to a smaller/bigger number as needed
}

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0