mrkd
2/29/2012 - 5:14 AM

transform.cpp

transform.cpp

/*
*Skeleton transform program
* SEIS750
* Spring 2012
**/

#include <GL/Angel.h>
#include <math.h>
#pragma comment(lib, "glew32.lib")

//store window width and height
int ww=500, wh=500;

#define M_PI 3.14159265358979323846

float tx = 1.0;
float ty = 1.0;
float tz = 1.0;

float cube2tx = 1.0;
float cube2ty = 1.0;
float cube2tz = 1.0;

float rx = 0.0;
float ry = 0.0;
float rz = 0.0;

GLuint vao[2];
GLuint vbo[4];

//our modelview and perspective matrices
mat4 mv, p;

//and we'll need pointers to our shader variables
GLuint model_view;
GLuint projection;
GLuint vPosition;
GLuint vColor;

vec4 cubeVerts[36];
vec4 cubeColors[36];

vec4 stageVerts[9];
vec4 stageColors[9];

void key_press (unsigned char key, int x, int y);
void special_key_press (int key, int x, int y);
void my_timer(int v);

void my_timer (int v)
{
	cube2ty += 1.0;
	cube2tx += 1.0;
	glutPostRedisplay();
	glutTimerFunc(1000/v, my_timer, v);
}

void generateCube(){
	for(int i=0; i<6; i++){
		cubeColors[i] = vec4(0.0, 1.0, 1.0, 1.0); //front
	}
	cubeVerts[0] = vec4(1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[1] = vec4(1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[2] = vec4(-1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[3] = vec4(-1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[4] = vec4(-1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[5] = vec4(1.0f, -1.0f, 1.0f, 1.0);


	for(int i=6; i<12; i++){
		cubeColors[i] = vec4(1.0, 0.0, 1.0, 1.0); //back
	}
	cubeVerts[6] = vec4(-1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[7] = vec4(-1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[8] = vec4(1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[9] = vec4(1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[10] = vec4(1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[11] = vec4(-1.0f, -1.0f, -1.0f, 1.0);

	for(int i=12; i<18; i++){
		cubeColors[i] = vec4(1.0, 1.0, 0.0, 1.0); //left
	}
	cubeVerts[12] = vec4(1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[13] = vec4(1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[14] = vec4(1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[15] = vec4(1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[16] = vec4(1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[17] = vec4(1.0f, 1.0f, 1.0f, 1.0);

	for(int i=18; i<24; i++){
		cubeColors[i] = vec4(1.0, 0.0, 0.0, 1.0); //right
	}
	cubeVerts[18] = vec4(-1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[19] = vec4(-1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[20] = vec4(-1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[21] = vec4(-1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[22] = vec4(-1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[23] = vec4(-1.0f, 1.0f, -1.0f, 1.0);

	for(int i=24; i<30; i++){
		cubeColors[i] = vec4(0.0, 0.0, 1.0, 1.0); //top
	}
	cubeVerts[24] = vec4(1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[25] = vec4(1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[26] = vec4(-1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[27] = vec4(-1.0f, 1.0f, -1.0f, 1.0);
	cubeVerts[28] = vec4(-1.0f, 1.0f, 1.0f, 1.0);
	cubeVerts[29] = vec4(1.0f, 1.0f, 1.0f, 1.0);

	for(int i=30; i<36; i++){
		cubeColors[i] = vec4(0.0, 1.0, 0.0, 1.0); //bottom
	}
	cubeVerts[30] = vec4(1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[31] = vec4(1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[32] = vec4(-1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[33] = vec4(-1.0f, -1.0f, 1.0f, 1.0);
	cubeVerts[34] = vec4(-1.0f, -1.0f, -1.0f, 1.0);
	cubeVerts[35] = vec4(1.0f, -1.0f, -1.0f, 1.0);
}


void generateStage() {
	for(int i=0; i<6; i++){
		stageColors[i] = vec4(0.0, 1.0, 1.0, 1.0); //front
	}
	stageVerts[0] = vec4(10.0f, 0.0f, -10.0f, 1.0);
	stageVerts[1] = vec4(10.0f, 0.0f, 10.0f, 1.0);
	stageVerts[2] = vec4(-10.0f, 0.0f, 10.0f, 1.0);
	stageVerts[3] = vec4(-10.0f, 0.0f, 10.0f, 1.0);
	stageVerts[4] = vec4(-10.0f, 0.0f, -10.0f, 1.0);
	stageVerts[5] = vec4(10.0f, 0.0f, -1.0f, 1.0);
}


void display(void)
{
	/*clear all pixels*/
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// we'll explain this later, but it's setting our default modelview matrix
	mv = LookAt(vec4(0, 0, 20, 1.0), vec4(0, 0, 0, 1.0), vec4(0, 1, 0, 0.0));

	// any additional modelview transformations would happen here

	/* Rotation */
	mv = mv*RotateX(rx);
	mv = mv*RotateY(ry);
	mv = mv*RotateZ(rz);

	/* Translation */
	mv = mv*Translate(tx,ty,tz);
	// now that our modelview matrix is all set to go, we send it to our shaders
	// modelview is the same for all vertices in an object, so it's a uniform rather 
	// than an attribute
	glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);

	// and we also need to send our projection matrix, which again is more appropriately
	// a uniform instead of an attribute since it's the same for every vertex
	glUniformMatrix4fv(projection, 1, GL_TRUE, p);

	// Now we have a vertex array that has all of our cube vertex locations and colors
	glBindVertexArray( vao[0] );
	glDrawArrays( GL_TRIANGLES, 0, 36 );    // draw the cube 
	
	/***************/
	/* SECOND CUBE */
	/***************/
	// we'll explain this later, but it's setting our default modelview matrix
	mv = LookAt(vec4(0, 0, 20, 1.0), vec4(0, 0, 0, 1.0), vec4(0, 1, 0, 0.0));
	/* ROTATION */
	mv = mv*RotateY(cube2ty);
	mv = mv*RotateX(cube2tx);
	
	/* TRANSLATE */
	mv = mv*Translate(5,1.0,1.0);
	// now that our modelview matrix is all set to go, we send it to our shaders
	// modelview is the same for all vertices in an object, so it's a uniform rather 
	// than an attribute
	glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);

	// and we also need to send our projection matrix, which again is more appropriately
	// a uniform instead of an attribute since it's the same for every vertex
	glUniformMatrix4fv(projection, 1, GL_TRUE, p);

	// Now we have a vertex array that has all of our cube vertex locations and colors
	// already bound so dont have to rebind - glBindVertexArray( vao[0] );
	glDrawArrays( GL_TRIANGLES, 0, 36 );    // draw the cube 
	

	/*start processing buffered OpenGL routines*/
	glutSwapBuffers();
}

void Keyboard(unsigned char key, int x, int y) {
	/*exit when the escape key is pressed*/
	if (key == 27)
		exit(0);

	switch(key)
	{
		case 'a':
			tz +=1;
			break;
		case 'z':
			tz-=1;
			break;
		case 'r':
			rx += 10;
			printf("rotate angle: %f\n", rx);
			break;
		case 'f':
			rx-=10;
			break;
		case 'g':
			ry-=10;
			break;
		case 'h':
			rz-=10;
			break;
		case 't':
			ry += 10;
			break;
		case 'y':
			rz += 10;
			break;
	}
	glutPostRedisplay();
}

void special_key_press (int key, int x, int y)
{

	switch(key)
	{
	case GLUT_KEY_UP:
		tx+=1;
		break;
	case GLUT_KEY_DOWN:
		tx-=1;
		break;
	case GLUT_KEY_RIGHT:
		ty+=1;
		break;
	case GLUT_KEY_LEFT:
		ty-=1;
		break;
	}
	glutPostRedisplay();

}

void init() {

	/*select clearing (background) color*/
	glClearColor(0.0, 0.0, 0.0, 0.0);


	//populate our arrays
	generateCube();
	generateStage();

	// Load shaders and use the resulting shader program
	GLuint program = InitShader( "vshader-transform.glsl", "fshader-transform.glsl" );
	glUseProgram( program );

	// Create a vertex array object
	glGenVertexArrays( 1, &vao[0] );

	// Create and initialize any buffer objects
	glBindVertexArray( vao[0] );
	glGenBuffers( 2, &vbo[0] );
	glBindBuffer( GL_ARRAY_BUFFER, vbo[0] );
	glBufferData( GL_ARRAY_BUFFER, sizeof(cubeVerts), cubeVerts, GL_STATIC_DRAW);
	// notice that since position is unique for every vertex, we treat it as an 
	// attribute instead of a uniform
	vPosition = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(vPosition);
	glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);

	//and now our colors for each vertex
	glBindBuffer( GL_ARRAY_BUFFER, vbo[1] );
	glBufferData( GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW );
	vColor = glGetAttribLocation(program, "vColor");
	glEnableVertexAttribArray(vColor);
	glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, 0);

	//grab pointers for our modelview and perspecive uniform matrices
	model_view = glGetUniformLocation(program, "model_view");
	projection = glGetUniformLocation(program, "projection");

	//Only draw the things in the front layer
	glEnable(GL_DEPTH_TEST);
}


void reshape(int width, int height){
	ww= width;
	wh = height;
	//field of view angle, aspect ratio, closest distance from camera to object, largest distanec from camera to object
	p = Perspective(45.0, (float)width/(float)height, 1.0, 100.0);

	glViewport( 0, 0, width, height );
}

int main(int argc, char **argv)
{
	/*set up window for display*/
	glutInit(&argc, argv);
	glutInitWindowPosition(0, 0); 
	glutInitWindowSize(ww, wh);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow("Transformations Exercise");  

	glewExperimental = GL_TRUE;

	glewInit();
	init();

	glutDisplayFunc(display);
	glutKeyboardFunc(Keyboard);
	glutSpecialFunc(special_key_press);
	glutReshapeFunc(reshape);
	glutTimerFunc(500,my_timer,60);
	//glutIdleFunc(idle);

	glutMainLoop();
	return 0;
}