Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /examples/iso2d-demo/main.c
ViewVC logotype

Annotation of /examples/iso2d-demo/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3349 - (view) (download) (as text)

1 : jhr 1880 /*! \file main.c
2 :     *
3 :     * \author John Reppy
4 :     *
5 :     * Main program for Diderot ISO2d animation.
6 :     */
7 :    
8 :     /*
9 : jhr 3349 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
10 :     *
11 :     * COPYRIGHT (c) 2015 The University of Chicago
12 : jhr 1880 * All rights reserved.
13 :     */
14 :    
15 :     #include <AntTweakBar.h>
16 : jhr 1882 #include "GL/glfw.h"
17 : jhr 1884 #include "util.h"
18 :     #include "load-png.h"
19 : jhr 1918 #include "iso2d.h"
20 : jhr 1920 #include <unistd.h>
21 : jhr 1880
22 :     /* pixel dimensions of output */
23 : jhr 1920 #define WIDTH 990
24 :     #define HEIGHT 990
25 : jhr 1880
26 : jhr 1920 /* world bounds */
27 :     #define WRLD_MIN_X 0.0
28 :     #define WRLD_MIN_Y 0.0
29 :     #define WRLD_MAX_X 1.0
30 :     #define WRLD_MAX_Y 1.0
31 :     #define WRLD_CENTER_X 0.5
32 :     #define WRLD_CENTER_Y 0.5
33 :    
34 : jhr 1918 #define STEP_SIZE 1
35 : jhr 1920 #define SLEEP_MS 250
36 : jhr 1918
37 : jhr 1884 static inline void CheckError ()
38 :     {
39 :     GLenum errCode;
40 :     if ((errCode = glGetError()) != GL_NO_ERROR) {
41 :     fprintf(stderr, "OpenGL error: %s\n", gluErrorString(errCode));
42 :     exit (1);
43 :     }
44 :     }
45 :    
46 : jhr 1880 /***** Globals for viewing, etc. *****/
47 :    
48 :     Nrrd *Diderot; // input image nrrd
49 :     unsigned int Width; // view window width
50 :     unsigned int Height; // view window height
51 : jhr 1884 GLuint ImageTexture; // Texture ID of background image
52 : jhr 1921 float WrldOrigin[2];
53 :     float WrldDim[2];
54 : jhr 1880
55 : jhr 1882 typedef struct {
56 :     TwBar *ctls;
57 :     unsigned int running;
58 :     } State_t;
59 :    
60 : jhr 1880 // Callback function called by GLUT to render screen
61 : jhr 1913 void Draw (Nrrd *positions)
62 : jhr 1880 {
63 :     // Clear frame buffer
64 :     glClearColor (0, 0, 0, 1);
65 :     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
66 :    
67 : jhr 1920 glDisable(GL_DEPTH_TEST);
68 : jhr 1880 glDisable(GL_CULL_FACE);
69 :    
70 :     // Draw background
71 : jhr 1884 glEnable (GL_TEXTURE_2D);
72 : jhr 1920 glActiveTexture (GL_TEXTURE0);
73 :     glBindTexture (GL_TEXTURE_2D, ImageTexture);
74 : jhr 1884 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
75 : jhr 1882 glBegin (GL_QUADS);
76 : jhr 1884 glColor3f (0.1, 0.1, 0.1);
77 : jhr 1882 glTexCoord2f (0.0, 0.0);
78 : jhr 1921 glVertex2f (WrldOrigin[0], WrldOrigin[1]);
79 : jhr 1882 glTexCoord2f (1.0, 0.0);
80 : jhr 1921 glVertex2f (WrldOrigin[0]+WrldDim[0], WrldOrigin[1]);
81 : jhr 1882 glTexCoord2f (1.0, 1.0);
82 : jhr 1921 glVertex2f (WrldOrigin[0]+WrldDim[0], WrldOrigin[1]+WrldDim[1]);
83 : jhr 1882 glTexCoord2f (0.0, 1.0);
84 : jhr 1921 glVertex2f (WrldOrigin[0], WrldOrigin[1]+WrldDim[1]);
85 : jhr 1882 glEnd();
86 : jhr 1884 glDisable (GL_TEXTURE_2D);
87 :     CheckError ();
88 : jhr 1880
89 : jhr 1920 // Draw current particle state
90 :     glEnable (GL_POINT_SMOOTH);
91 :     // glPointSize (2.0);
92 :     // it would be more efficient to do this as a single buffer, but it is fast enough
93 :     float *p = (float *)(positions->data);
94 :     unsigned int nPoints = positions->axis[1].size;
95 :     glBegin (GL_POINTS);
96 :     // first draw some points at known locations for testing purposes
97 :     // glColor3f (1.0, 0.0, 0.0);
98 :     // glVertex2f (WRLD_MIN_X, WRLD_MIN_Y);
99 :     // glVertex2f (WRLD_MAX_X, WRLD_MIN_Y);
100 :     // glVertex2f (WRLD_MAX_X, WRLD_MAX_Y);
101 :     // glVertex2f (WRLD_MIN_X, WRLD_MAX_Y);
102 :     glColor3f (0.2, 1.0, 0.2);
103 :     for (int i = 0; i < nPoints; i++) {
104 :     glVertex2fv(p);
105 :     p += 2;
106 :     }
107 :     glEnd ();
108 : jhr 1880
109 :     // Draw tweak bars
110 :     TwDraw();
111 :    
112 :     // Present frame buffer
113 : jhr 1882 glfwSwapBuffers();
114 : jhr 1880 }
115 :    
116 : jhr 1882 // Callback function called by GLFW when window size changes
117 :     void GLFWCALL WindowSizeCB (int width, int height)
118 : jhr 1880 {
119 : jhr 1920 printf("window size = %d x %d\n", width, height);
120 : jhr 1880 // Set OpenGL viewport and camera
121 : jhr 1882 glViewport(0, 0, width, height);
122 :    
123 : jhr 1920 glMatrixMode (GL_PROJECTION);
124 :     glLoadIdentity ();
125 :     double pad = 0.05*(WRLD_MAX_X - WRLD_MIN_X); // add 10% to world dimensions
126 :     gluOrtho2D (
127 :     WRLD_MIN_X - pad, WRLD_MAX_X + pad,
128 :     WRLD_MAX_Y + pad, WRLD_MIN_Y - pad);
129 :    
130 : jhr 1880 glMatrixMode (GL_MODELVIEW);
131 :     glLoadIdentity ();
132 : jhr 1882 gluLookAt (
133 : jhr 1920 // WRLD_CENTER_X, WRLD_CENTER_Y, 1.0,
134 :     0.0, 0.0, 1.0,
135 :     // WRLD_CENTER_X, WRLD_CENTER_Y, 0.0,
136 :     0.0, 0.0, 0.0,
137 : jhr 1882 0.0, 1.0, 0.0);
138 : jhr 1880
139 : jhr 1882 // Send the new window size to AntTweakBar
140 :     TwWindowSize(width, height);
141 : jhr 1880
142 :     // remember width and height
143 :     Width = width;
144 :     Height = height;
145 :    
146 :     }
147 :    
148 :     // initialize a texture from a grayscale Nrrd file
149 : jhr 1884 void InitTexture ()
150 : jhr 1880 {
151 : jhr 1920 Image2D_t *img = LoadImage ("data/ddro-tx.png", true, GRAY_IMAGE);
152 : jhr 1884 if (img == 0) {
153 :     fprintf (stderr, "unable to load texture file\n");
154 : jhr 1880 exit (1);
155 :     }
156 :    
157 :     // generate the TeXID
158 :     GLuint texId;
159 :     glGenTextures (1, &texId);
160 :    
161 :     // load the texture data
162 :     glBindTexture (GL_TEXTURE_2D, texId);
163 : jhr 1884 int sts = TexImage (img);
164 :     if (sts != GL_NO_ERROR) {
165 :     fprintf(stderr, "error loading texture\n");
166 :     exit (1);
167 :     }
168 : jhr 1920 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
169 :     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
170 : jhr 1880
171 : jhr 1884 FreeImage (img);
172 :    
173 : jhr 1880 ImageTexture = texId;
174 :     }
175 :    
176 : jhr 1882 void TW_CALL StartButtonCB (void *data)
177 :     {
178 :     State_t *st = (State_t *)data;
179 :    
180 :     if (st->running == 0) {
181 :     st->running = 1;
182 :     TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Stop");
183 :     }
184 :     else {
185 :     st->running = 0;
186 :     TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Start");
187 :     }
188 :     }
189 :    
190 : jhr 1918 void GetData (ISO_World_t *wrld, Nrrd *nData)
191 :     {
192 :     // get snapshot of state
193 :     if (ISO_Snapshot_pos (wrld, nData)) {
194 :     // error
195 : jhr 3086 fprintf(stderr, "Error getting nrrd data: %s", ISO_GetErrors(wrld));
196 : jhr 1918 exit(1);
197 :     }
198 :     }
199 :    
200 : jhr 1880 int main (int argc, const char **argv)
201 :     {
202 : jhr 1882 State_t state = { .running = 0 };
203 : jhr 1880
204 : jhr 1882 // Initialize GLFW
205 :     if (0 == glfwInit()) {
206 :     // An error occured
207 :     fprintf(stderr, "GLFW initialization failed\n");
208 :     return 1;
209 :     }
210 : jhr 1880
211 : jhr 1882 GLFWvidmode mode;
212 :     glfwGetDesktopMode (&mode);
213 :     if (0 == glfwOpenWindow(WIDTH, HEIGHT, mode.RedBits, mode.GreenBits, mode.BlueBits, 0, 0, 0, GLFW_WINDOW) ) {
214 :     // A fatal error occured
215 :     fprintf(stderr, "Cannot open GLFW window\n");
216 :     glfwTerminate();
217 :     return 1;
218 :     }
219 :     glfwEnable(GLFW_MOUSE_CURSOR);
220 :     glfwEnable(GLFW_KEY_REPEAT);
221 :     glfwSetWindowTitle("Diderot Iso2D Animation");
222 :    
223 : jhr 1880 // Initialize AntTweakBar
224 :     TwInit (TW_OPENGL, 0);
225 :    
226 : jhr 1882 // create a tweakbar
227 :     TwBar *tweakBar = TwNewBar("Controls");
228 :     state.ctls = tweakBar;
229 :     unsigned int NumSteps = 0;
230 :     TwAddVarRO (tweakBar, "NumSteps", TW_TYPE_UINT32, &NumSteps, " label='# of steps' ");
231 :     TwAddButton (tweakBar, "StartButton", StartButtonCB, &state, " label='Start' ");
232 : jhr 1880
233 : jhr 1882 // Set GLFW event callbacks
234 :     glfwSetWindowSizeCallback (WindowSizeCB);
235 :     glfwSetMouseButtonCallback ((GLFWmousebuttonfun)TwEventMouseButtonGLFW); // redirect to AntTweakBar
236 :     glfwSetMousePosCallback ((GLFWmouseposfun)TwEventMousePosGLFW); // redirect to AntTweakBar
237 :     glfwSetMouseWheelCallback ((GLFWmousewheelfun)TwEventMouseWheelGLFW); // redirect to AntTweakBar
238 :     glfwSetKeyCallback ((GLFWkeyfun)TwEventKeyGLFW); // redirect to AntTweakBar
239 :     glfwSetCharCallback ((GLFWcharfun)TwEventCharGLFW); // redirect to AntTweakBar
240 :    
241 : jhr 1884 // load Diderot image for background texture
242 :     InitTexture ();
243 : jhr 1880
244 : jhr 1921 // setup the world coords.
245 :     // FIXME: we should get these from the nrrd file, but for now I'm hard coding them
246 :     WrldOrigin[0] = -0.0184375;
247 :     WrldOrigin[1] = -0.0184375;
248 :     WrldDim[0] = 0.013125 * 80.0;
249 :     WrldDim[1] = 0.013125 * 80.0;
250 :    
251 : jhr 1918 // initialize the Diderot program
252 : jhr 3086 ISO_World_t *wrld = ISO_New ();
253 :     if (wrld == 0) {
254 :     fprintf (stderr, "Unable to create Diderot world\n");
255 :     exit (1);
256 :     }
257 :     if (ISO_Init(wrld)) {
258 :     fprintf (stderr, "Error initializing Diderot: %s", ISO_GetErrors(wrld));
259 :     exit (1);
260 :     }
261 : jhr 2079 ISO_InVarSet_stepScale (wrld, 0.05);
262 :     ISO_InVarSet_stepsMax (wrld, 200);
263 : jhr 1880 ISO_Initially (wrld);
264 :    
265 : jhr 1918 // nrrd for getting computational state
266 : jhr 1913 Nrrd *nData = nrrdNew();
267 : jhr 1880
268 : jhr 1918 // get and render initial state
269 :     GetData (wrld, nData);
270 : jhr 1913 Draw (nData);
271 : jhr 1880
272 : jhr 1918 // Main loop (repeated while window is not closed and [ESC] is not pressed)
273 :     while (glfwGetWindowParam(GLFW_OPENED) && !glfwGetKey(GLFW_KEY_ESC)) {
274 :     if (state.running != 0) {
275 :     while ((state.running != 0) && (ISO_NumActive(wrld) > 0)) {
276 :     // step the computation
277 :     NumSteps += ISO_Run (wrld, STEP_SIZE);
278 :     // get and render the state
279 :     GetData (wrld, nData);
280 :     Draw (nData);
281 : jhr 2079 usleep (SLEEP_MS * 50); // sleep for a bit
282 : jhr 1918 }
283 :     if (ISO_NumActive(wrld) == 0) {
284 :     // get and render final state
285 :     if (ISO_OutputGet_pos (wrld, nData)) {
286 :     // error
287 :     fprintf(stderr, "Error getting nrrd data\n");
288 :     exit(1);
289 :     }
290 :     Draw (nData);
291 :     }
292 :     }
293 :     else {
294 :     glfwWaitEvents();
295 :     Draw(nData);
296 :     }
297 :     }
298 :    
299 :     // shutdown the world
300 : jhr 1880 ISO_Shutdown (wrld);
301 :    
302 : jhr 1882 // Terminate AntTweakBar and GLFW
303 :     TwTerminate();
304 :     glfwTerminate();
305 :    
306 : jhr 1880 return 0;
307 :     }

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0