void TessellationSampleApp::createIcosahedron()
{
	const int faces[] = {
		2, 1, 0,
		3, 2, 0,
		4, 3, 0,
		5, 4, 0,
		1, 5, 0,
		
		11, 6,	7,
		11, 7,	8,
		11, 8,	9,
		11, 9,	10,
		11, 10, 6,
		
		1, 2, 6,
		2, 3, 7,
		3, 4, 8,
		4, 5, 9,
		5, 1, 10,
		
		2,	7, 6,
		3,	8, 7,
		4,	9, 8,
		5, 10, 9,
		1,	6, 10
	};
	
	const float verts[] = {
		0.000f,	 0.000f,  1.000f,
		0.894f,	 0.000f,  0.447f,
		0.276f,	 0.851f,  0.447f,
		-0.724f,  0.526f,  0.447f,
		-0.724f, -0.526f,  0.447f,
		0.276f, -0.851f,  0.447f,
		0.724f,	 0.526f, -0.447f,
		-0.276f,  0.851f, -0.447f,
		-0.894f,  0.000f, -0.447f,
		-0.276f, -0.851f, -0.447f,
		0.724f, -0.526f, -0.447f,
		0.000f,	 0.000f, -1.000f
	};
	
	mIndexCount = sizeof(faces) / sizeof(faces[0]);
	
	vertexArrayObject->bind();
	
	// Create the VBO for positions:
	GLsizei stride = 3 * sizeof(float);
	vertexBufferObject->bind();
	vertexBufferObject->bufferData(sizeof(verts), verts, GL_STATIC_DRAW);
	gl::enableVertexAttribArray( (GLuint)mPositionIndex );
	gl::vertexAttribPointer( (GLuint)mPositionIndex, 3, GL_FLOAT, GL_FALSE, stride, 0 );
	
	// Create the VBO for indices:
	indexBufferObject->bind();
	indexBufferObject->bufferData( sizeof(faces), faces, GL_STATIC_DRAW );
}
void TransformFeedbackClothSimulationApp::loadBuffers()
{
	int n = 0;
	
	array<vec4, POINTS_TOTAL> positions;
	array<vec3, POINTS_TOTAL> velocities;
	array<ivec4, POINTS_TOTAL> connections;
	
	// We set all connections to -1, because these will only be updated
	// if there are connection indices. Explanation below.
	connections.fill( ivec4( -1 ) );
	
	for( int j = 0; j < POINTS_Y; j++ ) {
		float fj = (float)j / (float)POINTS_Y;
		for( int i = 0; i < POINTS_X; i++ ) {
			float fi = (float)i / (float)POINTS_X;
			
			// This fills the position buffer data, basically makes a grid
			positions[n] = vec4((fi - 0.5f) * (float)POINTS_X,	// x coordinate
								 (fj - 0.5f) * (float)POINTS_Y,	// y coordinate
								 0.6f * sinf(fi) * cosf(fj),	// z coordinate
								 1.0f);							// homogenous coordinate or w
			
			// This allows us to figure out the indices of the four points
			// surrounding the current point. This will be used to index
			// into the texture buffer.
			if( j != (POINTS_Y - 1) ) {	// if it's not one of the top row, don't move
				if( i != 0 )
					connections[n][0] = n - 1;
				if( j != 0 )
					connections[n][1] = n - POINTS_X;
				if( i != (POINTS_X - 1) )
					connections[n][2] = n + 1;
				if( j != (POINTS_Y - 1) )
					connections[n][3] = n + POINTS_X;
			}
			n++;
		}
	}
	
	// Create the Position Buffer with the intial position data
	mPositions[0] = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec4), positions.data(), GL_STATIC_DRAW );
	// Create another Position Buffer that is null, for ping-ponging
	mPositions[1] = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec4), nullptr, GL_STATIC_DRAW );
	
	// Create the Velocity Buffer with the intial velocity data
	mVelocities[0] = gl::Vbo::create( GL_ARRAY_BUFFER, velocities.size() * sizeof(vec3), velocities.data(), GL_STATIC_DRAW );
	// Create another Velocity Buffer that is null, for ping-ponging
	mVelocities[1] = gl::Vbo::create( GL_ARRAY_BUFFER, velocities.size() * sizeof(vec3), nullptr, GL_STATIC_DRAW );
	
	// Create Connection Buffer to index into the Texture Buffer
	mConnections = gl::Vbo::create( GL_ARRAY_BUFFER, connections.size() * sizeof(ivec4), connections.data(), GL_STATIC_DRAW );
	
	for( int i = 0; i < 2; i++ ) {
		// Initialize the Vao's holding the info for each buffer
		mVaos[i] = gl::Vao::create();
		
		// Bind the vao to capture index data for the glsl
		mVaos[i]->bind();
		mPositions[i]->bind();
		gl::vertexAttribPointer( POSITION_INDEX, 4, GL_FLOAT, GL_FALSE, 0, NULL );
		gl::enableVertexAttribArray( POSITION_INDEX );
		
		mVelocities[i]->bind();
		gl::vertexAttribPointer( VELOCITY_INDEX, 3, GL_FLOAT, GL_FALSE, 0, NULL );
		gl::enableVertexAttribArray( VELOCITY_INDEX );
		
		mConnections->bind();
		gl::vertexAttribIPointer( CONNECTION_INDEX, 4, GL_INT, 0, NULL );
		gl::enableVertexAttribArray( CONNECTION_INDEX );
		
		// Create a TransformFeedbackObj, which is similar to Vao
		// It's used to capture the output of a glsl and uses the
		// index of the feedback's varying variable names.
		mFeedbackObjs[i] = gl::TransformFeedbackObj::create();
		
		// Bind the TransformFeedbackObj and bind each corresponding buffer
		// to it's index.
		mFeedbackObjs[i]->bind();
		gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, POSITION_INDEX, mPositions[i] );
		gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, VELOCITY_INDEX, mVelocities[i] );
		mFeedbackObjs[i]->unbind();
		
		// Create Texture buffers to gain access to the lookup tables for
		// calculations in the update shader
		mPosBufferTextures[i] = gl::BufferTexture::create( mPositions[i], GL_RGBA32F );
	}
	
	// Create an element buffer to draw the lines (connections) between the points
	array<uint32_t, CONNECTIONS_TOTAL*2> lineIndices;
	uint32_t * e = lineIndices.data();
	for( int j = 0; j < POINTS_Y; j++ ) {
		for( int i = 0; i < POINTS_X - 1; i++ ) {
			*e++ = i + j * POINTS_X;
			*e++ = 1 + i + j * POINTS_Y;
		}
	}
	
	for( int i = 0; i < POINTS_X; i++ ) {
		for( int j = 0; j < POINTS_Y - 1; j++ ) {
			*e++ = i + j * POINTS_X;
			*e++ = POINTS_X + i + j * POINTS_X;
		}
	}
	
	mLineIndices = lineIndices.size();
	mLineElementBuffer = gl::Vbo::create( GL_ELEMENT_ARRAY_BUFFER, lineIndices.size() * sizeof(uint32_t), lineIndices.data(), GL_STATIC_DRAW );
}