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 2080 - (download) (as text) (annotate)
Mon Nov 5 19:07:00 2012 UTC (6 years, 7 months ago) by jhr
File size: 6880 byte(s)
  fix window resizing
/*! \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.h"
#include <unistd.h>
#include "teem/air.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))

#define OPAC_DELTA	25

/* reduced-size inputs */
#define REDUCED_WID	256
#define REDUCED_HT	184
#define REDUCED_STEP	1


/* full-size inputs */
#define FULL_WID	512
#define FULL_HT		368
#define FULL_STEP	0.5

#define WIDTH   (2*FULL_WID)
#define HEIGHT  (2*FULL_HT)

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

typedef struct {
    bool	init;
    GLuint	wid;
    GLuint	ht;
    GLuint	id;
} TexInfo_t;

VR_World_t	*World;
unsigned int    Width;          // view window width
unsigned int    Height;         // view window height
TexInfo_t	ReducedTexure = {	// Texture ID of reduced image
	false, REDUCED_WID, REDUCED_HT, 0
    };
TexInfo_t	FullTexture = {		// Texture ID of full image
	false, FULL_WID, FULL_HT, 0
    };
bool		NeedsRedraw;
bool		NeedsRecompute;
float		OpacMid = 550.0;
int		Dir = 0;		/* -1, 0, 1 */


// initialize a texture from a grayscale Nrrd file
void InitTexture (TexInfo_t *txt, Nrrd *img)
{
    if (! txt->init) {
      // generate the TeXID
	glGenTextures (1, &(txt->id));

      // load the texture data
	glBindTexture (GL_TEXTURE_2D, txt->id);
	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, txt->wid, txt->ht, 0, GL_RGBA, GL_FLOAT, img->data);
	CheckError();
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	CheckError();
    }
    else {
      // reload the texture data
	glBindTexture (GL_TEXTURE_2D, txt->id);
	glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, txt->wid, txt->ht, GL_RGBA, GL_FLOAT, img->data);
	CheckError();
    }
}

// Callback function called by GLUT to render screen
void Draw (GLuint txtId)
{
  // 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, txtId);
    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glBegin (GL_QUADS);
	glTexCoord2f (0.0, 0.0);
	glVertex2f (0.0, 0.0);
	glTexCoord2f (1.0, 0.0);
	glVertex2f (1.0, 0.0);
	glTexCoord2f (1.0, 1.0);
	glVertex2f (1.0, 1.0);
	glTexCoord2f (0.0, 1.0);
	glVertex2f (0.0, 1.0);
    glEnd();
    glDisable (GL_TEXTURE_2D);
    CheckError ();

  // Present frame buffer
    glfwSwapBuffers();
}

// Callback function called by GLFW when window size changes
void GLFWCALL WindowSizeCB (int width, int height)
{
  // Set OpenGL viewport and camera
    glViewport(0, 0, width, height);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluOrtho2D (0.0, 1.0, 0.0, 1.0);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    gluLookAt (
        0.0, 0.0, 1.0,
        0.0, 0.0, 0.0,
	0.0, 1.0, 0.0);

  // remember width and height
    Width = width;
    Height = height;

    NeedsRedraw = true;
}

void GLFWCALL KeyCB (int key, int action)
{
    switch (key) {
      case '+':
	if ((action == GLFW_PRESS) && (Dir >= 0))
	    Dir++;
	break;
      case '-':
	if ((action == GLFW_PRESS) && (Dir <= 0))
	    Dir--;
	break;
      default:
	break;
    }
}

void Compute (VR_World_t *wrld, bool fullSize, Nrrd *nRGB)
{
    printf("computing %s... ", fullSize ? "" : "(fast) "); fflush(stdout);
    double t0 = airTime();
  // setup raycast parameters
    if (fullSize) {
	VR_InVarSet_imgResU (wrld, FULL_WID);
	VR_InVarSet_imgResV (wrld, FULL_HT);
	VR_InVarSet_rayStep (wrld, FULL_STEP);
    }
    else {
	VR_InVarSet_imgResU (wrld, REDUCED_WID);
	VR_InVarSet_imgResV (wrld, REDUCED_HT);
	VR_InVarSet_rayStep (wrld, REDUCED_STEP);
    }
  // recompute
    if (VR_Initially (wrld)) {
      // error
	fprintf(stderr, "Error initializing world: %s", VR_GetErrors(wrld));
	exit(1);
    }
    int nSteps = VR_Run (wrld, 0);
    printf(" %d steps in %5.3f seconds\n", nSteps, airTime() - t0);
  // get output image
    if (VR_OutputGet_outRGBA (wrld, nRGB)) {
      // error
	fprintf(stderr, "Error getting nrrd data: %s", VR_GetErrors(wrld));
	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);
    glfwSetCharCallback (KeyCB);

  // initialize the Diderot program
    VR_World_t *wrld = VR_Init ();
    World = wrld;

  // initialize inputs
    VR_InVarSet_valOpacMid(wrld, OpacMid);
    VR_InVarSetByName_hand (wrld, "data/vfrhand-nohip.nhdr");

  // nrrd for getting computational state
    Nrrd *nRGB = nrrdNew();

  // Main loop (repeated while window is not closed and [ESC] is not pressed)
    NeedsRecompute = true;
    GLuint txtId;
    while (glfwGetWindowParam(GLFW_OPENED) && !glfwGetKey(GLFW_KEY_ESC)) {
	if (Dir < 0) {
	    Dir++;
	    float mid = OpacMid - OPAC_DELTA;
	    if (mid >= MIN_OPAC_MID) {
		OpacMid = mid;
		VR_InVarSet_valOpacMid(World, mid);
		NeedsRecompute = true;
	    }
	}
	else if (Dir > 0) {
	    Dir--;
	    float mid = OpacMid + OPAC_DELTA;
	    if (mid <= MAX_OPAC_MID) {
		OpacMid = mid;
		VR_InVarSet_valOpacMid(World, mid);
		NeedsRecompute = true;
	    }
	}
	if (NeedsRecompute) {
	    if (Dir != 0) {
		Compute(wrld, false, nRGB);
		InitTexture(&ReducedTexure, nRGB);
		txtId = ReducedTexure.id;
	    }
 	    else {
 		Compute (wrld, true, nRGB);
 		InitTexture(&FullTexture, nRGB);
 		NeedsRecompute = false;
 		txtId = FullTexture.id;
 	    }
	    NeedsRedraw = true;
	}
	if (NeedsRedraw) {
	    Draw (txtId);
	    NeedsRedraw = false;
	}
	if (NeedsRecompute)
	    glfwPollEvents();
	else
	    glfwWaitEvents();
    }

  // shutdown the world
    VR_Shutdown (wrld);

  // Terminate GLFW
    glfwTerminate();

    return 0;
}

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