Exemplo n.º 1
0
int main(int argc, char** argv)
{
	/* Initialize GLUT and GLEW */
	kuhl_ogl_init(&argc, argv, 512, 512, 32,
	              GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE, 4);

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program("triangle.vert", "triangle.frag");
	glUseProgram(program);
	kuhl_errorcheck();
	/* Set the uniform variable in the shader that is named "red" to the value 1. */
	glUniform1i(kuhl_get_uniform("red"), 1);
	kuhl_errorcheck();
	/* Good practice: Unbind objects until we really need them. */
	glUseProgram(0);

	/* Create kuhl_geometry structs for the objects that we want to
	 * draw. */
	init_geometryTriangle(&triangle, program);
	init_geometryQuad(&quad, program);

	prerendProgram = kuhl_create_program("prerend.vert", "prerend.frag");
	init_geometryQuadPrerender(&prerendQuad, prerendProgram);	

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,0,3}; // location of camera
	float initCamLook[3] = {0,0,0}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
    /* // An alternative approach:
    while(1)
       glutMainLoopEvent();
    */

	exit(EXIT_SUCCESS);
}
Exemplo n.º 2
0
int main(int argc, char** argv)
{
	totalTextures = argc-1;
	if(totalTextures == 0)
	{
		printf("ERROR: Provide textures to use.\n");
		exit(EXIT_FAILURE);
	}
	globalargv = argv;

	/* set up our GLUT window */
	glutInit(&argc, argv);
	glutInitWindowSize(1152, 432); // same aspect ratio as IVS
	/* Ask GLUT to for a double buffered, full color window that
	 * includes a depth buffer */
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow(argv[0]); // set window title to executable name

	/* Initialize GLEW */
	GLenum glewError = glewInit();
	if(glewError != GLEW_OK)
	{
		fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(glewError));
		exit(EXIT_FAILURE);
	}
	kuhl_errorcheck();

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(special_keyboard); // pageup,pagedown, etc

	glClearColor(0.1f, 0.1f, 0.1f, 1.0f);

	// Initialize DGR
	dgr_init();
	projmat_init();

	loadTexture(1);

	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
	exit(EXIT_SUCCESS);
}
Exemplo n.º 3
0
int main(int argc, char** argv)
{
	/* set up our GLUT window */
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	/* Ask GLUT to for a double buffered, full color window that
	 * includes a depth buffer */
#ifdef __APPLE__
	glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
#else
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitContextVersion(3,2);
	glutInitContextProfile(GLUT_CORE_PROFILE);
#endif
	glutCreateWindow(argv[0]); // set window title to executable name

	/* Initialize GLEW */
	glewExperimental = GL_TRUE;
	GLenum glewError = glewInit();
	if(glewError != GLEW_OK)
	{
		fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(glewError));
		exit(EXIT_FAILURE);
	}
	/* When experimental features are turned on in GLEW, the first
	 * call to glGetError() or kuhl_errorcheck() may incorrectly
	 * report an error. So, we call glGetError() to ensure that a
	 * later call to glGetError() will only see correct errors. For
	 * details, see:
	 * http://www.opengl.org/wiki/OpenGL_Loading_Library */
	glGetError();

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program("ogl3-triangle.vert", "ogl3-triangle.frag");
	glUseProgram(program);
	kuhl_errorcheck();
	/* Set the uniform variable in the shader that is named "red" to the value 1. */
	glUniform1i(kuhl_get_uniform("red"), 1);
	kuhl_errorcheck();
	/* Good practice: Unbind objects until we really need them. */
	glUseProgram(0);

	/* Create kuhl_geometry structs for the objects that we want to
	 * draw. */
	init_geometryTriangle(&triangle, program);
	init_geometryQuad(&quad, program);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,0,10}; // location of camera
	float initCamLook[3] = {0,0,0}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
    /* // An alternative approach:
    while(1)
       glutMainLoopEvent();
    */

	exit(EXIT_SUCCESS);
}
Exemplo n.º 4
0
int main(int argc, char** argv)
{
	char *modelFilename    = NULL;
	char *modelTexturePath = NULL;

	int currentArgIndex = 1; // skip program name
	int usageError = 0;
	while(argc > currentArgIndex)
	{
		if(strcmp(argv[currentArgIndex], "--fit") == 0)
			fitToView = 1;
		else if(strcmp(argv[currentArgIndex], "--origin") == 0)
			showOrigin = 1;
		else if(modelFilename == NULL)
		{
			modelFilename = argv[currentArgIndex];
			modelTexturePath = NULL;
		}
		else if(modelTexturePath == NULL)
			modelTexturePath = argv[currentArgIndex];
		else
		{
			usageError = 1;
		}
		currentArgIndex++;
	}

	// If we have no model to load or if there were too many arguments.
	if(modelFilename == NULL || usageError)
	{
		printf("Usage:\n"
		       "%s [--fit] [--origin] modelFile     - Textures are assumed to be in the same directory as the model.\n"
		       "- or -\n"
		       "%s [--fit] [--origin] modelFile texturePath\n"
		       "If the optional --fit parameter is included, the model will be scaled and translated to fit within the approximate view of the camera\n"
		       "If the optional --origin parameter is included, a box will is drawn at the origin and unit-length lines are drawn down each axis.\n",
		       argv[0], argv[0]);
		exit(EXIT_FAILURE);
	}

	/* set up our GLUT window */
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	glutSetOption(GLUT_MULTISAMPLE, 4); // set msaa samples; default to 4
	/* Ask GLUT to for a double buffered, full color window that
	 * includes a depth buffer */
#ifdef __APPLE__
	glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
#else
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
	glutInitContextVersion(3,2);
	glutInitContextProfile(GLUT_CORE_PROFILE);
#endif
	glutCreateWindow(argv[0]); // set window title to executable name
	glEnable(GL_MULTISAMPLE);

	/* Initialize GLEW */
	glewExperimental = GL_TRUE;
	GLenum glewError = glewInit();
	if(glewError != GLEW_OK)
	{
		fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(glewError));
		exit(EXIT_FAILURE);
	}
	/* When experimental features are turned on in GLEW, the first
	 * call to glGetError() or kuhl_errorcheck() may incorrectly
	 * report an error. So, we call glGetError() to ensure that a
	 * later call to glGetError() will only see correct errors. For
	 * details, see:
	 * http://www.opengl.org/wiki/OpenGL_Loading_Library */
	glGetError();

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program(GLSL_VERT_FILE, GLSL_FRAG_FILE);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,1.55,2}; // 1.55m is a good approx eyeheight
	float initCamLook[3] = {0,0,0}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);

	// Clear the screen while things might be loading
	glClearColor(.2,.2,.2,1);
	glClear(GL_COLOR_BUFFER_BIT);

	// Load the model from the file
	modelgeom = kuhl_load_model(modelFilename, modelTexturePath, program, bbox);
	if(showOrigin)
		origingeom = kuhl_load_model("../models/origin/origin.obj", NULL, program, NULL);
	
	init_geometryQuad(&labelQuad, program);

	kuhl_getfps_init(&fps_state);
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
	/* // An alternative approach:
	   while(1)
	   glutMainLoopEvent();
	*/

	exit(EXIT_SUCCESS);
}
Exemplo n.º 5
0
int main( int argc, char* argv[] )
{	
	/* Initialize glut */
	glutInit(&argc, argv); //initialize the toolkit
	glEnable(GL_POINT_SMOOTH);
	glutSetOption(GLUT_MULTISAMPLE, 4); // set msaa samples; default to 4
	
	/* Ask GLUT to for a double buffered, full color window that includes a depth buffer */
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);  //set display mode
	glutInitWindowSize(768, 512); //set window size
	glutInitWindowPosition(0, 0); //set window position on screen
	glutCreateWindow(argv[0]); //open the screen window
	glEnable(GL_MULTISAMPLE);
	
	/* Initialize glew */
	int glew_err = glewInit();
	if(glew_err != GLEW_OK)
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(glew_err));

	/* Initialize call backs */
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	
	/* Initialize DGR */
	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float frustum[6]; // left, right, bottom, top, near, far
	                  // 0     1      2       3    4     5
	projmat_get_frustum(frustum, -1, -1);
	ball.xpos = (frustum[0] + frustum[1])/2.0;
	ball.ypos = (frustum[2] + frustum[3])/2.0;
	ball.speed = ball.minSpeed = (frustum[3]-frustum[2]) / 178.462f;
	
	paddleA.xpos = ball.xpos;
	paddleA.ypos = frustum[3]-(frustum[3]-frustum[2])/20.0;
	paddleA.width = (frustum[1]-frustum[0])/10.0;
	paddleA.increment = paddleA.width / 3.0;
	paddleA.thickness = (frustum[3]-frustum[2])/25.0;
	
	paddleB.xpos = paddleA.xpos;
	paddleB.ypos = frustum[2]+(frustum[3]-frustum[2])/20.0;
	paddleB.width = paddleA.width;
	paddleB.increment = paddleA.increment;
	paddleB.thickness = -paddleA.thickness;
	
	msg(INFO, "Initial ball position %f %f\n", ball.xpos, ball.ypos);
	msg(INFO, "Initial Ball speed: %f\n", frustum[3]-frustum[2], ball.speed);
	msg(INFO, "Initial paddle A position %f %f\n", paddleA.xpos, paddleA.ypos);
	msg(INFO, "Initial paddle B position %f %f\n", paddleB.xpos, paddleB.ypos);

	ball.radius = (frustum[1]-frustum[0])/50.0;
	
	planet[0] = ((frustum[0] + frustum[1])/2.0f) - ((frustum[1] - frustum[0])/2.4f);
	planet[1] = ((frustum[2] + frustum[3])/2.0f) - ((frustum[1] - frustum[0])*1.7f);
	planet[2] = (frustum[1] - frustum[0]);
	
	earth = gluNewQuadric();
	clouds = gluNewQuadric();
	gluQuadricDrawStyle(earth, GLU_FILL);
	gluQuadricTexture(earth, GL_TRUE);
	gluQuadricNormals(earth, GLU_SMOOTH);
	gluQuadricDrawStyle(clouds, GLU_FILL);
	gluQuadricTexture(clouds, GL_TRUE);
	gluQuadricNormals(clouds, GLU_SMOOTH);
		
	kuhl_read_texture_file(EARTH, &texIdEarth);
	kuhl_read_texture_file(CLOUDS, &texIdClouds);
	kuhl_read_texture_file(STARS, &texIdStars);

	glutMainLoop();
	
}
Exemplo n.º 6
0
int main(int argc, char** argv)
{
	/* Initialize GLUT and GLEW */
	kuhl_ogl_init(&argc, argv, 512, 512, 32,
	              GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE, 4);

	
	if(argc != 2 && argc != 3 && argc != 7 && argc != 13)
	{
		printf("Usage for cylindrical panoramas:\n");
		printf("   %s panoImage.jpg\n", argv[0]);
		printf("   %s left.jpg right.jpg\n", argv[0]);
		printf("\n");
		printf("Usage for cubemap panoramas:\n");
		printf("   %s front.jpg back.jpg left.jpg right.jpg down.jpg up.jpg\n", argv[0]);
		printf("   %s Lfront.jpg Lback.jpg Lleft.jpg Lright.jpg Ldown.jpg Lup.jpg Rfront.jpg Rback.jpg Rleft.jpg Rright.jpg Rdown.jpg Rup.jpg\n", argv[0]);
		printf("\n");
		printf("Tip: Works best if horizon is at center of the panorama.\n");
		exit(EXIT_FAILURE);
	}
	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program("texture.vert", "texture.frag");
	glUseProgram(program);
	kuhl_errorcheck();

	init_geometryQuad(&quad, program);
	init_geometryCylinder(&cylinder, program);

	if(argc == 2)
	{
		msg(INFO, "Cylinder mono image: %s\n", argv[1]);
		kuhl_read_texture_file(argv[1], &texIdLeft);
		texIdRight = texIdLeft;
	}
	if(argc == 3)
	{
		msg(INFO, "Cylinder left  image: %s\n", argv[1]);
		kuhl_read_texture_file(argv[1], &texIdLeft);
		msg(INFO, "Cylinder right image: %s\n", argv[2]);
		kuhl_read_texture_file(argv[2], &texIdRight);
	}

	char *cubemapNames[] = { "front", "back", "left", "right", "down", "up" };	
	if(argc == 7)
	{
		for(int i=0; i<6; i++)
		{
			msg(INFO, "Cubemap image (%-5s): %s\n", cubemapNames[i], argv[i+1]);
			kuhl_read_texture_file(argv[i+1], &(cubemapLeftTex[i]));
			cubemapRightTex[i]= cubemapLeftTex[i];
			texIdLeft =0;
			texIdRight=0;
		}
	}
	if(argc == 13)
	{
		for(int i=0; i<6; i++)
		{
			msg(INFO, "Cubemap image (left,  %-5s): %s\n", cubemapNames[i], argv[i+6+1]);
			kuhl_read_texture_file(argv[i+6+1], &(cubemapLeftTex[i]));
			msg(INFO, "Cubemap image (right, %-5s)\n", cubemapNames[i], argv[i+6+1]);
			cubemapRightTex[i]= cubemapLeftTex[i];
			texIdLeft =0;
			texIdRight=0;
		}
	}
	
	
	/* Good practice: Unbind objects until we really need them. */
	glUseProgram(0);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,0,0}; // location of camera
	float initCamLook[3] = {0,0,-1}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
    /* // An alternative approach:
    while(1)
       glutMainLoopEvent();
    */

	exit(EXIT_SUCCESS);
}
Exemplo n.º 7
0
int main(int argc, char** argv)
{
	if(argc == 2)
	{
		modelFilename = argv[1];
		modelTexturePath = NULL;
	}
	else if(argc == 3)
	{
		modelFilename = argv[1];
		modelTexturePath = argv[2];
	}
	else
	{
		printf("Usage:\n"
		       "%s modelFile     - Textures are assumed to be in the same directory as the model.\n"
		       "- or -\n"
		       "%s modelFile texturePath\n", argv[0], argv[0]);
		exit(1);
	}

	/* set up our GLUT window */
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	/* Ask GLUT to for a double buffered, full color window that
	 * includes a depth buffer */
#ifdef __APPLE__
	glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
#else
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
	glutInitContextVersion(3,2);
	glutInitContextProfile(GLUT_CORE_PROFILE);
	glutCreateWindow(argv[0]); // set window title to executable name
#endif
	glEnable(GL_MULTISAMPLE);
	
	/* Initialize GLEW */
	glewExperimental = GL_TRUE;
	GLenum glewError = glewInit();
	if(glewError != GLEW_OK)
	{
		fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(glewError));
		exit(EXIT_FAILURE);
	}
	/* When experimental features are turned on in GLEW, the first
	 * call to glGetError() or kuhl_errorcheck() may incorrectly
	 * report an error. So, we call glGetError() to ensure that a
	 * later call to glGetError() will only see correct errors. For
	 * details, see:
	 * http://www.opengl.org/wiki/OpenGL_Loading_Library */
	glGetError();

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program(GLSL_VERT_FILE, GLSL_FRAG_FILE);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,0,2}; // location of camera
	float initCamLook[3] = {0,0,0}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);

	// Clear the screen while things might be loading
	glClearColor(.2,.2,.2,1);
	glClear(GL_COLOR_BUFFER_BIT);
	glutSwapBuffers();
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
    /* // An alternative approach:
    while(1)
       glutMainLoopEvent();
    */

	exit(EXIT_SUCCESS);
}
Exemplo n.º 8
0
int main(int argc, char** argv)
{
	/* Initialize GLUT and GLEW */
	kuhl_ogl_init(&argc, argv, 512, 512, 32,
	              GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE, 4);

	if(argc == 1)
	{
		msg(FATAL, "You didn't provide the name of the object(s) that you want to track.");
		msg(FATAL, "Usage: %s vrpnObjectName1 vrpnObjectName2 ...");
		exit(EXIT_FAILURE);
	}
	global_argc = argc;
	global_argv = argv;
	
	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program(GLSL_VERT_FILE, GLSL_FRAG_FILE);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	viewmat_init(initCamPos, initCamLook, initCamUp);

	// Clear the screen while things might be loading
	glClearColor(.2,.2,.2,1);
	glClear(GL_COLOR_BUFFER_BIT);

	// Load the model from the file
	//modelgeom = kuhl_load_model("../models/cube/cube.obj", NULL, program, NULL);
	modelgeom = kuhl_load_model("../models/origin/origin.obj", NULL, program, NULL);

	init_geometryQuad(&quad, program);
	label            = malloc(sizeof(GLuint)*argc-1);
	labelAspectRatio = malloc(sizeof(float)*argc-1);
	float labelColor[3] = { 1,1,1 };
	float labelBg[4] = { 0,0,0,.3 };
	for(int i=1; i<argc; i++)
	{
		labelAspectRatio[i-1] = kuhl_make_label(argv[i],
		                                        &(label[i-1]),
		                                        labelColor, labelBg, 24);
	}
	

	kuhl_getfps_init(&fps_state);
	
	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
	/* // An alternative approach:
	   while(1)
	   glutMainLoopEvent();
	*/

	exit(EXIT_SUCCESS);
}
Exemplo n.º 9
0
int main(int argc, char** argv)
{
	char *modelFilename    = NULL;
	char *modelTexturePath = NULL;
	
	if(argc == 2)
	{
		modelFilename = argv[1];
		modelTexturePath = NULL;
	}
	else if(argc == 3)
	{
		modelFilename = argv[1];
		modelTexturePath = argv[2];
	}
	else
	{
		printf("Usage:\n"
		       "%s modelFile     - Textures are assumed to be in the same directory as the model.\n"
		       "- or -\n"
		       "%s modelFile texturePath\n", argv[0], argv[0]);
		exit(1);
	}

	/* set up our GLUT window */
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	/* Ask GLUT to for a double buffered, full color window that
	 * includes a depth buffer */
#ifdef FREEGLUT
	glutSetOption(GLUT_MULTISAMPLE, 4); // set msaa samples; default to 4
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
	glutInitContextVersion(3,2);
	glutInitContextProfile(GLUT_CORE_PROFILE);
#else
	glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
#endif
	glutCreateWindow(argv[0]); // set window title to executable name
	glEnable(GL_MULTISAMPLE);

	/* Initialize GLEW */
	glewExperimental = GL_TRUE;
	GLenum glewError = glewInit();
	if(glewError != GLEW_OK)
	{
		fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(glewError));
		exit(EXIT_FAILURE);
	}
	/* When experimental features are turned on in GLEW, the first
	 * call to glGetError() or kuhl_errorcheck() may incorrectly
	 * report an error. So, we call glGetError() to ensure that a
	 * later call to glGetError() will only see correct errors. For
	 * details, see:
	 * http://www.opengl.org/wiki/OpenGL_Loading_Library */
	glGetError();

	// setup callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);

	/* Compile and link a GLSL program composed of a vertex shader and
	 * a fragment shader. */
	program = kuhl_create_program(GLSL_VERT_FILE, GLSL_FRAG_FILE);

	dgr_init();     /* Initialize DGR based on environment variables. */
	projmat_init(); /* Figure out which projection matrix we should use based on environment variables */

	float initCamPos[3]  = {0,1.55,2}; // 1.55m is a good approx eyeheight
	float initCamLook[3] = {0,0,0}; // a point the camera is facing at
	float initCamUp[3]   = {0,1,0}; // a vector indicating which direction is up
	viewmat_init(initCamPos, initCamLook, initCamUp);

	// Clear the screen while things might be loading
	glClearColor(.2,.2,.2,1);
	glClear(GL_COLOR_BUFFER_BIT);

	// Load the model from the file
	modelgeom = kuhl_load_model(modelFilename, modelTexturePath, program, bbox);

	/* Count the number of kuhl_geometry objects for this model */
	unsigned int geomCount = kuhl_geometry_count(modelgeom);
	
	/* Allocate an array of particle arrays */
	particles = malloc(sizeof(particle*)*geomCount);
	int i = 0;
	for(kuhl_geometry *g = modelgeom; g != NULL; g=g->next)
	{
		/* allocate space to store velocity information for all of the
		 * vertices in this kuhl_geometry */
		particles[i] = malloc(sizeof(particle)*g->vertex_count);
		for(unsigned int j=0; j<g->vertex_count; j++)
			vec3f_set(particles[i][j].velocity, 0,0,0);

		/* Change the geometry to be drawn as points */
		g->primitive_type = GL_POINTS; // Comment out this line to default to triangle rendering.
		i++;
	}

	/* Tell GLUT to start running the main loop and to call display(),
	 * keyboard(), etc callback methods as needed. */
	glutMainLoop();
	/* // An alternative approach:
	   while(1)
	   glutMainLoopEvent();
	*/

	exit(EXIT_SUCCESS);
}