main.cpp
4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#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;
}