glviewvol
view src/viewer.cc @ 11:73edd1b7c2da
changed the name to glviewvol
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 31 Dec 2014 07:53:53 +0200 |
parents | src/dicomview.cc@89efc666105c |
children | 773f89037a35 |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "opengl.h"
4 #include "viewer.h"
5 #include "rend_fast.h"
6 #include "opt.h"
7 #include "volume.h"
8 #include "xfer_view.h"
10 static int win_width, win_height;
11 static float cam_theta, cam_phi, cam_dist = 4;
12 static float pre_rot = -90;
13 static int splitter_y = -1;
15 #define SPLITTER_WIDTH 5
17 static Renderer *rend;
18 static Volume *vol;
19 static TransferFunc *xfer;
21 extern "C" {
23 int init()
24 {
25 if(!opt.fname) {
26 fprintf(stderr, "you must specify the volume data filename\n");
27 return -1;
28 }
30 switch(opt.rend_type) {
31 case REND_FAST:
32 rend = new RendererFast;
33 break;
34 default:
35 return -1;
36 }
38 if(!rend->init()) {
39 fprintf(stderr, "renderer initialization failed\n");
40 return -1;
41 }
43 VoxelVolume *voxvol = new VoxelVolume;
44 if(!voxvol->load(opt.fname)) {
45 fprintf(stderr, "failed to load volume data from: %s\n", opt.fname);
46 return -1;
47 }
48 vol = voxvol;
49 rend->set_volume(vol);
51 xfer = new TransferWindow;
52 rend->set_transfer_function(xfer);
54 if(!xfview_init(xfer)) {
55 return -1;
56 }
58 return 0;
59 }
61 void cleanup()
62 {
63 xfview_destroy();
65 rend->destroy();
66 delete rend;
67 delete vol;
68 delete xfer;
69 }
71 void ev_display()
72 {
73 glClear(GL_COLOR_BUFFER_BIT);
75 // render the main view
76 glViewport(0, win_height - splitter_y, win_width, splitter_y);
78 glMatrixMode(GL_PROJECTION);
79 glLoadIdentity();
80 gluPerspective(50.0, (float)win_width / (float)splitter_y, 0.1, 100.0);
82 glMatrixMode(GL_MODELVIEW);
83 glLoadIdentity();
84 glTranslatef(0, 0, -cam_dist);
85 glRotatef(cam_phi + pre_rot, 1, 0, 0);
86 glRotatef(cam_theta, 0, 1, 0);
88 rend->update(0);
89 rend->render();
91 // draw the transfer function view
92 glViewport(0, 0, win_width, win_height - splitter_y);
94 xfview_draw();
96 // draw the GUI
97 glViewport(0, 0, win_width, win_height);
99 glMatrixMode(GL_PROJECTION);
100 glLoadIdentity();
101 glOrtho(0, win_width, win_height, 0, -1, 1);
103 glMatrixMode(GL_MODELVIEW);
104 glLoadIdentity();
106 glBegin(GL_QUADS);
107 glColor3f(1, 1, 1);
108 glVertex2f(0, splitter_y + SPLITTER_WIDTH / 2);
109 glVertex2f(win_width, splitter_y + SPLITTER_WIDTH / 2);
110 glVertex2f(win_width, splitter_y - SPLITTER_WIDTH / 2);
111 glVertex2f(0, splitter_y - SPLITTER_WIDTH / 2);
112 glEnd();
114 swap_buffers();
115 }
117 void ev_reshape(int x, int y)
118 {
119 if(splitter_y < 0) { // not initialized yet
120 splitter_y = (int)(y * 0.85);
121 } else {
122 // calculate where the splitter was relative to the window height
123 // and based on that, it's new position
124 float split = (float)splitter_y / (float)win_height;
125 splitter_y = (int)(y * split);
126 }
128 win_width = x;
129 win_height = y;
131 glViewport(0, 0, x, y);
132 if(rend) {
133 rend->reshape(x, y);
134 }
135 }
137 static bool zscaling;
139 void ev_keyboard(int key, int press, int x, int y)
140 {
141 RendererFast *fr;
143 switch(key) {
144 case 27:
145 if(press) {
146 quit();
147 }
148 break;
150 case 'z':
151 case 'Z':
152 zscaling = press;
153 break;
155 case '=':
156 if(press && (fr = dynamic_cast<RendererFast*>(rend))) {
157 int n = fr->get_proxy_count();
158 int add = n / 4;
159 n += add < 1 ? 1 : add;
160 printf("proxy count: %d\n", n);
161 fr->set_proxy_count(n);
162 redisplay();
163 }
164 break;
166 case '-':
167 if(press && (fr = dynamic_cast<RendererFast*>(rend))) {
168 int n = fr->get_proxy_count();
169 int sub = n / 4;
170 n -= sub < 1 ? 1 : sub;
172 if(n < 1) n = 1;
174 printf("proxy count: %d\n", n);
175 fr->set_proxy_count(n);
176 redisplay();
177 }
178 break;
180 default:
181 break;
182 }
183 }
185 static bool bnstate[8];
186 static int prev_x, prev_y;
188 #define ON_SPLITTER(y) (abs(y - splitter_y) <= SPLITTER_WIDTH / 2)
189 static bool splitter_dragging;
191 void ev_mouse_button(int bn, int press, int x, int y)
192 {
193 bnstate[bn] = press != 0;
194 prev_x = x;
195 prev_y = y;
197 splitter_dragging = bn == 0 && press && ON_SPLITTER(y);
199 if(!splitter_dragging && y > splitter_y) {
200 xfview_button(bn, press, x, y);
201 }
202 }
204 void ev_mouse_motion(int x, int y)
205 {
206 int dx = x - prev_x;
207 int dy = y - prev_y;
208 prev_x = x;
209 prev_y = y;
211 if((dx | dy) == 0) return;
213 if(bnstate[0] && zscaling) {
214 float s = rend->get_zscale() + (float)dy / (float)win_height;
215 rend->set_zscale(s < 0.0 ? 0.0 : s);
216 redisplay();
217 return;
218 }
220 if(splitter_dragging) {
221 splitter_y += dy;
222 redisplay();
223 return;
224 }
226 if(y > splitter_y) {
227 xfview_motion(x, y);
228 return;
229 }
231 // main view motion handling
232 if(bnstate[0]) {
233 cam_theta += dx * 0.5;
234 cam_phi += dy * 0.5;
236 if(cam_phi < -90) cam_phi = -90;
237 if(cam_phi > 90) cam_phi = 90;
238 redisplay();
239 }
240 if(bnstate[2]) {
241 cam_dist += dy * 0.1;
243 if(cam_dist < 0.0) cam_dist = 0.0;
244 redisplay();
245 }
246 }
248 } // extern "C"