1 : |
jhr |
1880 |
/*! \file main.c
|
2 : |
|
|
*
|
3 : |
|
|
* \author John Reppy
|
4 : |
|
|
*
|
5 : |
|
|
* Main program for Diderot ISO2d animation.
|
6 : |
|
|
*/
|
7 : |
|
|
|
8 : |
|
|
/*
|
9 : |
|
|
* COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
|
10 : |
|
|
* All rights reserved.
|
11 : |
|
|
*/
|
12 : |
|
|
|
13 : |
|
|
#include <AntTweakBar.h>
|
14 : |
jhr |
1882 |
#include "GL/glfw.h"
|
15 : |
|
|
#ifdef DIDEROT_CODE
|
16 : |
|
|
#include "vr-lite-cam.h"
|
17 : |
jhr |
1880 |
#endif
|
18 : |
jhr |
1882 |
#include "teem/nrrd.h"
|
19 : |
|
|
#include "teem/biff.h"
|
20 : |
jhr |
1880 |
|
21 : |
|
|
/* pixel dimensions of output */
|
22 : |
|
|
#define WIDTH 512
|
23 : |
|
|
#define HEIGHT 512
|
24 : |
|
|
|
25 : |
|
|
/***** Globals for viewing, etc. *****/
|
26 : |
|
|
|
27 : |
|
|
Nrrd *Diderot; // input image nrrd
|
28 : |
|
|
unsigned int Width; // view window width
|
29 : |
|
|
unsigned int Height; // view window height
|
30 : |
|
|
GLuint ImageTexture; // Texture ID of background image
|
31 : |
|
|
|
32 : |
jhr |
1882 |
typedef struct {
|
33 : |
|
|
TwBar *ctls;
|
34 : |
|
|
unsigned int running;
|
35 : |
|
|
} State_t;
|
36 : |
|
|
|
37 : |
jhr |
1880 |
// Callback function called by GLUT to render screen
|
38 : |
jhr |
1882 |
void Draw ()
|
39 : |
jhr |
1880 |
{
|
40 : |
|
|
// Clear frame buffer
|
41 : |
|
|
glClearColor (0, 0, 0, 1);
|
42 : |
|
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
43 : |
|
|
|
44 : |
|
|
glEnable(GL_DEPTH_TEST);
|
45 : |
|
|
glDisable(GL_CULL_FACE);
|
46 : |
|
|
|
47 : |
|
|
// Draw background
|
48 : |
jhr |
1882 |
float halfWid = 0.5 * (float)Width;
|
49 : |
|
|
float halfHt = 0.5 * (float)Height;
|
50 : |
|
|
glBindTexture (GL_TEXTURE_2D, ImageTexture);
|
51 : |
|
|
glBegin (GL_QUADS);
|
52 : |
|
|
glTexCoord2f (0.0, 0.0);
|
53 : |
|
|
glVertex2f (-halfWid, -halfHt);
|
54 : |
|
|
glTexCoord2f (1.0, 0.0);
|
55 : |
|
|
glVertex2f (halfWid, -halfHt);
|
56 : |
|
|
glTexCoord2f (1.0, 1.0);
|
57 : |
|
|
glVertex2f (halfWid, halfHt);
|
58 : |
|
|
glTexCoord2f (0.0, 1.0);
|
59 : |
|
|
glVertex2f (-halfWid, halfHt);
|
60 : |
|
|
glEnd();
|
61 : |
jhr |
1880 |
|
62 : |
|
|
// Draw current render state
|
63 : |
|
|
|
64 : |
|
|
// Draw tweak bars
|
65 : |
|
|
TwDraw();
|
66 : |
|
|
|
67 : |
|
|
// Present frame buffer
|
68 : |
jhr |
1882 |
glfwSwapBuffers();
|
69 : |
jhr |
1880 |
}
|
70 : |
|
|
|
71 : |
jhr |
1882 |
// Callback function called by GLFW when window size changes
|
72 : |
|
|
void GLFWCALL WindowSizeCB (int width, int height)
|
73 : |
jhr |
1880 |
{
|
74 : |
jhr |
1882 |
double halfWid = 0.5 * (double)width;
|
75 : |
|
|
double halfHt = 0.5 * (double)height;
|
76 : |
|
|
|
77 : |
jhr |
1880 |
// Set OpenGL viewport and camera
|
78 : |
jhr |
1882 |
glViewport(0, 0, width, height);
|
79 : |
|
|
glMatrixMode(GL_PROJECTION);
|
80 : |
|
|
glLoadIdentity();
|
81 : |
|
|
gluOrtho2D (-halfWid, halfWid, -halfHt, halfHt);
|
82 : |
|
|
|
83 : |
jhr |
1880 |
glMatrixMode (GL_MODELVIEW);
|
84 : |
|
|
glLoadIdentity ();
|
85 : |
jhr |
1882 |
gluLookAt (
|
86 : |
|
|
0.0, 0.0, 1.0,
|
87 : |
|
|
0.0, 0.0, 0.0,
|
88 : |
|
|
0.0, 1.0, 0.0);
|
89 : |
jhr |
1880 |
|
90 : |
jhr |
1882 |
// Send the new window size to AntTweakBar
|
91 : |
|
|
TwWindowSize(width, height);
|
92 : |
jhr |
1880 |
|
93 : |
|
|
// remember width and height
|
94 : |
|
|
Width = width;
|
95 : |
|
|
Height = height;
|
96 : |
|
|
|
97 : |
|
|
}
|
98 : |
|
|
|
99 : |
|
|
// initialize a texture from a grayscale Nrrd file
|
100 : |
|
|
void InitTexture (Nrrd *nin)
|
101 : |
|
|
{
|
102 : |
|
|
if ((nin->dim != 2)
|
103 : |
|
|
|| (nin->axis[0].kind != nrrdKindSpace)
|
104 : |
|
|
|| (nin->axis[1].kind != nrrdKindSpace)) {
|
105 : |
|
|
fprintf (stderr, "unable to handle nrrd file\n");
|
106 : |
|
|
exit (1);
|
107 : |
|
|
}
|
108 : |
|
|
|
109 : |
|
|
// determine the pixel format for the texture
|
110 : |
|
|
GLenum type;
|
111 : |
|
|
switch (nin->type) {
|
112 : |
|
|
case nrrdTypeUChar: type = GL_UNSIGNED_BYTE; break;
|
113 : |
|
|
case nrrdTypeFloat: type = GL_FLOAT; break;
|
114 : |
|
|
default:
|
115 : |
|
|
fprintf (stderr, "unable to handle nrdd file type %d\n", nin->type);
|
116 : |
|
|
exit (1);
|
117 : |
|
|
}
|
118 : |
|
|
|
119 : |
|
|
// generate the TeXID
|
120 : |
|
|
GLuint texId;
|
121 : |
|
|
glGenTextures (1, &texId);
|
122 : |
|
|
|
123 : |
|
|
// load the texture data
|
124 : |
|
|
glBindTexture (GL_TEXTURE_2D, texId);
|
125 : |
|
|
glTexImage2D (GL_TEXTURE_2D, /* or GL_TEXTURE_RECTANGLE ? */
|
126 : |
|
|
0,
|
127 : |
|
|
GL_RED,
|
128 : |
jhr |
1882 |
nin->axis[0].size, nin->axis[1].size, 0,
|
129 : |
jhr |
1880 |
GL_RED, type,
|
130 : |
|
|
nin->data);
|
131 : |
|
|
/* check for error */
|
132 : |
|
|
|
133 : |
|
|
ImageTexture = texId;
|
134 : |
|
|
}
|
135 : |
|
|
|
136 : |
jhr |
1882 |
void TW_CALL StartButtonCB (void *data)
|
137 : |
|
|
{
|
138 : |
|
|
State_t *st = (State_t *)data;
|
139 : |
|
|
|
140 : |
|
|
if (st->running == 0) {
|
141 : |
|
|
st->running = 1;
|
142 : |
|
|
TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Stop");
|
143 : |
|
|
}
|
144 : |
|
|
else {
|
145 : |
|
|
st->running = 0;
|
146 : |
|
|
TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Start");
|
147 : |
|
|
}
|
148 : |
|
|
}
|
149 : |
|
|
|
150 : |
jhr |
1880 |
int main (int argc, const char **argv)
|
151 : |
|
|
{
|
152 : |
jhr |
1882 |
State_t state = { .running = 0 };
|
153 : |
jhr |
1880 |
|
154 : |
jhr |
1882 |
// Initialize GLFW
|
155 : |
|
|
if (0 == glfwInit()) {
|
156 : |
|
|
// An error occured
|
157 : |
|
|
fprintf(stderr, "GLFW initialization failed\n");
|
158 : |
|
|
return 1;
|
159 : |
|
|
}
|
160 : |
jhr |
1880 |
|
161 : |
jhr |
1882 |
GLFWvidmode mode;
|
162 : |
|
|
glfwGetDesktopMode (&mode);
|
163 : |
|
|
if (0 == glfwOpenWindow(WIDTH, HEIGHT, mode.RedBits, mode.GreenBits, mode.BlueBits, 0, 0, 0, GLFW_WINDOW) ) {
|
164 : |
|
|
// A fatal error occured
|
165 : |
|
|
fprintf(stderr, "Cannot open GLFW window\n");
|
166 : |
|
|
glfwTerminate();
|
167 : |
|
|
return 1;
|
168 : |
|
|
}
|
169 : |
|
|
glfwEnable(GLFW_MOUSE_CURSOR);
|
170 : |
|
|
glfwEnable(GLFW_KEY_REPEAT);
|
171 : |
|
|
glfwSetWindowTitle("Diderot Iso2D Animation");
|
172 : |
|
|
|
173 : |
jhr |
1880 |
// Initialize AntTweakBar
|
174 : |
|
|
TwInit (TW_OPENGL, 0);
|
175 : |
|
|
|
176 : |
jhr |
1882 |
// create a tweakbar
|
177 : |
|
|
TwBar *tweakBar = TwNewBar("Controls");
|
178 : |
|
|
state.ctls = tweakBar;
|
179 : |
|
|
unsigned int NumSteps = 0;
|
180 : |
|
|
TwAddVarRO (tweakBar, "NumSteps", TW_TYPE_UINT32, &NumSteps, " label='# of steps' ");
|
181 : |
|
|
TwAddButton (tweakBar, "StartButton", StartButtonCB, &state, " label='Start' ");
|
182 : |
jhr |
1880 |
|
183 : |
jhr |
1882 |
// Set GLFW event callbacks
|
184 : |
|
|
glfwSetWindowSizeCallback (WindowSizeCB);
|
185 : |
|
|
glfwSetMouseButtonCallback ((GLFWmousebuttonfun)TwEventMouseButtonGLFW); // redirect to AntTweakBar
|
186 : |
|
|
glfwSetMousePosCallback ((GLFWmouseposfun)TwEventMousePosGLFW); // redirect to AntTweakBar
|
187 : |
|
|
glfwSetMouseWheelCallback ((GLFWmousewheelfun)TwEventMouseWheelGLFW); // redirect to AntTweakBar
|
188 : |
|
|
glfwSetKeyCallback ((GLFWkeyfun)TwEventKeyGLFW); // redirect to AntTweakBar
|
189 : |
|
|
glfwSetCharCallback ((GLFWcharfun)TwEventCharGLFW); // redirect to AntTweakBar
|
190 : |
|
|
|
191 : |
jhr |
1880 |
// load Diderot image as nrrd file
|
192 : |
jhr |
1882 |
Diderot = nrrdNew();
|
193 : |
|
|
if (nrrdLoad(Diderot, "data/ddro-80.nrrd", 0) != 0) {
|
194 : |
jhr |
1880 |
char *msg = biffGetDone(NRRD);
|
195 : |
|
|
fprintf (stderr, "Error loading nrrd file: %s", msg);
|
196 : |
|
|
free (msg);
|
197 : |
|
|
return 0;
|
198 : |
|
|
}
|
199 : |
|
|
|
200 : |
jhr |
1882 |
InitTexture (Diderot);
|
201 : |
|
|
|
202 : |
|
|
// Main loop (repeated while window is not closed and [ESC] is not pressed)
|
203 : |
|
|
while (glfwGetWindowParam(GLFW_OPENED) && !glfwGetKey(GLFW_KEY_ESC)) {
|
204 : |
|
|
Draw();
|
205 : |
|
|
}
|
206 : |
|
|
|
207 : |
|
|
#ifdef DIDEROT_CODE
|
208 : |
jhr |
1880 |
ISO_World_t *wrld = ISO_Init ();
|
209 : |
|
|
|
210 : |
|
|
ISO_Initially (wrld);
|
211 : |
|
|
|
212 : |
|
|
uint32_t nSteps = ISO_Run (wrld, 0);
|
213 : |
|
|
|
214 : |
|
|
// get results
|
215 : |
|
|
Nrrd *nData = nrrdNew();
|
216 : |
|
|
if (ISO_OutputGet_outRGBA (wrld, nData)) {
|
217 : |
|
|
// error
|
218 : |
|
|
fprintf(stderr, "Error getting nrrd data\n");
|
219 : |
|
|
return 1;
|
220 : |
|
|
}
|
221 : |
|
|
|
222 : |
|
|
if (nrrdSave("out.nrrd", nData, NULL)) {
|
223 : |
|
|
char *err = biffGetDone(NRRD);
|
224 : |
|
|
fprintf(stderr, "Trouble saving nrrd struct: %s\n", err);
|
225 : |
|
|
return 1;
|
226 : |
|
|
}
|
227 : |
|
|
|
228 : |
|
|
ISO_Shutdown (wrld);
|
229 : |
jhr |
1882 |
#endif
|
230 : |
jhr |
1880 |
|
231 : |
jhr |
1882 |
// Terminate AntTweakBar and GLFW
|
232 : |
|
|
TwTerminate();
|
233 : |
|
|
glfwTerminate();
|
234 : |
|
|
|
235 : |
jhr |
1880 |
return 0;
|
236 : |
|
|
}
|