SCM Repository
View of /examples/vr-demo/main.c
Parent Directory
|
Revision Log
Revision 2058 -
(download)
(as text)
(annotate)
Tue Oct 30 10:38:25 2012 UTC (9 years, 6 months ago) by jhr
File size: 8230 byte(s)
Tue Oct 30 10:38:25 2012 UTC (9 years, 6 months ago) by jhr
File size: 8230 byte(s)
Working on vr-lite demo
/*! \file main.c * * \author John Reppy * * Main program for Diderot VR viewer. */ /* * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu) * All rights reserved. */ #include <AntTweakBar.h> #include "GL/glfw.h" #include "util.h" #include "vr-lite.h" #include <unistd.h> /* pixel dimensions of output */ #define WIDTH 990 #define HEIGHT 990 /* world bounds */ #define WRLD_MIN_X 0.0 #define WRLD_MIN_Y 0.0 #define WRLD_MAX_X 1.0 #define WRLD_MAX_Y 1.0 #define WRLD_CENTER_X 0.5 #define WRLD_CENTER_Y 0.5 #define STEP_SIZE 1 #define SLEEP_MS 250 static inline void CheckError () { GLenum errCode; if ((errCode = glGetError()) != GL_NO_ERROR) { fprintf(stderr, "OpenGL error: %s\n", gluErrorString(errCode)); exit (1); } } /***** Globals for viewing, etc. *****/ Nrrd *Diderot; // input image nrrd unsigned int Width; // view window width unsigned int Height; // view window height GLuint ImageTexture; // Texture ID of background image float WrldOrigin[2]; float WrldDim[2]; typedef struct { TwBar *ctls; unsigned int running; } State_t; // Callback function called by GLUT to render screen void Draw (Nrrd *img) { // Clear frame buffer glClearColor (0, 0, 0, 1); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); // Draw image glEnable (GL_TEXTURE_2D); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, ImageTexture); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBegin (GL_QUADS); glColor3f (0.1, 0.1, 0.1); glTexCoord2f (0.0, 0.0); glVertex2f (WrldOrigin[0], WrldOrigin[1]); glTexCoord2f (1.0, 0.0); glVertex2f (WrldOrigin[0]+WrldDim[0], WrldOrigin[1]); glTexCoord2f (1.0, 1.0); glVertex2f (WrldOrigin[0]+WrldDim[0], WrldOrigin[1]+WrldDim[1]); glTexCoord2f (0.0, 1.0); glVertex2f (WrldOrigin[0], WrldOrigin[1]+WrldDim[1]); glEnd(); glDisable (GL_TEXTURE_2D); CheckError (); // Draw current particle state glEnable (GL_POINT_SMOOTH); // glPointSize (2.0); // it would be more efficient to do this as a single buffer, but it is fast enough float *p = (float *)(positions->data); unsigned int nPoints = positions->axis[1].size; glBegin (GL_POINTS); // first draw some points at known locations for testing purposes // glColor3f (1.0, 0.0, 0.0); // glVertex2f (WRLD_MIN_X, WRLD_MIN_Y); // glVertex2f (WRLD_MAX_X, WRLD_MIN_Y); // glVertex2f (WRLD_MAX_X, WRLD_MAX_Y); // glVertex2f (WRLD_MIN_X, WRLD_MAX_Y); glColor3f (0.2, 1.0, 0.2); for (int i = 0; i < nPoints; i++) { glVertex2fv(p); p += 2; } glEnd (); // Draw tweak bars TwDraw(); // Present frame buffer glfwSwapBuffers(); } // Callback function called by GLFW when window size changes void GLFWCALL WindowSizeCB (int width, int height) { printf("window size = %d x %d\n", width, height); // Set OpenGL viewport and camera glViewport(0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); double pad = 0.05*(WRLD_MAX_X - WRLD_MIN_X); // add 10% to world dimensions gluOrtho2D ( WRLD_MIN_X - pad, WRLD_MAX_X + pad, WRLD_MAX_Y + pad, WRLD_MIN_Y - pad); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt ( // WRLD_CENTER_X, WRLD_CENTER_Y, 1.0, 0.0, 0.0, 1.0, // WRLD_CENTER_X, WRLD_CENTER_Y, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // Send the new window size to AntTweakBar TwWindowSize(width, height); // remember width and height Width = width; Height = height; } // initialize a texture from a grayscale Nrrd file void InitTexture () { Image2D_t *img = LoadImage ("data/ddro-tx.png", true, GRAY_IMAGE); if (img == 0) { fprintf (stderr, "unable to load texture file\n"); exit (1); } // generate the TeXID GLuint texId; glGenTextures (1, &texId); // load the texture data glBindTexture (GL_TEXTURE_2D, texId); int sts = TexImage (img); if (sts != GL_NO_ERROR) { fprintf(stderr, "error loading texture\n"); exit (1); } glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); FreeImage (img); ImageTexture = texId; } void TW_CALL StartButtonCB (void *data) { State_t *st = (State_t *)data; if (st->running == 0) { st->running = 1; TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Stop"); } else { st->running = 0; TwSetParam (st->ctls, "StartButton", "label", TW_PARAM_CSTRING, 1, "Start"); } } void GetData (ISO_World_t *wrld, Nrrd *nData) { // get snapshot of state if (ISO_Snapshot_pos (wrld, nData)) { // error fprintf(stderr, "Error getting nrrd data\n"); exit(1); } } int main (int argc, const char **argv) { State_t state = { .running = 0 }; // Initialize GLFW if (0 == glfwInit()) { // An error occured fprintf(stderr, "GLFW initialization failed\n"); return 1; } GLFWvidmode mode; glfwGetDesktopMode (&mode); if (0 == glfwOpenWindow(WIDTH, HEIGHT, mode.RedBits, mode.GreenBits, mode.BlueBits, 0, 0, 0, GLFW_WINDOW) ) { // A fatal error occured fprintf(stderr, "Cannot open GLFW window\n"); glfwTerminate(); return 1; } glfwEnable(GLFW_MOUSE_CURSOR); glfwEnable(GLFW_KEY_REPEAT); glfwSetWindowTitle("Diderot Iso2D Animation"); // Initialize AntTweakBar TwInit (TW_OPENGL, 0); // create a tweakbar TwBar *tweakBar = TwNewBar("Controls"); state.ctls = tweakBar; unsigned int NumSteps = 0; TwAddVarRO (tweakBar, "NumSteps", TW_TYPE_UINT32, &NumSteps, " label='# of steps' "); TwAddButton (tweakBar, "StartButton", StartButtonCB, &state, " label='Start' "); // Set GLFW event callbacks glfwSetWindowSizeCallback (WindowSizeCB); glfwSetMouseButtonCallback ((GLFWmousebuttonfun)TwEventMouseButtonGLFW); // redirect to AntTweakBar glfwSetMousePosCallback ((GLFWmouseposfun)TwEventMousePosGLFW); // redirect to AntTweakBar glfwSetMouseWheelCallback ((GLFWmousewheelfun)TwEventMouseWheelGLFW); // redirect to AntTweakBar glfwSetKeyCallback ((GLFWkeyfun)TwEventKeyGLFW); // redirect to AntTweakBar glfwSetCharCallback ((GLFWcharfun)TwEventCharGLFW); // redirect to AntTweakBar // load Diderot image for background texture InitTexture (); // setup the world coords. // FIXME: we should get these from the nrrd file, but for now I'm hard coding them WrldOrigin[0] = -0.0184375; WrldOrigin[1] = -0.0184375; WrldDim[0] = 0.013125 * 80.0; WrldDim[1] = 0.013125 * 80.0; // initialize the Diderot program ISO_World_t *wrld = ISO_Init (); ISO_Initially (wrld); // nrrd for getting computational state Nrrd *nData = nrrdNew(); // get and render initial state GetData (wrld, nData); Draw (nData); // Main loop (repeated while window is not closed and [ESC] is not pressed) while (glfwGetWindowParam(GLFW_OPENED) && !glfwGetKey(GLFW_KEY_ESC)) { if (state.running != 0) { while ((state.running != 0) && (ISO_NumActive(wrld) > 0)) { // step the computation NumSteps += ISO_Run (wrld, STEP_SIZE); // get and render the state GetData (wrld, nData); Draw (nData); usleep (SLEEP_MS * 1000); // sleep for a bit } if (ISO_NumActive(wrld) == 0) { // get and render final state if (ISO_OutputGet_pos (wrld, nData)) { // error fprintf(stderr, "Error getting nrrd data\n"); exit(1); } Draw (nData); } } else { glfwWaitEvents(); Draw(nData); } } // shutdown the world ISO_Shutdown (wrld); // Terminate AntTweakBar and GLFW TwTerminate(); glfwTerminate(); return 0; }
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |