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

SCM Repository

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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3086 - (download) (as text) (annotate)
Tue Mar 17 16:35:19 2015 UTC (4 years, 5 months ago) by jhr
File size: 8577 byte(s)
  update example for changes in initialization
/*! \file main.c
 *
 * \author John Reppy
 *
 * Main program for Diderot ISO2d animation.
 */

/*
 * 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 "load-png.h"
#include "iso2d.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 *positions)
{
  // 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 background
    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: %s", ISO_GetErrors(wrld));
        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_New ();
    if (wrld == 0) {
	fprintf (stderr, "Unable to create Diderot world\n");
	exit (1);
    }
    if (ISO_Init(wrld)) {
	fprintf (stderr, "Error initializing Diderot: %s", ISO_GetErrors(wrld));
	exit (1);
    }
    ISO_InVarSet_stepScale (wrld, 0.05);
    ISO_InVarSet_stepsMax (wrld, 200);
    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 * 50);  // 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