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

SCM Repository

[diderot] View of /examples/vr-demo/main.c
ViewVC logotype

View of /examples/vr-demo/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2061 - (download) (as text) (annotate)
Tue Oct 30 21:55:10 2012 UTC (6 years, 8 months ago) by jhr
File size: 6935 byte(s)
  Working on VR 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 "GL/glfw.h"
#include "util.h"
#include "vr-lite.h"
#include <unistd.h>

/* minimum and maximum values from */
#define MIN_VALUE	0
#define MAX_VALUE	2632

/* half the width of the opacity range */
#define OPAC_HALF_WID	150

#define MIN_OPAC_MID	((float)(MIN_VALUE+OPAC_HALF_WID))
#define MAX_OPAC_MID	((float)(MAX_VALUE-OPAC_HALF_WID))

/* pixel dimensions of output */
#define WIDTH   480
#define HEIGHT  345

/* 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



// 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 (VR_World_t *wrld, Nrrd *nData)
{
  // get snapshot of state
    if (VR_Snapshot_pos (wrld, nData)) {
      // error
        fprintf(stderr, "Error getting nrrd data\n");
        exit(1);
    }
}

int main (int argc, const char **argv)
{
  // 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_KEY_REPEAT);
    glfwSetWindowTitle("Diderot VR Demo");

  // Set GLFW event callbacks
    glfwSetWindowSizeCallback (WindowSizeCB);
    glfwSetKeyCallback ((GLFWkeyfun)TwEventKeyGLFW);

  // 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
    VR_World_t *wrld = VR_Init ();

  // nrrd for getting computational state
    Nrrd *nRGB = 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 (NeedsRecompute) {
	  // recompute
	    VR_Initially (wrld);
	    VR_Run (wrld, 0);
	  // get output image
	    if (VR_OutputGet_outRGBA (wrld, nRGB)) {
	      // error
		fprintf(stderr, "Error getting nrrd data\n");
		exit(1);
	    }
	}
	if (NeedsRedraw) {
	}
	glfwWaitEvents();
    }

  // shutdown the world
    VR_Shutdown (wrld);

  // Terminate AntTweakBar and GLFW
    TwTerminate();
    glfwTerminate();

    return 0;
}

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