main.cpp 4.04 KB
#include <iostream>

#include <GL/glut.h>

#include <stim/visualization/camera.h>
#include <stim/parser/arguments.h>
#include <stim/visualization/sph_harmonics.h>

#define theta_scale		0.01
#define phi_scale		0.01

//create a global camera that will specify the viewport
stim::camera cam;
int mx, my;			//mouse coordinates in the window space

stim::sph_harmonics S;

float d = 1.5;		//initial distance between the camera and the sphere

bool rotate_zoom = true;	//sets the current camera mode (rotation = true, zoom = false)

stim::arglist args;			//class for processing command line arguments

#ifdef _WIN32
	args.set_ansi(false);
#endif

bool init(){

	//set the clear color to white
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

	//initialize the camera
	cam.setPosition(d, d, d);
	cam.LookAt(0, 0, 0, 0, 1, 1);
	cam.setFOV(40);

	//initialize the texture map stuff	

	srand(time(NULL));
	unsigned int T = 40;
	double c;
	for(unsigned int t = 0; t < T; t++){

		c = (double)rand() / RAND_MAX - 0.5;
		S.push(c);
	}

	S.glInit(256);

	return true;
}

//code that is run every time the user changes something
void display(){
	//clear the screen
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

	//set the projection matrix
	glMatrixMode(GL_PROJECTION);				//put the projection matrix on the stack
	glLoadIdentity();							//set it to the identity matrix
	gluPerspective(cam.getFOV(), 1, 0.001, 1000000);	//set up a perspective projection


	//set the model view matrix
	glMatrixMode(GL_MODELVIEW);					//load the model view matrix to the stack
	glLoadIdentity();							//set it to the identity matrix

	//get the camera parameters
	stim::vec<float, 3> p = cam.getPosition();
	stim::vec<float, 3> u = cam.getUp();
	stim::vec<float, 3> d = cam.getDirection();

	//specify the camera parameters to OpenGL
	gluLookAt(p[0], p[1], p[2], d[0], d[1], d[2], u[0], u[1], u[2]);

	//draw the sphere
	S.glRender();

	//flush commands on the GPU
	glutSwapBuffers();
}

void mouse_press(int button, int state, int x, int y){

	//set the camera motion mode based on the mouse button pressed
	if(button == GLUT_LEFT_BUTTON)
		rotate_zoom = true;
	else if(button == GLUT_MIDDLE_BUTTON)
		rotate_zoom = false;

	//if the mouse is pressed
	if(state == GLUT_DOWN){
		//set the current mouse position
		mx = x;		my = y;
	}
}

void mouse_drag(int x, int y){

	//if the camera is in rotation mode, rotate
	if(rotate_zoom == true){
		float theta = theta_scale * (mx - x);
		float phi = -phi_scale * (my - y);

		//if the mouse is dragged
		cam.OrbitFocus(theta, phi);
	}
	//otherwize zoom
	else{
		cam.Push(my - y);
	}

	//update the mouse position
	mx = x;		my = y;

	glutPostRedisplay();
}

void process_arguments(int argc, char* argv[]){

	args.add("help", "prints this help");

	//process the command line arguments
	args.parse(argc, argv);


	//push all of the arguments to the spherical harmonics class as coefficients
	for(unsigned int a = 0; a < args.nargs(); a++)
		S.push(atof(args.arg(a).c_str()));

	//if the user asks for help, give it and exit
	if(args["help"].is_set()){
		std::cout<<"usage: shview c0 c1 c2 c3 ... --option [A B C]"<<std::endl;
		std::cout<<"examples:"<<std::endl;
		std::cout<<"          shview 1 2 3 4"<<std::endl;
		std::cout<<args.str();
		exit(0);
	}
}

int main(int argc, char *argv[]){

	//initialize GLUT
	glutInit(&argc, argv);

	//process arguments
	process_arguments(argc, argv);

	//set the size of the GLUT window
	glutInitWindowSize(500, 500);

	glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE);

	//create the GLUT window (and an OpenGL context)
	glutCreateWindow("Spherical Harmonic Viewport");

	//set the display function (which will be called repeatedly by glutMainLoop)
	glutDisplayFunc(display);

	//set the mouse press function (called when a mouse button is pressed)
	glutMouseFunc(mouse_press);
	//set the mouse motion function (which will be called any time the mouse is dragged)
	glutMotionFunc(mouse_drag);

	//run the initialization function
	if(!init())
		return 1;	//return an error if it fails


	//enter the main loop
	glutMainLoop();

	//return 0 if everything is awesome
	return 0;



}