Commit 8f96cac657af116f86b9c17d53c487e03e5f2a9d
1 parent
09cb5950
pushed old changes
Showing
2 changed files
with
595 additions
and
267 deletions
Show diff stats
CMakeLists.txt
... | ... | @@ -29,6 +29,16 @@ find_package(OpenGL REQUIRED) |
29 | 29 | |
30 | 30 | find_package(GLUT REQUIRED) |
31 | 31 | |
32 | +#GLEW is required for MS Visual C | |
33 | +if(MSVC) | |
34 | + find_package(GLEW REQUIRED) | |
35 | + include_directories(${GLEW_INCLUDE_DIR}) | |
36 | +endif(MSVC) | |
37 | + | |
38 | +#find OpenCV | |
39 | +find_package(OpenCV REQUIRED) | |
40 | +add_definitions(-DUSING_OPENCV) | |
41 | + | |
32 | 42 | #find the pthreads package |
33 | 43 | find_package(Threads) |
34 | 44 | |
... | ... | @@ -50,6 +60,7 @@ include_directories( |
50 | 60 | ${STIM_INCLUDE_DIRS} |
51 | 61 | #${ANN_INCLUDE_DIR} |
52 | 62 | ${Boost_INCLUDE_DIR} |
63 | + ${OpenCV_INCLUDE_DIRS} | |
53 | 64 | ) |
54 | 65 | |
55 | 66 | #Assign source files to the appropriate variables |
... | ... | @@ -68,7 +79,12 @@ target_link_libraries(netmets |
68 | 79 | ${CMAKE_THREAD_LIBS_INIT} |
69 | 80 | #${ANN_LIBRARY} |
70 | 81 | ${X11_LIBRARIES} |
82 | + ${OpenCV_LIBS} | |
71 | 83 | ) |
84 | +if(MSVC) | |
85 | + target_link_libraries(netmets ${GLEW_LIBRARY}) | |
86 | +endif(MSVC) | |
87 | + | |
72 | 88 | |
73 | 89 | #set up copying data files |
74 | 90 | configure_file(data/00_GT.obj ${CMAKE_CURRENT_BINARY_DIR}/00_GT.obj @ONLY) | ... | ... |
main.cu
... | ... | @@ -3,33 +3,70 @@ |
3 | 3 | #include <fstream> |
4 | 4 | #include <algorithm> |
5 | 5 | |
6 | -//OpenGL includes | |
7 | -#include <GL/glut.h> | |
8 | -#include <GL/freeglut.h> | |
9 | - | |
10 | -//STIM includes | |
6 | +// STIM includes | |
7 | +#include <stim/parser/arguments.h> | |
8 | +#include <stim/visualization/camera.h> | |
9 | +#include <stim/gl/gl_texture.h> | |
11 | 10 | #include <stim/visualization/gl_network.h> |
12 | 11 | #include <stim/biomodels/network.h> |
13 | 12 | #include <stim/visualization/gl_aaboundingbox.h> |
14 | -#include <stim/parser/arguments.h> | |
15 | -#include <stim/visualization/camera.h> | |
13 | + | |
14 | +// OpenGL includes | |
15 | +#include <GL/glut.h> | |
16 | +#include <GL/freeglut.h> | |
16 | 17 | |
17 | 18 | #ifdef __CUDACC__ |
18 | 19 | //CUDA includes |
19 | 20 | #include <cuda.h> |
20 | 21 | #endif |
21 | 22 | |
22 | -//BOOST includes | |
23 | +// BOOST includes | |
23 | 24 | #include <boost/tuple/tuple.hpp> |
24 | 25 | |
26 | +<<<<<<< HEAD | |
27 | +// visualization objects | |
28 | +stim::gl_aaboundingbox<float> bb; // axis-aligned bounding box object | |
29 | +stim::camera cam; // camera object | |
30 | +======= | |
25 | 31 | //visualization objects |
26 | 32 | stim::gl_aaboundingbox<float> bb; //axis-aligned bounding box object |
27 | 33 | stim::camera cam; //camera object |
34 | +>>>>>>> 09cb5950f628309ac65c6b85119d3f16e5bcd0a2 | |
28 | 35 | |
29 | -// number of networks | |
30 | -unsigned num_nets = 0; | |
36 | +// overall parameters | |
37 | +unsigned num_nets = 0; // number of networks that've been loaded | |
38 | +float sigma = 3.0; // default sigma(resample rate) equals to 3.0 | |
39 | +float radius = 0.7; // equals to radius | |
40 | +float delta; // camera moving parameter | |
31 | 41 | |
32 | 42 | // networks |
43 | +<<<<<<< HEAD | |
44 | +stim::gl_network<float> GT; // ground truth network | |
45 | +stim::gl_network<float> T; // test network | |
46 | +stim::gl_network<float> _GT; // splitted GT | |
47 | +stim::gl_network<float> _T; // splitted T | |
48 | + | |
49 | +// flags | |
50 | +bool flag_mapping = false; // flag indicates mapping | |
51 | +bool flag_stack = false; // flag indicates loading image stacks | |
52 | +bool flag_adjoint_network = false; // flag indicates render a T overlaid on GT | |
53 | +bool flag_light = false; // flag indicates light on/off | |
54 | +bool flag_highlight_difference; // flag indicates highlight the difference between two networks | |
55 | + | |
56 | +// relationships | |
57 | +std::vector<unsigned> _gt_t; // store indices of nearest edge points in _T for _GT | |
58 | +std::vector<unsigned> _t_gt; // store indices of nearest edge points in _GT for _T | |
59 | + | |
60 | +// hard-coded parameters | |
61 | +float resample_rate = 0.5f; // sample rate for the network (fraction of sigma used as the maximum sample rate) | |
62 | +float camera_factor = 1.2f; // start point of the camera as a function of X and Y size | |
63 | +float orbit_factor = 0.01f; // degrees per pixel used to orbit the camera | |
64 | +float zoom_factor = 10.0f; // zooming factor | |
65 | +float radius_factor = 0.5f; // radius changing factor | |
66 | + | |
67 | +// mouse click | |
68 | +bool LButtonDown = false; // true when left button down | |
69 | +======= | |
33 | 70 | stim::gl_network<float> GT; //ground truth network |
34 | 71 | stim::gl_network<float> T; //test network |
35 | 72 | stim::gl_network<float> _GT; //splitted GT |
... | ... | @@ -51,15 +88,17 @@ float radius_factor = 0.5f; |
51 | 88 | |
52 | 89 | //mouse click |
53 | 90 | bool LButtonDown = false; // true when left button down |
91 | +>>>>>>> 09cb5950f628309ac65c6b85119d3f16e5bcd0a2 | |
54 | 92 | bool RButtonDown = false; |
55 | 93 | |
56 | -//mouse position tracking | |
94 | +// mouse position tracking | |
57 | 95 | int mouse_x; |
58 | 96 | int mouse_y; |
59 | 97 | |
60 | 98 | // render modes |
61 | 99 | bool compareMode = true; // default mode is compare mode |
62 | 100 | bool mappingMode = false; |
101 | +bool volumeMode = false; | |
63 | 102 | |
64 | 103 | // random color set |
65 | 104 | std::vector<float> colormap; |
... | ... | @@ -67,6 +106,14 @@ std::vector<float> colormap; |
67 | 106 | // special key indicator |
68 | 107 | int mods; |
69 | 108 | |
109 | +<<<<<<< HEAD | |
110 | +// OpenGL objects | |
111 | +GLuint cmap_tex = 0; // texture name for the color map | |
112 | + | |
113 | +// Stack view parameter | |
114 | +stim::gl_texture<unsigned char> S; // texture storing the image stack | |
115 | +float planes[3] = { 0.0f, 0.0f, 0.0f }; // plane position in world space | |
116 | +======= | |
70 | 117 | //OpenGL objects |
71 | 118 | GLuint cmap_tex = 0; //texture name for the color map |
72 | 119 | |
... | ... | @@ -76,55 +123,215 @@ float radius = 0.7; //equals to radius |
76 | 123 | int adjoint_fac = 0; |
77 | 124 | int light_fac = 0; |
78 | 125 | int difference_fac = 0; |
126 | +>>>>>>> 09cb5950f628309ac65c6b85119d3f16e5bcd0a2 | |
79 | 127 | |
80 | -//sets an OpenGL viewport taking up the entire window | |
128 | +// sets an OpenGL viewport taking up the entire window | |
81 | 129 | void glut_render_single_projection(){ |
82 | 130 | |
83 | - glMatrixMode(GL_PROJECTION); //load the projection matrix for editing | |
84 | - glLoadIdentity(); //start with the identity matrix | |
85 | - int X = glutGet(GLUT_WINDOW_WIDTH); //use the whole screen for rendering | |
131 | + glMatrixMode(GL_PROJECTION); // load the projection matrix for editing | |
132 | + glLoadIdentity(); // start with the identity matrix | |
133 | + int X = glutGet(GLUT_WINDOW_WIDTH); // use the whole screen for rendering | |
86 | 134 | int Y = glutGet(GLUT_WINDOW_HEIGHT); |
87 | - glViewport(0, 0, X, Y); //specify a viewport for the entire window | |
88 | - float aspect = (float)X / (float)Y; //calculate the aspect ratio | |
89 | - gluPerspective(60, aspect, 0.1, 1000000); //set up a perspective projection | |
135 | + glViewport(0, 0, X, Y); // specify a viewport for the entire window | |
136 | + float aspect = (float)X / (float)Y; // calculate the aspect ratio | |
137 | + gluPerspective(60, aspect, 0.1, 1000000); // set up a perspective projection | |
90 | 138 | } |
91 | 139 | |
92 | -//sets an OpenGL viewport taking up the left half of the window | |
140 | +// sets an OpenGL viewport taking up the left half of the window | |
93 | 141 | void glut_render_left_projection(){ |
94 | 142 | |
95 | - glMatrixMode(GL_PROJECTION); //load the projection matrix for editing | |
96 | - glLoadIdentity(); //start with the identity matrix | |
97 | - int X = glutGet(GLUT_WINDOW_WIDTH) / 2; //only use half of the screen for the viewport | |
143 | + glMatrixMode(GL_PROJECTION); // load the projection matrix for editing | |
144 | + glLoadIdentity(); // start with the identity matrix | |
145 | + int X = glutGet(GLUT_WINDOW_WIDTH) / 2; // only use half of the screen for the viewport | |
98 | 146 | int Y = glutGet(GLUT_WINDOW_HEIGHT); |
99 | - glViewport(0, 0, X, Y); //specify the viewport on the left | |
100 | - float aspect = (float)X / (float)Y; //calculate the aspect ratio | |
101 | - gluPerspective(60, aspect, 0.1, 1000000); //set up a perspective projection | |
147 | + glViewport(0, 0, X, Y); // specify the viewport on the left | |
148 | + float aspect = (float)X / (float)Y; // calculate the aspect ratio | |
149 | + gluPerspective(60, aspect, 0.1, 1000000); // set up a perspective projection | |
102 | 150 | } |
103 | 151 | |
104 | -//sets an OpenGL viewport taking up the right half of the window | |
152 | +// sets an OpenGL viewport taking up the right half of the window | |
105 | 153 | void glut_render_right_projection(){ |
106 | 154 | |
107 | - glMatrixMode(GL_PROJECTION); //load the projection matrix for editing | |
108 | - glLoadIdentity(); //start with the identity matrix | |
109 | - int X = glutGet(GLUT_WINDOW_WIDTH) / 2; //only use half of the screen for the viewport | |
155 | + glMatrixMode(GL_PROJECTION); // load the projection matrix for editing | |
156 | + glLoadIdentity(); // start with the identity matrix | |
157 | + int X = glutGet(GLUT_WINDOW_WIDTH) / 2; // only use half of the screen for the viewport | |
110 | 158 | int Y = glutGet(GLUT_WINDOW_HEIGHT); |
111 | - glViewport(X, 0, X, Y); //specify the viewport on the right | |
112 | - float aspect = (float)X / (float)Y; //calculate the aspect ratio | |
113 | - gluPerspective(60, aspect, 0.1, 1000000); //set up a perspective projection | |
159 | + glViewport(X, 0, X, Y); // specify the viewport on the right | |
160 | + float aspect = (float)X / (float)Y; // calculate the aspect ratio | |
161 | + gluPerspective(60, aspect, 0.1, 1000000); // set up a perspective projection | |
114 | 162 | } |
115 | 163 | |
116 | 164 | void glut_render_modelview(){ |
117 | 165 | |
118 | - glMatrixMode(GL_MODELVIEW); //load the modelview matrix for editing | |
119 | - glLoadIdentity(); //start with the identity matrix | |
120 | - stim::vec3<float> eye = cam.getPosition(); //get the camera position (eye point) | |
121 | - stim::vec3<float> focus = cam.getLookAt(); //get the camera focal point | |
122 | - stim::vec3<float> up = cam.getUp(); //get the camera "up" orientation | |
166 | + glMatrixMode(GL_MODELVIEW); // load the modelview matrix for editing | |
167 | + glLoadIdentity(); // start with the identity matrix | |
168 | + stim::vec3<float> eye = cam.getPosition(); // get the camera position (eye point) | |
169 | + stim::vec3<float> focus = cam.getLookAt(); // get the camera focal point | |
170 | + stim::vec3<float> up = cam.getUp(); // get the camera "up" orientation | |
123 | 171 | |
124 | - gluLookAt(eye[0], eye[1], eye[2], focus[0], focus[1], focus[2], up[0], up[1], up[2]); //set up the OpenGL camera | |
172 | + gluLookAt(eye[0], eye[1], eye[2], focus[0], focus[1], focus[2], up[0], up[1], up[2]); // set up the OpenGL camera | |
125 | 173 | } |
126 | 174 | |
127 | -//draws the network(s) | |
175 | +// draw x slice | |
176 | +void draw_x_slice(float p) { | |
177 | + float x = p; | |
178 | + float y = S.size(1); | |
179 | + float z = S.size(2); | |
180 | + | |
181 | + float tx = p / S.size(0); | |
182 | + | |
183 | + glBegin(GL_QUADS); | |
184 | + glTexCoord3f(tx, 0, 0); | |
185 | + glVertex3f(x, 0, 0); | |
186 | + | |
187 | + glTexCoord3f(tx, 0, 1); | |
188 | + glVertex3f(x, 0, z); | |
189 | + | |
190 | + glTexCoord3f(tx, 1, 1); | |
191 | + glVertex3f(x, y, z); | |
192 | + | |
193 | + glTexCoord3f(tx, 1, 0); | |
194 | + glVertex3f(x, y, 0); | |
195 | + glEnd(); | |
196 | +} | |
197 | +// draw y slice | |
198 | +void draw_y_slice(float p) { | |
199 | + float x = S.size(0); | |
200 | + float y = p; | |
201 | + float z = S.size(2); | |
202 | + | |
203 | + float ty = p / S.size(1); | |
204 | + | |
205 | + glBegin(GL_QUADS); | |
206 | + glTexCoord3f(0, ty, 0); | |
207 | + glVertex3f(0, y, 0); | |
208 | + | |
209 | + glTexCoord3f(0, ty, 1); | |
210 | + glVertex3f(0, y, z); | |
211 | + | |
212 | + glTexCoord3f(1, ty, 1); | |
213 | + glVertex3f(x, y, z); | |
214 | + | |
215 | + glTexCoord3f(1, ty, 0); | |
216 | + glVertex3f(x, y, 0); | |
217 | + glEnd(); | |
218 | +} | |
219 | +// draw z slice | |
220 | +void draw_z_slice(float p) { | |
221 | + float x = S.size(0); | |
222 | + float y = S.size(1); | |
223 | + float z = p; | |
224 | + | |
225 | + float tz = p / S.size(2); | |
226 | + | |
227 | + glBegin(GL_QUADS); | |
228 | + glTexCoord3f(0, 0, tz); | |
229 | + glVertex3f(0, 0, z); | |
230 | + | |
231 | + glTexCoord3f(0, 1, tz); | |
232 | + glVertex3f(0, y, z); | |
233 | + | |
234 | + glTexCoord3f(1, 1, tz); | |
235 | + glVertex3f(x, y, z); | |
236 | + | |
237 | + glTexCoord3f(1, 0, tz); | |
238 | + glVertex3f(x, 0, z); | |
239 | + glEnd(); | |
240 | +} | |
241 | + | |
242 | +/// draw a bounding box around the data set | |
243 | +void draw_box() { | |
244 | + float c[3] = { S.size(0), S.size(1), S.size(2) }; | |
245 | + glLineWidth(1.0); | |
246 | + | |
247 | + glBegin(GL_LINE_LOOP); | |
248 | + glColor3f(0, 0, 0); | |
249 | + glVertex3f(0, 0, 0); | |
250 | + | |
251 | + glColor3f(0, 1, 0); | |
252 | + glVertex3f(0, c[1], 0); | |
253 | + | |
254 | + glColor3f(0, 1, 1); | |
255 | + glVertex3f(0, c[1], c[2]); | |
256 | + | |
257 | + glColor3f(0, 0, 1); | |
258 | + glVertex3f(0, 0, c[2]); | |
259 | + glEnd(); | |
260 | + | |
261 | + glBegin(GL_LINE_LOOP); | |
262 | + glColor3f(1, 0, 0); | |
263 | + glVertex3f(c[0], 0, 0); | |
264 | + | |
265 | + glColor3f(1, 1, 0); | |
266 | + glVertex3f(c[0], c[1], 0); | |
267 | + | |
268 | + glColor3f(1, 1, 1); | |
269 | + glVertex3f(c[0], c[1], c[2]); | |
270 | + | |
271 | + glColor3f(1, 0, 1); | |
272 | + glVertex3f(c[0], 0, c[2]); | |
273 | + glEnd(); | |
274 | + | |
275 | + glBegin(GL_LINES); | |
276 | + glColor3f(0, 0, 0); | |
277 | + glVertex3f(0, 0, 0); | |
278 | + glColor3f(1, 0, 0); | |
279 | + glVertex3f(c[0], 0, 0); | |
280 | + | |
281 | + glColor3f(0, 1, 0); | |
282 | + glVertex3f(0, c[1], 0); | |
283 | + glColor3f(1, 1, 0); | |
284 | + glVertex3f(c[0], c[1], 0); | |
285 | + | |
286 | + glColor3f(0, 1, 1); | |
287 | + glVertex3f(0, c[1], c[2]); | |
288 | + glColor3f(1, 1, 1); | |
289 | + glVertex3f(c[0], c[1], c[2]); | |
290 | + | |
291 | + glColor3f(0, 0, 1); | |
292 | + glVertex3f(0, 0, c[2]); | |
293 | + glColor3f(1, 0, 1); | |
294 | + glVertex3f(c[0], 0, c[2]); | |
295 | + glEnd(); | |
296 | +} | |
297 | +void draw_frames() { | |
298 | + float c[3] = { S.size(0), S.size(1), S.size(2) }; // store the size of the data set for all three dimensions | |
299 | + | |
300 | + glLineWidth(1.0); | |
301 | + glColor3f(1, 0, 0); // draw the X plane | |
302 | + glBegin(GL_LINE_LOOP); | |
303 | + glVertex3f(planes[0], 0, 0); | |
304 | + glVertex3f(planes[0], c[1], 0); | |
305 | + glVertex3f(planes[0], c[1], c[2]); | |
306 | + glVertex3f(planes[0], 0, c[2]); | |
307 | + glEnd(); | |
308 | + | |
309 | + glColor3f(0, 1, 0); // draw the Y plane | |
310 | + glBegin(GL_LINE_LOOP); | |
311 | + glVertex3f(0, planes[1], 0); | |
312 | + glVertex3f(c[0], planes[1], 0); | |
313 | + glVertex3f(c[0], planes[1], c[2]); | |
314 | + glVertex3f(0, planes[1], c[2]); | |
315 | + glEnd(); | |
316 | + | |
317 | + glColor3f(0, 0, 1); // draw the Z plane | |
318 | + glBegin(GL_LINE_LOOP); | |
319 | + glVertex3f(0, 0, planes[2]); | |
320 | + glVertex3f(c[0], 0, planes[2]); | |
321 | + glVertex3f(c[0], c[1], planes[2]); | |
322 | + glVertex3f(0, c[1], planes[2]); | |
323 | + glEnd(); | |
324 | +} | |
325 | + | |
326 | +// enforce bound | |
327 | +void enforce_bounds() { | |
328 | + for (int d = 0; d < 3; d++) { | |
329 | + if (planes[d] < 0) planes[d] = 0; | |
330 | + if (planes[d] > S.size(d)) planes[d] = S.size(d); | |
331 | + } | |
332 | +} | |
333 | + | |
334 | +// draw the network(s) | |
128 | 335 | void glut_render(void) { |
129 | 336 | |
130 | 337 | stim::vec3<float> p1 = cam.getLookAt() + cam.getUp() * 100000; |
... | ... | @@ -144,72 +351,79 @@ void glut_render(void) { |
144 | 351 | |
145 | 352 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); |
146 | 353 | |
147 | - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); | |
148 | - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse1); | |
149 | - glLightfv(GL_LIGHT0, GL_SPECULAR, specular); | |
150 | - glLightfv(GL_LIGHT0, GL_POSITION, position1); | |
354 | + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); // set ambient for light 0 | |
355 | + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse1); // set diffuse for light 0 | |
356 | + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); // set specular for light 0 | |
357 | + glLightfv(GL_LIGHT0, GL_POSITION, position1); // set position for light 0 | |
151 | 358 | |
152 | - glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); | |
153 | - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2); | |
154 | - glLightfv(GL_LIGHT1, GL_SPECULAR, specular); | |
155 | - glLightfv(GL_LIGHT1, GL_POSITION, position2); | |
359 | + glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); // set ambient for light 1 | |
360 | + glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse2); // set diffuse for light 1 | |
361 | + glLightfv(GL_LIGHT1, GL_SPECULAR, specular); // set specular for light 1 | |
362 | + glLightfv(GL_LIGHT1, GL_POSITION, position2); // set position for light 1 | |
156 | 363 | |
157 | 364 | //no mapping, just comparing |
158 | - if (ind == 0) { | |
159 | - if (num_nets == 1) { //if a single network is loaded | |
160 | - glEnable(GL_DEPTH_TEST); //enable depth | |
161 | - glut_render_single_projection(); //fill the entire viewport | |
162 | - glut_render_modelview(); //set up the modelview matrix with camera details | |
163 | - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen | |
164 | - GT.glCenterline0(); //render the GT network (the only one loaded) | |
165 | - glDisable(GL_DEPTH_TEST); | |
365 | + if (!flag_mapping) { | |
366 | + if (num_nets == 1) { // if a single network is loaded | |
367 | + glEnable(GL_DEPTH_TEST); // enable depth | |
368 | + glut_render_single_projection(); // fill the entire viewport | |
369 | + glut_render_modelview(); // set up the modelview matrix with camera details | |
370 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen | |
371 | + if (volumeMode) { | |
372 | + draw_box(); | |
373 | + draw_frames(); | |
374 | + glEnable(GL_TEXTURE_3D); // enable 3D texture mapping | |
375 | + S.bind(); // bind the texture | |
376 | + draw_x_slice(planes[0]); // draw the X plane | |
377 | + draw_y_slice(planes[1]); // draw the Y plane | |
378 | + draw_z_slice(planes[2]); // draw the Z plane | |
379 | + glDisable(GL_TEXTURE_3D); // disable 3D texture mapping | |
380 | + } | |
381 | + glColor3f(1.0f, 1.0f, 1.0f); | |
382 | + GT.glCenterline0(); // render the GT network (the only one loaded) | |
383 | + glDisable(GL_DEPTH_TEST); | |
166 | 384 | } |
167 | 385 | |
168 | - if (num_nets == 2) { //if two networks are loaded | |
169 | - glEnable(GL_TEXTURE_1D); //enable texture mapping | |
170 | - if (light_fac == 0) | |
171 | - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //texture map will be used as the network color | |
386 | + if (num_nets == 2) { // if two networks are loaded | |
387 | + glEnable(GL_TEXTURE_1D); // enable texture mapping | |
388 | + if (flag_light == 0) | |
389 | + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // texture map will be used as the network color | |
172 | 390 | else |
173 | 391 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
174 | - glBindTexture(GL_TEXTURE_1D, cmap_tex); //bind the Brewer texture map | |
392 | + glBindTexture(GL_TEXTURE_1D, cmap_tex); // bind the Brewer texture map | |
175 | 393 | |
176 | - glEnable(GL_DEPTH_TEST); //enable depth | |
177 | - glut_render_left_projection(); //set up a projection for the left half of the window | |
178 | - glut_render_modelview(); //set up the modelview matrix using camera details | |
179 | - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen | |
180 | - | |
181 | - GT.glCylinder(sigma, radius); //render the GT network | |
182 | - //GT.glCenterline(); | |
183 | - if (adjoint_fac == 1) { | |
184 | - glDisable(GL_TEXTURE_1D); //disable texture in order to render in other color | |
185 | - glEnable(GL_BLEND); //enable color blend | |
186 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set blend function | |
187 | - glDisable(GL_DEPTH_TEST); //should disable depth to render transparancy | |
394 | + glEnable(GL_DEPTH_TEST); // enable depth | |
395 | + glut_render_left_projection(); // set up a projection for the left half of the window | |
396 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
397 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen | |
398 | + | |
399 | + GT.glCylinder(sigma, radius); // render the GT network | |
400 | + if (flag_adjoint_network == 1) { | |
401 | + glDisable(GL_TEXTURE_1D); // disable texture in order to render in other color | |
402 | + glEnable(GL_BLEND); // enable color blend | |
403 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
404 | + glDisable(GL_DEPTH_TEST); // should disable depth to render transparancy | |
188 | 405 | glColor4f(0.0f, 0.3f, 0.0f, 0.2f); |
189 | 406 | T.glAdjointCylinder(sigma, radius); |
190 | - //T.glAdjointCenterline(); | |
191 | 407 | glDisable(GL_BLEND); |
192 | 408 | glEnable(GL_DEPTH_TEST); |
193 | 409 | glEnable(GL_TEXTURE_1D); |
194 | 410 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
195 | 411 | } |
196 | 412 | |
197 | - glut_render_right_projection(); //set up a projection for the right half of the window | |
198 | - glut_render_modelview(); //set up the modelview matrix using camera details | |
199 | - | |
200 | - T.glCylinder(sigma, radius); //render the T network | |
201 | - //T.glCenterline(); | |
202 | - if (adjoint_fac == 1) { | |
203 | - glDisable(GL_TEXTURE_1D); //temporarily disable texture | |
204 | - glEnable(GL_BLEND); //enable color blend | |
205 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set blend function | |
206 | - glDisable(GL_DEPTH_TEST); //should disable depth | |
413 | + glut_render_right_projection(); // set up a projection for the right half of the window | |
414 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
415 | + | |
416 | + T.glCylinder(sigma, radius); // render the T network | |
417 | + if (flag_adjoint_network == 1) { | |
418 | + glDisable(GL_TEXTURE_1D); // temporarily disable texture | |
419 | + glEnable(GL_BLEND); // enable color blend | |
420 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
421 | + glDisable(GL_DEPTH_TEST); // should disable depth | |
207 | 422 | glColor4f(0.0f, 0.3f, 0.0f, 0.2f); |
208 | 423 | GT.glAdjointCylinder(sigma, radius); |
209 | - //GT.glAdjointCenterline(); | |
210 | 424 | glDisable(GL_BLEND); |
211 | 425 | glEnable(GL_DEPTH_TEST); |
212 | - glEnable(GL_TEXTURE_1D); //re-enable texture | |
426 | + glEnable(GL_TEXTURE_1D); // re-enable texture | |
213 | 427 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
214 | 428 | } |
215 | 429 | |
... | ... | @@ -220,121 +434,152 @@ void glut_render(void) { |
220 | 434 | |
221 | 435 | //do comparing and mapping |
222 | 436 | else { |
223 | - if (num_nets == 1) { //if a single network is loaded | |
224 | - std::cout << "You should have at least two networks to do mapping." << std::endl; //exit program because there isn't enough network | |
437 | + if (num_nets == 1) { // if a single network is loaded | |
438 | + std::cout << "You should have at least two networks to do mapping." << std::endl; // exit program because there isn't enough network | |
225 | 439 | exit(1); |
226 | 440 | } |
227 | - if (num_nets == 2) { //if two networks are loaded | |
441 | + if (num_nets == 2) { // if two networks are loaded | |
228 | 442 | if (compareMode) { |
229 | - glEnable(GL_TEXTURE_1D); //enable texture mapping | |
230 | - if (light_fac == 0) | |
231 | - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //texture map will be used as the network color | |
443 | + glEnable(GL_TEXTURE_1D); // enable texture mapping | |
444 | + if (flag_light == 0) | |
445 | + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // texture map will be used as the network color | |
232 | 446 | else |
233 | - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//map light to texture | |
234 | - glBindTexture(GL_TEXTURE_1D, cmap_tex); //bind the Brewer texture map | |
447 | + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);// map light to texture | |
448 | + glBindTexture(GL_TEXTURE_1D, cmap_tex); // bind the Brewer texture map | |
235 | 449 | |
236 | - glEnable(GL_DEPTH_TEST); //enable depth | |
237 | - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen | |
238 | - glut_render_left_projection(); //set up a projection for the left half of the window | |
450 | + glEnable(GL_DEPTH_TEST); // enable depth | |
451 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen | |
452 | + glut_render_left_projection(); // set up a projection for the left half of the window | |
239 | 453 | glut_render_modelview(); //set up the modelview matrix using camera details |
240 | 454 | |
241 | - _GT.glCylinder(sigma, radius); //render the GT network | |
242 | - //_GT.glCenterline(); | |
243 | - if (adjoint_fac == 1) { | |
244 | - glDisable(GL_TEXTURE_1D); //temporarily disable texture | |
245 | - glEnable(GL_BLEND); //enable color blend | |
246 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set blend function | |
247 | - glDisable(GL_DEPTH_TEST); //should disable depth | |
455 | + _GT.glCylinder(sigma, radius); // render the GT network | |
456 | + if (flag_adjoint_network == 1) { | |
457 | + glDisable(GL_TEXTURE_1D); // temporarily disable texture | |
458 | + glEnable(GL_BLEND); // enable color blend | |
459 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
460 | + glDisable(GL_DEPTH_TEST); // should disable depth | |
248 | 461 | glColor4f(0.0f, 0.3f, 0.0f, 0.2f); |
249 | 462 | _T.glAdjointCylinder(sigma, radius); |
250 | - //_T.glAdjointCenterline(); | |
251 | 463 | glDisable(GL_BLEND); |
252 | 464 | glEnable(GL_DEPTH_TEST); |
253 | - glEnable(GL_TEXTURE_1D); //re-enable texture | |
465 | + glEnable(GL_TEXTURE_1D); // re-enable texture | |
254 | 466 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
255 | 467 | } |
256 | 468 | |
257 | - glut_render_right_projection(); //set up a projection for the right half of the window | |
258 | - glut_render_modelview(); //set up the modelview matrix using camera details | |
469 | + glut_render_right_projection(); // set up a projection for the right half of the window | |
470 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
259 | 471 | |
260 | - _T.glCylinder(sigma, radius); //render the T network | |
261 | - //_T.glCenterline(); | |
262 | - if (adjoint_fac == 1) { | |
263 | - glDisable(GL_TEXTURE_1D); //temporarily disable texture | |
264 | - glEnable(GL_BLEND); //enable color blend | |
265 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set blend function | |
472 | + _T.glCylinder(sigma, radius); // render the T network | |
473 | + if (flag_adjoint_network == 1) { | |
474 | + glDisable(GL_TEXTURE_1D); // temporarily disable texture | |
475 | + glEnable(GL_BLEND); // enable color blend | |
476 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
266 | 477 | glDisable(GL_DEPTH_TEST); //should disable depth |
267 | 478 | glColor4f(0.0f, 0.3f, 0.0f, 0.2f); |
268 | 479 | _GT.glAdjointCylinder(sigma, radius); |
269 | - //_GT.glAdjointCenterline(); | |
270 | 480 | glDisable(GL_BLEND); |
271 | 481 | glEnable(GL_DEPTH_TEST); |
272 | - glEnable(GL_TEXTURE_1D); //re-enable texture | |
482 | + glEnable(GL_TEXTURE_1D); // re-enable texture | |
273 | 483 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
274 | 484 | } |
275 | 485 | |
276 | - sigma = radius; //set sigma equal to radius | |
486 | + sigma = radius; // set sigma equal to radius | |
277 | 487 | glDisable(GL_TEXTURE_1D); |
278 | 488 | } |
279 | - else { | |
489 | + else if (mappingMode) { | |
280 | 490 | glEnable(GL_COLOR_MATERIAL); |
281 | - glEnable(GL_DEPTH_TEST); //enable depth | |
282 | - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the screen | |
283 | - glut_render_left_projection(); //set up a projection for the left half of the window | |
284 | - glut_render_modelview(); //set up the modelview matrix using camera details | |
491 | + glEnable(GL_DEPTH_TEST); // enable depth | |
492 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen | |
493 | + glut_render_left_projection(); // set up a projection for the left half of the window | |
494 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
285 | 495 | |
286 | - if (difference_fac == 0) | |
496 | + if (flag_highlight_difference == 0) | |
287 | 497 | _GT.glRandColorCylinder(0, _gt_t, colormap, sigma, radius); |
288 | - //_GT.glRandColorCenterline(0, _gt_t, colormap); | |
289 | 498 | else |
290 | 499 | _GT.glDifferenceCylinder(0, _gt_t, colormap, sigma, radius); |
291 | 500 | |
292 | 501 | |
293 | - glut_render_right_projection(); //set up a projection for the right half of the window | |
294 | - glut_render_modelview(); //set up the modelview matrix using camera details | |
502 | + glut_render_right_projection(); // set up a projection for the right half of the window | |
503 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
295 | 504 | |
296 | - if (difference_fac == 0) | |
505 | + if (flag_highlight_difference == 0) | |
297 | 506 | _T.glRandColorCylinder(1, _t_gt, colormap, sigma, radius); |
298 | - //_T.glRandColorCenterline(1, _t_gt, colormap); | |
299 | 507 | else |
300 | 508 | _T.glDifferenceCylinder(1, _t_gt, colormap, sigma, radius); |
301 | 509 | |
302 | - sigma = radius; //set sigma equal to radius | |
510 | + sigma = radius; // set sigma equal to radius | |
511 | + } | |
512 | + else if (volumeMode) { | |
513 | + | |
514 | + glEnable(GL_DEPTH_TEST); // enable depth | |
515 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen | |
516 | + glut_render_left_projection(); // set up a projection for the left half of the window | |
517 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
518 | + | |
519 | + draw_box(); | |
520 | + draw_frames(); | |
521 | + glDisable(GL_TEXTURE_1D); // disable 1D texture | |
522 | + glEnable(GL_TEXTURE_3D); // enable 3D texture mapping | |
523 | + S.bind(); // bind the texture | |
524 | + draw_x_slice(planes[0]); // draw the X plane | |
525 | + draw_y_slice(planes[1]); // draw the Y plane | |
526 | + draw_z_slice(planes[2]); // draw the Z plane | |
527 | + glDisable(GL_TEXTURE_3D); // disable 3D texture mapping | |
528 | + GT.glCylinder(sigma, radius); | |
529 | + | |
530 | + glut_render_right_projection(); // set up a projection for the right half of the window | |
531 | + glut_render_modelview(); // set up the modelview matrix using camera details | |
532 | + | |
533 | + draw_box(); | |
534 | + draw_frames(); | |
535 | + glDisable(GL_TEXTURE_1D); // disable 1D texture | |
536 | + glEnable(GL_TEXTURE_3D); // enable 3D texture mapping | |
537 | + S.bind(); // bind the texture | |
538 | + draw_x_slice(planes[0]); // draw the X plane | |
539 | + draw_y_slice(planes[1]); // draw the Y plane | |
540 | + draw_z_slice(planes[2]); // draw the Z plane | |
541 | + glDisable(GL_TEXTURE_3D); // disable 3D texture mapping | |
542 | + T.glCylinder(sigma, radius); | |
543 | + glColor3f(1.0f, 1.0f, 1.0f); | |
544 | + | |
545 | + sigma = radius; | |
303 | 546 | } |
304 | 547 | } |
305 | 548 | } |
306 | 549 | glDisable(GL_DEPTH_TEST); |
307 | 550 | |
308 | - if (num_nets == 2) { // works only with two networks | |
551 | + if (num_nets == 2) { // works only with two networks | |
309 | 552 | std::ostringstream ss; |
310 | - if (mappingMode) // if it is in mapping mode | |
553 | + if (mappingMode) // if it is in mapping mode | |
311 | 554 | ss << "Mapping Mode"; |
555 | + else if (compareMode) | |
556 | + ss << "Compare Mode"; // default mode is compare mode | |
312 | 557 | else |
313 | - ss << "Compare Mode"; // default mode is compare mode | |
558 | + ss << "volumeDisplay"; | |
314 | 559 | |
315 | - if (light_fac == 1) | |
560 | + if (flag_light == 1) | |
316 | 561 | glDisable(GL_LIGHTING); |
317 | - glMatrixMode(GL_PROJECTION); // set up the 2d viewport for mode text printing | |
562 | + glMatrixMode(GL_PROJECTION); // set up the 2d viewport for mode text printing | |
318 | 563 | glPushMatrix(); |
319 | 564 | glLoadIdentity(); |
320 | - int X = glutGet(GLUT_WINDOW_WIDTH); // get the current window width | |
321 | - int Y = glutGet(GLUT_WINDOW_HEIGHT); // get the current window height | |
322 | - glViewport(0, 0, X / 2, Y); // locate to left bottom corner | |
323 | - gluOrtho2D(0, X, 0, Y); // define othogonal aspect | |
324 | - glColor3f(0.8, 0.0, 0.0); // using red to show mode | |
565 | + int X = glutGet(GLUT_WINDOW_WIDTH); // get the current window width | |
566 | + int Y = glutGet(GLUT_WINDOW_HEIGHT); // get the current window height | |
567 | + glViewport(0, 0, X / 2, Y); // locate to left bottom corner | |
568 | + gluOrtho2D(0, X, 0, Y); // define othogonal aspect | |
569 | + glColor3f(0.8, 0.0, 0.0); // using red to show mode | |
325 | 570 | |
326 | 571 | glMatrixMode(GL_MODELVIEW); |
327 | 572 | glPushMatrix(); |
328 | 573 | glLoadIdentity(); |
329 | 574 | |
330 | - glRasterPos2f(0, 5); //print text in the left bottom corner | |
575 | + glRasterPos2f(0, 5); //print text in the left bottom corner | |
331 | 576 | glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, (const unsigned char*)(ss.str().c_str())); |
332 | 577 | |
333 | 578 | glPopMatrix(); |
334 | 579 | glMatrixMode(GL_PROJECTION); |
335 | 580 | glPopMatrix(); |
336 | - glColor3f(1.0, 1.0, 1.0); //clear red color | |
337 | - if (light_fac == 1) | |
581 | + glColor3f(1.0, 1.0, 1.0); //clear red color | |
582 | + if (flag_light == 1) | |
338 | 583 | glEnable(GL_LIGHTING); |
339 | 584 | } |
340 | 585 | |
... | ... | @@ -346,31 +591,55 @@ void glut_render(void) { |
346 | 591 | // defines camera motion based on mouse dragging |
347 | 592 | void glut_motion(int x, int y){ |
348 | 593 | |
349 | - if(LButtonDown == true && RButtonDown == false && mods != GLUT_ACTIVE_CTRL){ | |
594 | + int mods = glutGetModifiers(); | |
595 | + if(LButtonDown == true && RButtonDown == false && mods == 0){ | |
350 | 596 | |
351 | - float theta = orbit_factor * (mouse_x - x); //determine the number of degrees along the x-axis to rotate | |
352 | - float phi = orbit_factor * (y - mouse_y); //number of degrees along the y-axis to rotate | |
597 | + float theta = orbit_factor * (mouse_x - x); // determine the number of degrees along the x-axis to rotate | |
598 | + float phi = orbit_factor * (y - mouse_y); // number of degrees along the y-axis to rotate | |
353 | 599 | |
354 | - cam.OrbitFocus(theta, phi); //rotate the camera around the focal point | |
600 | + cam.OrbitFocus(theta, phi); // rotate the camera around the focal point | |
601 | + } | |
602 | + else if (mods != 0) { | |
603 | + float dx = (float)(x - mouse_x); | |
604 | + float dist = dx; // calculate the distance that the mouse moved in pixel coordinates | |
605 | + float sdist = dist; // scale the distance by the sensitivity | |
606 | + if (mods == GLUT_ACTIVE_SHIFT) { // if the SHIFT key is pressed | |
607 | + planes[0] += (sdist)* S.spacing(0); // move the X plane based on the mouse wheel direction | |
608 | + } | |
609 | + else if (mods == GLUT_ACTIVE_CTRL) { // if the CTRL key is pressed | |
610 | + planes[1] += (sdist)* S.spacing(1); // move the Y plane based on the mouse wheel direction | |
611 | + } | |
612 | + else if (mods == GLUT_ACTIVE_ALT) { // if hte ALT key is pressed | |
613 | + planes[2] += (sdist)* S.spacing(2); // move the Z plane based on the mouse wheel direction | |
614 | + } | |
615 | + enforce_bounds(); | |
616 | + } | |
355 | 617 | |
356 | - mouse_x = x; //update the mouse position | |
618 | + mouse_x = x; // update the mouse position | |
357 | 619 | mouse_y = y; |
358 | - | |
359 | - glutPostRedisplay(); //re-draw the visualization | |
360 | - } | |
620 | + | |
621 | + glutPostRedisplay(); // re-draw the visualization | |
361 | 622 | } |
362 | 623 | |
363 | 624 | // sets the menu options |
364 | 625 | void glut_menu(int value) { |
626 | + | |
365 | 627 | if (value == 1) { // menu 1 represents comparing mode |
366 | 628 | compareMode = true; |
367 | 629 | mappingMode = false; |
630 | + volumeMode = false; | |
368 | 631 | } |
369 | 632 | if (value == 2) { // menu 2 represents mapping mode |
370 | 633 | compareMode = false; |
371 | 634 | mappingMode = true; |
635 | + volumeMode = false; | |
636 | + } | |
637 | + if (value == 3) { // menu 3 represents volume mode | |
638 | + compareMode = false; | |
639 | + mappingMode = false; | |
640 | + volumeMode = true; | |
372 | 641 | } |
373 | - if (value == 3) { | |
642 | + if (value == 4) { | |
374 | 643 | exit(0); |
375 | 644 | } |
376 | 645 | glutPostRedisplay(); |
... | ... | @@ -399,39 +668,28 @@ void glut_mouse(int button, int state, int x, int y){ |
399 | 668 | mouse_y = y; |
400 | 669 | RButtonDown = false; |
401 | 670 | } |
402 | - | |
403 | - /// implementation of mouse click mapping feedback | |
404 | - mods = glutGetModifiers(); // get modifier keys | |
405 | - if (mods == GLUT_ACTIVE_CTRL) // if the CTRL key is pressed | |
406 | - if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { | |
407 | - std::cout << "( " << x << ", " << y << " )" << std::endl; // if the CTRL key is pressed and LEFT BUTTON is DOWN, print the window coordinates | |
408 | - | |
409 | - GLint viewport[4]; | |
410 | - GLdouble modelview[16]; | |
411 | - GLdouble projection[16]; | |
412 | - GLdouble winX, winY, winZ; | |
413 | - GLdouble posX, posY, posZ; | |
414 | - | |
415 | - glGetIntegerv(GL_VIEWPORT, viewport); | |
416 | - glGetDoublev(GL_MODELVIEW_MATRIX, modelview); | |
417 | - glGetDoublev(GL_PROJECTION_MATRIX, projection); | |
418 | - | |
419 | - winX = (GLdouble)x; | |
420 | - winY = viewport[3] - (GLdouble)y; | |
421 | - glReadPixels((GLint)winX, (GLint)winY, (GLsizei)1, (GLsizei)1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); // need frame buffer FBO | |
422 | - gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); // not sure why it should add 1 to the winZ | |
423 | - | |
424 | - std::cout << "( " << posX << ", " << posY << ", "<< posZ <<" )" << std::endl; | |
425 | - } | |
426 | 671 | } |
427 | 672 | |
428 | 673 | // define camera move based on mouse wheel move(actually we can combine this with glut_mouse) |
429 | 674 | void glut_wheel(int wheel, int direction, int x, int y) { |
430 | - | |
431 | - if (direction > 0) // if it is button 3(up), move closer | |
432 | - delta = zoom_factor; | |
433 | - else // if it is button 4(down), leave farther | |
434 | - delta = -zoom_factor; | |
675 | + | |
676 | + int mods = glutGetModifiers(); | |
677 | + if (mods == GLUT_ACTIVE_SHIFT) { // if the SHIFT key is pressed | |
678 | + planes[0] += (direction)* S.spacing(0); // move the X plane based on the mouse wheel direction | |
679 | + } | |
680 | + else if (mods == GLUT_ACTIVE_CTRL) { // if the CTRL key is pressed | |
681 | + planes[1] += (direction)* S.spacing(1); // move the Y plane based on the mouse wheel direction | |
682 | + } | |
683 | + else if (mods == GLUT_ACTIVE_ALT) { // if hte ALT key is pressed | |
684 | + planes[2] += (direction)* S.spacing(2); // move the Z plane based on the mouse wheel direction | |
685 | + } | |
686 | + else { | |
687 | + if (direction > 0) // if it is button 3(up), move closer | |
688 | + delta = zoom_factor; | |
689 | + else // if it is button 4(down), leave farther | |
690 | + delta = -zoom_factor; | |
691 | + } | |
692 | + enforce_bounds(); | |
435 | 693 | |
436 | 694 | cam.Push(delta); |
437 | 695 | glutPostRedisplay(); |
... | ... | @@ -444,17 +702,25 @@ void glut_keyboard(unsigned char key, int x, int y){ |
444 | 702 | switch (key) { |
445 | 703 | |
446 | 704 | // change render mode |
447 | - case 'm': // if keyboard 'm' is pressed, then change render mode | |
448 | - if (compareMode && !mappingMode && ind && !adjoint_fac) { // if current mode is comparing mode | |
705 | + case 'm': // if keyboard 'm' is pressed, then change render mode | |
706 | + if (compareMode && !mappingMode && flag_mapping && !flag_adjoint_network) { // if current mode is comparing mode | |
449 | 707 | compareMode = false; |
450 | 708 | mappingMode = true; |
451 | 709 | } |
452 | - else if (!compareMode && mappingMode && ind && !adjoint_fac) { // if current mode is mapping mode | |
710 | + else if (!compareMode && mappingMode && flag_mapping && !flag_adjoint_network) {// if current mode is mapping mode | |
453 | 711 | compareMode = true; |
454 | 712 | mappingMode = false; |
455 | 713 | } |
456 | 714 | break; |
457 | 715 | |
716 | + // render the image stack | |
717 | + case 'v': | |
718 | + if (!volumeMode && !flag_mapping) | |
719 | + volumeMode = true; | |
720 | + else if (volumeMode && !flag_mapping) | |
721 | + volumeMode = false; | |
722 | + break; | |
723 | + | |
458 | 724 | // zooming |
459 | 725 | case 'w': // if keyboard 'w' is pressed, then move closer |
460 | 726 | delta = zoom_factor; |
... | ... | @@ -478,14 +744,14 @@ void glut_keyboard(unsigned char key, int x, int y){ |
478 | 744 | |
479 | 745 | // turn on/off the light |
480 | 746 | case 'l': // if keyboard 'l' is pressed, then change the light |
481 | - if (!light_fac && !adjoint_fac) { | |
482 | - light_fac = 1; | |
747 | + if (!flag_light && !flag_adjoint_network) { | |
748 | + flag_light = 1; | |
483 | 749 | glEnable(GL_LIGHTING); |
484 | 750 | glEnable(GL_LIGHT0); |
485 | 751 | glEnable(GL_LIGHT1); |
486 | 752 | } |
487 | - else if (light_fac && !adjoint_fac) { | |
488 | - light_fac = 0; | |
753 | + else if (flag_light && !flag_adjoint_network) { | |
754 | + flag_light = 0; | |
489 | 755 | glDisable(GL_LIGHTING); |
490 | 756 | glDisable(GL_LIGHT0); |
491 | 757 | glDisable(GL_LIGHT1); |
... | ... | @@ -493,19 +759,19 @@ void glut_keyboard(unsigned char key, int x, int y){ |
493 | 759 | break; |
494 | 760 | |
495 | 761 | // render a transparant T very close to GT in compare mode |
496 | - case 32: // if keyboard 'SPACE' is pressed, then change the adjoint_fac | |
497 | - if (!adjoint_fac && compareMode && !light_fac) | |
498 | - adjoint_fac = 1; | |
499 | - else if (adjoint_fac && compareMode && !light_fac) | |
500 | - adjoint_fac = 0; | |
762 | + case 32: // if keyboard 'SPACE' is pressed, then change the flag_adjoint_network | |
763 | + if (!flag_adjoint_network && compareMode && !flag_light) | |
764 | + flag_adjoint_network = 1; | |
765 | + else if (flag_adjoint_network && compareMode && !flag_light) | |
766 | + flag_adjoint_network = 0; | |
501 | 767 | break; |
502 | 768 | |
503 | 769 | // render only the difference |
504 | 770 | case 'h': |
505 | - if (!difference_fac && mappingMode && !light_fac) | |
506 | - difference_fac = 1; | |
507 | - else if (difference_fac && mappingMode && !light_fac) | |
508 | - difference_fac = 0; | |
771 | + if (!flag_highlight_difference && mappingMode && !flag_light) | |
772 | + flag_highlight_difference = 1; | |
773 | + else if (flag_highlight_difference && mappingMode && !flag_light) | |
774 | + flag_highlight_difference = 0; | |
509 | 775 | break; |
510 | 776 | |
511 | 777 | // close window and exit application |
... | ... | @@ -515,11 +781,11 @@ void glut_keyboard(unsigned char key, int x, int y){ |
515 | 781 | glutPostRedisplay(); |
516 | 782 | } |
517 | 783 | |
518 | -#define BREWER_CTRL_PTS 11 //number of control points in the Brewer map | |
784 | +#define BREWER_CTRL_PTS 11 // number of control points in the Brewer map | |
519 | 785 | void texture_initialize(){ |
520 | 786 | |
521 | 787 | //define the colormap |
522 | - static float brewer_map[BREWER_CTRL_PTS][3] = { //generate a Brewer color map (blue to red) | |
788 | + static float brewer_map[BREWER_CTRL_PTS][3] = { // generate a Brewer color map (blue to red) | |
523 | 789 | {0.192157f, 0.211765f, 0.584314f}, |
524 | 790 | {0.270588f, 0.458824f, 0.705882f}, |
525 | 791 | {0.454902f, 0.678431f, 0.819608f}, |
... | ... | @@ -533,58 +799,70 @@ void texture_initialize(){ |
533 | 799 | {0.647059f, 0.0f, 0.14902f} |
534 | 800 | }; |
535 | 801 | |
536 | - glGenTextures(1, &cmap_tex); //generate a texture map name | |
537 | - glBindTexture(GL_TEXTURE_1D, cmap_tex); //bind the texture map | |
802 | + glGenTextures(1, &cmap_tex); // generate a texture map name | |
803 | + glBindTexture(GL_TEXTURE_1D, cmap_tex); // bind the texture map | |
538 | 804 | |
539 | - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //enable linear interpolation | |
805 | + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // enable linear interpolation | |
540 | 806 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
541 | - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); //clamp the values at the minimum and maximum | |
542 | - glTexImage1D(GL_TEXTURE_1D, 0, 3, BREWER_CTRL_PTS, 0, GL_RGB, GL_FLOAT, //upload the texture map to the GPU | |
807 | + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); // clamp the values at the minimum and maximum | |
808 | + glTexImage1D(GL_TEXTURE_1D, 0, 3, BREWER_CTRL_PTS, 0, GL_RGB, GL_FLOAT, // upload the texture map to the GPU | |
543 | 809 | brewer_map); |
810 | + if (flag_stack == 1) { | |
811 | + S.attach(); // attach 3D texture | |
812 | + } | |
544 | 813 | } |
545 | 814 | |
546 | -//Initialize the OpenGL (GLUT) window, including starting resolution, callbacks, texture maps, and camera | |
815 | +// Initialize the OpenGL (GLUT) window, including starting resolution, callbacks, texture maps, and camera | |
547 | 816 | void glut_initialize(){ |
548 | 817 | |
549 | - int myargc = 1; //GLUT requires arguments, so create some bogus ones | |
818 | + int myargc = 1; // GLUT requires arguments, so create some bogus ones | |
550 | 819 | char* myargv[1]; |
551 | 820 | myargv [0]=strdup ("netmets"); |
552 | 821 | |
553 | - glutInit(&myargc, myargv); //pass bogus arguments to glutInit() | |
822 | + glutInit(&myargc, myargv); // pass bogus arguments to glutInit() | |
554 | 823 | glutSetOption(GLUT_MULTISAMPLE, 8); |
555 | - glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); //generate a color buffer, depth buffer, and enable double buffering | |
556 | - glutInitWindowPosition(100,100); //set the initial window position | |
557 | - glutInitWindowSize(320, 320); //set the initial window size | |
558 | - glutCreateWindow("NetMets - STIM Lab, UH"); //set the dialog box title | |
824 | + glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); // generate a color buffer, depth buffer, and enable double buffering | |
825 | + glutInitWindowPosition(100,100); // set the initial window position | |
826 | + glutInitWindowSize(320, 320); // set the initial window size | |
827 | + glutCreateWindow("NetMets - STIM Lab, UH"); // set the dialog box title | |
828 | + | |
829 | +#ifdef _WIN32 | |
830 | + GLenum err = glewInit(); // initialize GLEW (necessary for Windows) | |
831 | + if (GLEW_OK != err) { // eror with GLEW | |
832 | + std::cout << "Error with GLEW: " << glewGetErrorString(err) << std::endl; | |
833 | + exit(1); | |
834 | + } | |
835 | +#endif | |
559 | 836 | |
560 | 837 | // register callback functions |
561 | - glutDisplayFunc(glut_render); //function executed for rendering - renders networks | |
562 | - glutMouseFunc(glut_mouse); //executed on a mouse click - sets starting mouse positions for rotations | |
563 | - glutMotionFunc(glut_motion); //executed when the mouse is moved while a button is pressed | |
564 | - if (ind == 1) { //only in mapping mode, keyboard will be used | |
565 | - glutCreateMenu(glut_menu); //register menu option callback | |
566 | - glutAddMenuEntry("Comparing Mode", 1); //register menu 1 as comparing mode | |
567 | - glutAddMenuEntry("Mapping Mode", 2); //register menu 2 as mapping mode | |
568 | - glutAddMenuEntry("Exit", 3); //register menu 3 as exiting | |
569 | - glutAttachMenu(GLUT_RIGHT_BUTTON); //register right mouse to open menu option | |
838 | + glutDisplayFunc(glut_render); // function executed for rendering - renders networks | |
839 | + glutMouseFunc(glut_mouse); // executed on a mouse click - sets starting mouse positions for rotations | |
840 | + glutMotionFunc(glut_motion); // executed when the mouse is moved while a button is pressed | |
841 | + if (flag_mapping == 1) { // only in mapping mode, keyboard will be used | |
842 | + glutCreateMenu(glut_menu); // register menu option callback | |
843 | + glutAddMenuEntry("Comparing Mode", 1); // register menu 1 as comparing mode | |
844 | + glutAddMenuEntry("Mapping Mode", 2); // register menu 2 as mapping mode | |
845 | + glutAddMenuEntry("Volume Display", 3); // register menu 3 as volume metric mode | |
846 | + glutAddMenuEntry("Exit", 4); // register menu 4 as exiting | |
847 | + glutAttachMenu(GLUT_RIGHT_BUTTON); // register right mouse to open menu option | |
570 | 848 | } |
571 | - glutKeyboardFunc(glut_keyboard); //register keyboard callback | |
849 | + glutKeyboardFunc(glut_keyboard); // register keyboard callback | |
572 | 850 | glutMouseWheelFunc(glut_wheel); |
573 | 851 | |
574 | - texture_initialize(); //set up texture mapping (create texture maps, enable features) | |
852 | + texture_initialize(); // set up texture mapping (create texture maps, enable features) | |
575 | 853 | |
576 | - stim::vec3<float> c = bb.center(); //get the center of the network bounding box | |
854 | + stim::vec3<float> c = bb.center(); // get the center of the network bounding box | |
577 | 855 | |
578 | - //place the camera along the z-axis at a distance determined by the network size along x and y | |
856 | + // place the camera along the z-axis at a distance determined by the network size along x and y | |
579 | 857 | cam.setPosition(c + stim::vec<float>(0, 0, camera_factor * std::max(bb.size()[0], bb.size()[1]))); |
580 | - cam.LookAt(c[0], c[1], c[2]); //look at the center of the network | |
858 | + cam.LookAt(c[0], c[1], c[2]); // look at the center of the network | |
581 | 859 | } |
582 | 860 | |
583 | 861 | #ifdef __CUDACC__ |
584 | 862 | // set specific device to work on |
585 | 863 | void setdevice(int &device){ |
586 | 864 | int count; |
587 | - cudaGetDeviceCount(&count); // numbers of device that are available | |
865 | + cudaGetDeviceCount(&count); // numbers of device that are available | |
588 | 866 | if(count < device + 1){ |
589 | 867 | std::cout<<"No such device available, please set another device"<<std::endl; |
590 | 868 | exit(1); |
... | ... | @@ -592,26 +870,26 @@ void setdevice(int &device){ |
592 | 870 | } |
593 | 871 | #else |
594 | 872 | void setdevice(int &device){ |
595 | - device = -1; // set to default -1 | |
873 | + device = -1; // set to default -1 | |
596 | 874 | } |
597 | 875 | #endif |
598 | 876 | |
599 | -//compare both networks and fill the networks with error information | |
877 | +// compare both networks and fill the networks with error information | |
600 | 878 | void compare(float sigma, int device){ |
601 | 879 | |
602 | - GT = GT.compare(T, sigma, device); //compare the ground truth to the test case - store errors in GT | |
603 | - T = T.compare(GT, sigma, device); //compare the test case to the ground truth - store errors in T | |
880 | + GT = GT.compare(T, sigma, device); // compare the ground truth to the test case - store errors in GT | |
881 | + T = T.compare(GT, sigma, device); // compare the test case to the ground truth - store errors in T | |
604 | 882 | |
605 | 883 | //calculate the metrics |
606 | - float FPR = GT.average(); //calculate the metrics | |
884 | + float FPR = GT.average(); // calculate the metrics | |
607 | 885 | float FNR = T.average(); |
608 | 886 | |
609 | - std::cout << "FNR: " << FPR << std::endl; //print false alarms and misses | |
887 | + std::cout << "FNR: " << FPR << std::endl; // print false alarms and misses | |
610 | 888 | std::cout << "FPR: " << FNR << std::endl; |
611 | 889 | } |
612 | 890 | |
613 | -//split and map two networks and fill the networks' R with metric information | |
614 | -void map(float sigma, int device, float threshold){ | |
891 | +// split and map two networks and fill the networks' R with metric information | |
892 | +void mapping(float sigma, int device, float threshold){ | |
615 | 893 | |
616 | 894 | // compare and split two networks |
617 | 895 | _GT.split(GT, T, sigma, device, threshold); |
... | ... | @@ -622,16 +900,16 @@ void map(float sigma, int device, float threshold){ |
622 | 900 | _T.mapping(_GT, _t_gt, device, threshold); |
623 | 901 | |
624 | 902 | // generate random color set based on the number of edges in GT |
625 | - size_t num = _gt_t.size(); // also create random color for unmapping edge, but won't be used though | |
626 | - colormap.resize(3 * num); // 3 portions compound RGB | |
903 | + size_t num = _gt_t.size(); // also create random color for unmapping edge, but won't be used though | |
904 | + colormap.resize(3 * num); // 3 portions compound RGB | |
627 | 905 | for(int i = 0; i < 3 * num; i++) |
628 | - colormap[i] = rand()/(float)RAND_MAX; // set to [0, 1] | |
906 | + colormap[i] = rand()/(float)RAND_MAX; // set to [0, 1] | |
629 | 907 | |
630 | 908 | //calculate the metrics |
631 | - float FPR = _GT.average(0); //calculate the metrics | |
909 | + float FPR = _GT.average(0); // calculate the metrics | |
632 | 910 | float FNR = _T.average(0); |
633 | 911 | |
634 | - std::cout << "FNR: " << FPR << std::endl; //print false alarms and misses | |
912 | + std::cout << "FNR: " << FPR << std::endl; // print false alarms and misses | |
635 | 913 | std::cout << "FPR: " << FNR << std::endl; |
636 | 914 | } |
637 | 915 | |
... | ... | @@ -682,77 +960,111 @@ void advertise(){ |
682 | 960 | std::cout<<" mapping two files in random colors with a threshold of value"<<std::endl<<std::endl; |
683 | 961 | } |
684 | 962 | |
963 | +<<<<<<< HEAD | |
964 | +int main(int argc, char* argv[]) | |
965 | +{ | |
966 | + stim::arglist args; // create an instance of arglist | |
967 | +======= | |
685 | 968 | int main(int argc, char* argv[]) { |
686 | 969 | stim::arglist args; //create an instance of arglist |
970 | +>>>>>>> 09cb5950f628309ac65c6b85119d3f16e5bcd0a2 | |
687 | 971 | |
688 | - //add arguments | |
972 | + // add arguments | |
689 | 973 | args.add("help", "prints this help"); |
690 | 974 | args.add("sigma", "force a sigma value to specify the tolerance of the network comparison", "3"); |
691 | 975 | args.add("gui", "display the network or network comparison using OpenGL"); |
692 | 976 | args.add("device", "choose specific device to run", "0"); |
693 | 977 | args.add("features", "save features to a CSV file, specify file name"); |
694 | 978 | args.add("mapping", "mapping input according to similarity"); |
979 | + args.add("stack", "load the image stacks"); | |
980 | + args.add("spacing", "spacing between pixel samples in each dimension", "1.0 1.0 1.0", "any real positive value"); | |
695 | 981 | |
696 | - args.parse(argc, argv); //parse the user arguments | |
982 | + args.parse(argc, argv); // parse the user arguments | |
697 | 983 | |
698 | - if(args["help"].is_set() || args.nargs() == 0){ //test for help | |
699 | - advertise(); //output the advertisement | |
700 | - std::cout<<args.str(); //output arguments | |
701 | - exit(1); //exit | |
984 | + if(args["help"].is_set()){ // test for help | |
985 | + advertise(); // output the advertisement | |
986 | + std::cout<<args.str(); // output arguments | |
987 | + exit(1); // exit | |
702 | 988 | } |
703 | 989 | |
704 | - if (args.nargs() >= 1) { // if at least one network file is specified | |
705 | - num_nets = 1; // set the number of networks to one | |
990 | + if (args.nargs() >= 1) { // if at least one network file is specified | |
991 | + num_nets = 1; // set the number of networks to one | |
706 | 992 | std::vector<std::string> tmp = stim::parser::split(args.arg(0), '.'); // split the filename at '.' |
707 | - if ("swc" == tmp[1]) // loading swc file | |
708 | - GT.load_swc(args.arg(0)); // load the specified file as the ground truth | |
709 | - else if ("obj" == tmp[1]) // loading obj file | |
710 | - GT.load_obj(args.arg(0)); // load the specified file as the ground truth | |
993 | + if ("swc" == tmp[1]) // loading swc file | |
994 | + GT.load_swc(args.arg(0)); // load the specified file as the ground truth | |
995 | + else if ("obj" == tmp[1]) // loading obj file | |
996 | + GT.load_obj(args.arg(0)); // load the specified file as the ground truth | |
711 | 997 | else { |
712 | 998 | std::cout << "Invalid loading file" << std::endl; |
713 | 999 | exit(1); |
714 | 1000 | } |
715 | 1001 | } |
716 | 1002 | |
717 | - if (args.nargs() == 2) { //if two files are specified, they will be displayed in neighboring viewports and compared | |
718 | - int device = args["device"].as_int(); //get the device value from the user | |
719 | - num_nets = 2; //set the number of networks to two | |
720 | - sigma = args["sigma"].as_float(); //get the sigma value from the user | |
1003 | + if (args.nargs() == 2) { // if two files are specified, they will be displayed in neighboring viewports and compared | |
1004 | + int device = args["device"].as_int(); // get the device value from the user | |
1005 | + num_nets = 2; // set the number of networks to two | |
1006 | + sigma = args["sigma"].as_float(); // get the sigma value from the user | |
721 | 1007 | std::vector<std::string> tmp = stim::parser::split(args.arg(1), '.'); // split the filename at '.' |
722 | - if ("swc" == tmp[1]) //loading swc files | |
723 | - T.load_swc(args.arg(1)); //load the second (test) network | |
724 | - else if ("obj" == tmp[1]) //loading obj files | |
1008 | + if ("swc" == tmp[1]) // loading swc files | |
1009 | + T.load_swc(args.arg(1)); // load the second (test) network | |
1010 | + else if ("obj" == tmp[1]) // loading obj files | |
725 | 1011 | T.load_obj(args.arg(1)); |
726 | 1012 | else { |
727 | 1013 | std::cout << "Invalid loading file" << std::endl; |
728 | 1014 | exit(1); |
729 | 1015 | } |
730 | - if (args["features"].is_set()) //if the user wants to save features | |
1016 | + if (args["features"].is_set()) // if the user wants to save features | |
731 | 1017 | features(args["features"].as_string()); |
732 | - //does it need to be resampled?? | |
733 | - GT = GT.resample(resample_rate * sigma); //resample both networks based on the sigma value | |
1018 | + | |
1019 | + GT = GT.resample(resample_rate * sigma); // resample both networks based on the sigma value | |
734 | 1020 | T = T.resample(resample_rate * sigma); |
735 | 1021 | if (args["mapping"].is_set()) { |
736 | 1022 | float threshold = args["mapping"].as_float(); |
737 | - map(sigma, device, threshold); | |
1023 | + mapping(sigma, device, threshold); | |
1024 | + } | |
1025 | +<<<<<<< HEAD | |
1026 | + else | |
1027 | + compare(sigma, device); // run the comparison algorithm | |
738 | 1028 | } |
1029 | + | |
1030 | + if (args["stack"].is_set()) { | |
1031 | + S.load_images(args["stack"].as_string()); | |
1032 | + flag_stack = true; | |
1033 | + } | |
1034 | + | |
1035 | + float sp[3] = { 1.0f, 1.0f, 1.0f }; // allocate variables for grid spacing | |
1036 | + if (args["spacing"].nargs() == 1) // if only one argument is given | |
1037 | + sp[2] = (float)args["spacing"].as_float(0); // assume that it's the z coordinate (most often anisotropic) | |
1038 | + else if (args["spacing"].nargs() == 3) { // if three arguments are given | |
1039 | + sp[0] = (float)args["spacing"].as_float(0); // set the arguments as expected | |
1040 | + sp[1] = (float)args["spacing"].as_float(1); | |
1041 | + sp[2] = (float)args["spacing"].as_float(2); | |
1042 | + } | |
1043 | + | |
1044 | + S.spacing(sp[0], sp[1], sp[2]); // set the spacing between samples | |
1045 | + | |
1046 | + planes[0] = S.size(0) / 4.0f; // initialize the start positions for the orthogonal display planes | |
1047 | + planes[1] = S.size(1) / 4.0f; | |
1048 | + planes[2] = S.size(2) / 4.0f; | |
1049 | +======= | |
739 | 1050 | else { |
740 | 1051 | compare(sigma, device); //run the comparison algorithm |
741 | 1052 | } |
742 | 1053 | } |
1054 | +>>>>>>> 09cb5950f628309ac65c6b85119d3f16e5bcd0a2 | |
743 | 1055 | |
744 | 1056 | //if a GUI is requested, display the network using OpenGL |
745 | 1057 | if(args["gui"].is_set()){ |
746 | 1058 | if (args["mapping"].is_set()) { |
747 | - ind = 1; //set indicator of mapping to 1(true) | |
748 | - bb = _GT.boundingbox(); //generate a bounding volume | |
749 | - glut_initialize(); //create the GLUT window and set callback functions | |
750 | - glutMainLoop(); //enter GLUT event processing cycle | |
1059 | + flag_mapping = true; // set flag of mapping to true | |
1060 | + bb = _GT.boundingbox(); // generate a bounding volume | |
1061 | + glut_initialize(); // create the GLUT window and set callback functions | |
1062 | + glutMainLoop(); // enter GLUT event processing cycle | |
751 | 1063 | } |
752 | 1064 | else { |
753 | - bb = GT.boundingbox(); //generate a bounding volume | |
754 | - glut_initialize(); //create the GLUT window and set callback functions | |
755 | - glutMainLoop(); //enter GLUT event processing cycle | |
1065 | + bb = GT.boundingbox(); // generate a bounding volume | |
1066 | + glut_initialize(); // create the GLUT window and set callback functions | |
1067 | + glutMainLoop(); // enter GLUT event processing cycle | |
756 | 1068 | } |
757 | 1069 | } |
758 | 1070 | return 1; | ... | ... |