SCM Repository
Annotation of /examples/vr-demo/main.c
Parent Directory
|
Revision Log
Revision 2080 - (view) (download) (as text)
1 : | jhr | 2058 | /*! \file main.c |
2 : | * | ||
3 : | * \author John Reppy | ||
4 : | * | ||
5 : | * Main program for Diderot VR viewer. | ||
6 : | */ | ||
7 : | |||
8 : | /* | ||
9 : | * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu) | ||
10 : | * All rights reserved. | ||
11 : | */ | ||
12 : | |||
13 : | #include "GL/glfw.h" | ||
14 : | #include "util.h" | ||
15 : | jhr | 2063 | #include "vr.h" |
16 : | jhr | 2058 | #include <unistd.h> |
17 : | jhr | 2079 | #include "teem/air.h" |
18 : | jhr | 2058 | |
19 : | jhr | 2061 | /* minimum and maximum values from */ |
20 : | #define MIN_VALUE 0 | ||
21 : | #define MAX_VALUE 2632 | ||
22 : | |||
23 : | /* half the width of the opacity range */ | ||
24 : | #define OPAC_HALF_WID 150 | ||
25 : | |||
26 : | #define MIN_OPAC_MID ((float)(MIN_VALUE+OPAC_HALF_WID)) | ||
27 : | #define MAX_OPAC_MID ((float)(MAX_VALUE-OPAC_HALF_WID)) | ||
28 : | |||
29 : | jhr | 2079 | #define OPAC_DELTA 25 |
30 : | jhr | 2067 | |
31 : | jhr | 2079 | /* reduced-size inputs */ |
32 : | #define REDUCED_WID 256 | ||
33 : | #define REDUCED_HT 184 | ||
34 : | #define REDUCED_STEP 1 | ||
35 : | jhr | 2058 | |
36 : | |||
37 : | jhr | 2079 | /* full-size inputs */ |
38 : | #define FULL_WID 512 | ||
39 : | #define FULL_HT 368 | ||
40 : | #define FULL_STEP 0.5 | ||
41 : | |||
42 : | #define WIDTH (2*FULL_WID) | ||
43 : | #define HEIGHT (2*FULL_HT) | ||
44 : | |||
45 : | jhr | 2058 | static inline void CheckError () |
46 : | { | ||
47 : | GLenum errCode; | ||
48 : | if ((errCode = glGetError()) != GL_NO_ERROR) { | ||
49 : | fprintf(stderr, "OpenGL error: %s\n", gluErrorString(errCode)); | ||
50 : | exit (1); | ||
51 : | } | ||
52 : | } | ||
53 : | |||
54 : | /***** Globals for viewing, etc. *****/ | ||
55 : | |||
56 : | jhr | 2079 | typedef struct { |
57 : | bool init; | ||
58 : | GLuint wid; | ||
59 : | GLuint ht; | ||
60 : | GLuint id; | ||
61 : | } TexInfo_t; | ||
62 : | |||
63 : | jhr | 2067 | VR_World_t *World; |
64 : | jhr | 2058 | unsigned int Width; // view window width |
65 : | unsigned int Height; // view window height | ||
66 : | jhr | 2079 | TexInfo_t ReducedTexure = { // Texture ID of reduced image |
67 : | false, REDUCED_WID, REDUCED_HT, 0 | ||
68 : | }; | ||
69 : | TexInfo_t FullTexture = { // Texture ID of full image | ||
70 : | false, FULL_WID, FULL_HT, 0 | ||
71 : | }; | ||
72 : | jhr | 2063 | bool NeedsRedraw; |
73 : | bool NeedsRecompute; | ||
74 : | jhr | 2067 | float OpacMid = 550.0; |
75 : | jhr | 2079 | int Dir = 0; /* -1, 0, 1 */ |
76 : | jhr | 2058 | |
77 : | |||
78 : | jhr | 2079 | // initialize a texture from a grayscale Nrrd file |
79 : | void InitTexture (TexInfo_t *txt, Nrrd *img) | ||
80 : | { | ||
81 : | if (! txt->init) { | ||
82 : | // generate the TeXID | ||
83 : | glGenTextures (1, &(txt->id)); | ||
84 : | |||
85 : | // load the texture data | ||
86 : | glBindTexture (GL_TEXTURE_2D, txt->id); | ||
87 : | glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, txt->wid, txt->ht, 0, GL_RGBA, GL_FLOAT, img->data); | ||
88 : | CheckError(); | ||
89 : | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
90 : | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
91 : | CheckError(); | ||
92 : | } | ||
93 : | else { | ||
94 : | // reload the texture data | ||
95 : | glBindTexture (GL_TEXTURE_2D, txt->id); | ||
96 : | glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, txt->wid, txt->ht, GL_RGBA, GL_FLOAT, img->data); | ||
97 : | CheckError(); | ||
98 : | } | ||
99 : | } | ||
100 : | |||
101 : | jhr | 2058 | // Callback function called by GLUT to render screen |
102 : | jhr | 2079 | void Draw (GLuint txtId) |
103 : | jhr | 2058 | { |
104 : | // Clear frame buffer | ||
105 : | glClearColor (0, 0, 0, 1); | ||
106 : | glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
107 : | |||
108 : | glDisable(GL_DEPTH_TEST); | ||
109 : | glDisable(GL_CULL_FACE); | ||
110 : | |||
111 : | // Draw image | ||
112 : | jhr | 2079 | glEnable (GL_TEXTURE_2D); |
113 : | glActiveTexture (GL_TEXTURE0); | ||
114 : | glBindTexture (GL_TEXTURE_2D, txtId); | ||
115 : | glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | ||
116 : | glBegin (GL_QUADS); | ||
117 : | glTexCoord2f (0.0, 0.0); | ||
118 : | glVertex2f (0.0, 0.0); | ||
119 : | glTexCoord2f (1.0, 0.0); | ||
120 : | glVertex2f (1.0, 0.0); | ||
121 : | glTexCoord2f (1.0, 1.0); | ||
122 : | glVertex2f (1.0, 1.0); | ||
123 : | glTexCoord2f (0.0, 1.0); | ||
124 : | glVertex2f (0.0, 1.0); | ||
125 : | glEnd(); | ||
126 : | glDisable (GL_TEXTURE_2D); | ||
127 : | jhr | 2058 | CheckError (); |
128 : | |||
129 : | // Present frame buffer | ||
130 : | glfwSwapBuffers(); | ||
131 : | } | ||
132 : | |||
133 : | // Callback function called by GLFW when window size changes | ||
134 : | void GLFWCALL WindowSizeCB (int width, int height) | ||
135 : | { | ||
136 : | // Set OpenGL viewport and camera | ||
137 : | glViewport(0, 0, width, height); | ||
138 : | |||
139 : | jhr | 2079 | glMatrixMode (GL_PROJECTION); |
140 : | glLoadIdentity (); | ||
141 : | gluOrtho2D (0.0, 1.0, 0.0, 1.0); | ||
142 : | |||
143 : | glMatrixMode (GL_MODELVIEW); | ||
144 : | glLoadIdentity (); | ||
145 : | gluLookAt ( | ||
146 : | 0.0, 0.0, 1.0, | ||
147 : | 0.0, 0.0, 0.0, | ||
148 : | 0.0, 1.0, 0.0); | ||
149 : | |||
150 : | jhr | 2058 | // remember width and height |
151 : | Width = width; | ||
152 : | Height = height; | ||
153 : | |||
154 : | jhr | 2080 | NeedsRedraw = true; |
155 : | jhr | 2058 | } |
156 : | |||
157 : | jhr | 2067 | void GLFWCALL KeyCB (int key, int action) |
158 : | { | ||
159 : | jhr | 2079 | switch (key) { |
160 : | case '+': | ||
161 : | if ((action == GLFW_PRESS) && (Dir >= 0)) | ||
162 : | Dir++; | ||
163 : | break; | ||
164 : | case '-': | ||
165 : | if ((action == GLFW_PRESS) && (Dir <= 0)) | ||
166 : | Dir--; | ||
167 : | break; | ||
168 : | default: | ||
169 : | break; | ||
170 : | jhr | 2067 | } |
171 : | } | ||
172 : | |||
173 : | jhr | 2079 | void Compute (VR_World_t *wrld, bool fullSize, Nrrd *nRGB) |
174 : | jhr | 2058 | { |
175 : | jhr | 2079 | printf("computing %s... ", fullSize ? "" : "(fast) "); fflush(stdout); |
176 : | double t0 = airTime(); | ||
177 : | // setup raycast parameters | ||
178 : | if (fullSize) { | ||
179 : | VR_InVarSet_imgResU (wrld, FULL_WID); | ||
180 : | VR_InVarSet_imgResV (wrld, FULL_HT); | ||
181 : | VR_InVarSet_rayStep (wrld, FULL_STEP); | ||
182 : | } | ||
183 : | else { | ||
184 : | VR_InVarSet_imgResU (wrld, REDUCED_WID); | ||
185 : | VR_InVarSet_imgResV (wrld, REDUCED_HT); | ||
186 : | VR_InVarSet_rayStep (wrld, REDUCED_STEP); | ||
187 : | } | ||
188 : | // recompute | ||
189 : | if (VR_Initially (wrld)) { | ||
190 : | // error | ||
191 : | fprintf(stderr, "Error initializing world: %s", VR_GetErrors(wrld)); | ||
192 : | exit(1); | ||
193 : | } | ||
194 : | int nSteps = VR_Run (wrld, 0); | ||
195 : | printf(" %d steps in %5.3f seconds\n", nSteps, airTime() - t0); | ||
196 : | // get output image | ||
197 : | jhr | 2063 | if (VR_OutputGet_outRGBA (wrld, nRGB)) { |
198 : | jhr | 2058 | // error |
199 : | jhr | 2079 | fprintf(stderr, "Error getting nrrd data: %s", VR_GetErrors(wrld)); |
200 : | jhr | 2063 | exit(1); |
201 : | jhr | 2058 | } |
202 : | } | ||
203 : | |||
204 : | int main (int argc, const char **argv) | ||
205 : | { | ||
206 : | // Initialize GLFW | ||
207 : | if (0 == glfwInit()) { | ||
208 : | // An error occured | ||
209 : | fprintf(stderr, "GLFW initialization failed\n"); | ||
210 : | return 1; | ||
211 : | } | ||
212 : | |||
213 : | GLFWvidmode mode; | ||
214 : | glfwGetDesktopMode (&mode); | ||
215 : | if (0 == glfwOpenWindow(WIDTH, HEIGHT, mode.RedBits, mode.GreenBits, mode.BlueBits, 0, 0, 0, GLFW_WINDOW) ) { | ||
216 : | // A fatal error occured | ||
217 : | fprintf(stderr, "Cannot open GLFW window\n"); | ||
218 : | glfwTerminate(); | ||
219 : | return 1; | ||
220 : | } | ||
221 : | glfwEnable(GLFW_KEY_REPEAT); | ||
222 : | jhr | 2061 | glfwSetWindowTitle("Diderot VR Demo"); |
223 : | jhr | 2058 | |
224 : | // Set GLFW event callbacks | ||
225 : | glfwSetWindowSizeCallback (WindowSizeCB); | ||
226 : | jhr | 2067 | glfwSetCharCallback (KeyCB); |
227 : | jhr | 2058 | |
228 : | // initialize the Diderot program | ||
229 : | jhr | 2061 | VR_World_t *wrld = VR_Init (); |
230 : | jhr | 2067 | World = wrld; |
231 : | jhr | 2058 | |
232 : | jhr | 2067 | // initialize inputs |
233 : | VR_InVarSet_valOpacMid(wrld, OpacMid); | ||
234 : | jhr | 2079 | VR_InVarSetByName_hand (wrld, "data/vfrhand-nohip.nhdr"); |
235 : | jhr | 2067 | |
236 : | jhr | 2058 | // nrrd for getting computational state |
237 : | jhr | 2061 | Nrrd *nRGB = nrrdNew(); |
238 : | jhr | 2058 | |
239 : | // Main loop (repeated while window is not closed and [ESC] is not pressed) | ||
240 : | jhr | 2062 | NeedsRecompute = true; |
241 : | jhr | 2079 | GLuint txtId; |
242 : | jhr | 2058 | while (glfwGetWindowParam(GLFW_OPENED) && !glfwGetKey(GLFW_KEY_ESC)) { |
243 : | jhr | 2079 | if (Dir < 0) { |
244 : | Dir++; | ||
245 : | float mid = OpacMid - OPAC_DELTA; | ||
246 : | if (mid >= MIN_OPAC_MID) { | ||
247 : | OpacMid = mid; | ||
248 : | VR_InVarSet_valOpacMid(World, mid); | ||
249 : | NeedsRecompute = true; | ||
250 : | } | ||
251 : | } | ||
252 : | else if (Dir > 0) { | ||
253 : | Dir--; | ||
254 : | float mid = OpacMid + OPAC_DELTA; | ||
255 : | if (mid <= MAX_OPAC_MID) { | ||
256 : | OpacMid = mid; | ||
257 : | VR_InVarSet_valOpacMid(World, mid); | ||
258 : | NeedsRecompute = true; | ||
259 : | } | ||
260 : | } | ||
261 : | jhr | 2061 | if (NeedsRecompute) { |
262 : | jhr | 2079 | if (Dir != 0) { |
263 : | Compute(wrld, false, nRGB); | ||
264 : | InitTexture(&ReducedTexure, nRGB); | ||
265 : | txtId = ReducedTexure.id; | ||
266 : | jhr | 2067 | } |
267 : | jhr | 2079 | else { |
268 : | Compute (wrld, true, nRGB); | ||
269 : | InitTexture(&FullTexture, nRGB); | ||
270 : | NeedsRecompute = false; | ||
271 : | txtId = FullTexture.id; | ||
272 : | } | ||
273 : | jhr | 2063 | NeedsRedraw = true; |
274 : | jhr | 2061 | } |
275 : | if (NeedsRedraw) { | ||
276 : | jhr | 2079 | Draw (txtId); |
277 : | jhr | 2063 | NeedsRedraw = false; |
278 : | jhr | 2061 | } |
279 : | jhr | 2079 | if (NeedsRecompute) |
280 : | glfwPollEvents(); | ||
281 : | else | ||
282 : | glfwWaitEvents(); | ||
283 : | jhr | 2058 | } |
284 : | |||
285 : | // shutdown the world | ||
286 : | jhr | 2061 | VR_Shutdown (wrld); |
287 : | jhr | 2058 | |
288 : | jhr | 2063 | // Terminate GLFW |
289 : | jhr | 2058 | glfwTerminate(); |
290 : | |||
291 : | return 0; | ||
292 : | } |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |