/* render.c */ /* visualizes a grid from a file */ #include #include #include #include #ifdef __APPLE__ #include #else #include #endif #include "grid.h" GLfloat red[3] = {1.0, 0.0, 0.0}; GLfloat green[3] = {0.0, 1.0, 0.0}; GLfloat blue[3] = {0.0, 0.0, 1.0}; GLfloat black[3] = {0.0, 0.0, 0.0}; GLfloat white[3] = {1.0, 1.0, 1.0}; GLfloat gray[3] = {0.5, 0.5, 0.5}; GLfloat yellow[3] = {1.0, 1.0, 0.0}; GLfloat magenta[3] = {1.0, 0.0, 1.0}; GLfloat cyan[3] = {0.0, 1.0, 1.0}; struct { int fillmode; Grid g; float xres; float yres; GLfloat *nodatacolor; int colorsetting; float max_side; float rot[3]; float pos[3]; float scale; } glSettings; /* forward declarations of functions */ void display(void); void eleColor(int,float); void keypress(unsigned char key, int x, int y); void main_menu(int value); int main(int argc, char** argv) { glSettings.fillmode = 0; glSettings.nodatacolor = black; glSettings.colorsetting = 0; glSettings.rot[0] = glSettings.rot[1] = glSettings.rot[2]; glSettings.pos[0] = glSettings.pos[1] = glSettings.pos[2]; glSettings.scale = 1.0; if (argc < 2) { printf("Usage: %s file-name\n", argv[0]); return 0; } switch (gopen(&glSettings.g, argv[1])) { case 0: printf("File %s opened successfully\n", argv[1]); break; default: printf("Error opening file"); return 0; break; } if (argc > 2) { if (glSettings.g.cellsize > 1) gmultf(&glSettings.g, 1. / (float)(glSettings.g.cellsize)); else gmultf(&glSettings.g, (float)(glSettings.g.cellsize)); } glSettings.max_side = glSettings.g.ncols; if (glSettings.g.nrows > glSettings.max_side) glSettings.max_side = glSettings.g.nrows; if (glSettings.g.maxval - glSettings.g.minval > glSettings.max_side) glSettings.max_side = glSettings.g.maxval - glSettings.g.minval; glSettings.max_side *= 1.2; glSettings.xres = glSettings.g.ncols / 100; if (glSettings.xres < 1) glSettings.xres = 1; glSettings.yres = glSettings.g.nrows / 100; if (glSettings.yres < 1) glSettings.yres = 1; /* open a window */ //glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(750,750); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); /* OpenGL init */ glClearColor(0, 0, 0, 0); /* set background color black*/ //glEnable(GL_DEPTH_TEST); /* callback functions */ glutDisplayFunc(display); glutKeyboardFunc(keypress); glutCreateMenu(main_menu); glutAddMenuEntry("Fill/Outline", 1); glutAddMenuEntry("Full Resolution", 2); glutAddMenuEntry("Change color", 3); glutAddMenuEntry("Quit", 0); glutAttachMenu(GLUT_RIGHT_BUTTON); /* event handler */ glutMainLoop(); return 0; } void drawGrid(){ Grid g = glSettings.g; int i, j, **row, *crt, *undr, xres = glSettings.xres, yres = glSettings.yres; float colinc = 2.0 / (float)g.ncols, rowinc = 2.0 / (float)g.nrows, eleinc = 1.0 / (float)(g.maxval - g.minval); if (glSettings.fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } row = g.tbl; int xcoord = -1 * (g.ncols - 1)/2, ycoord = g.nrows / 2, lst = g.minval; for (i=0; i < g.nrows - 1; i += yres) { crt = *row; if (i + yres >= g.nrows) undr = *(row + g.nrows - i - 1); else undr = *(row + yres); xcoord = -1 * (g.ncols - 1) / 2; glBegin(GL_TRIANGLE_STRIP); for (j=0; j < g.ncols; j+=xres) { eleColor(*crt, eleinc); if (*crt != g.nodataval) glVertex3f(xcoord, ycoord, *crt); else glVertex3f(xcoord, ycoord, g.minval); eleColor(*undr, eleinc); if (*undr != g.nodataval) glVertex3f(xcoord, ycoord - yres, *undr); else glVertex3f(xcoord, ycoord - yres, g.minval); crt += xres; undr += xres; xcoord += xres; } glEnd(); row += yres; ycoord -= yres; } } void eleColor(int ele, float colorstep) { if (ele == glSettings.g.nodataval) { glColor3fv(glSettings.nodatacolor); return; } //printf("eleinc in grid: %f\n",colorstep); int minval = glSettings.g.minval; float elevation = (float)(ele - minval), color[3] = {0,0,0}; switch(glSettings.colorsetting) { default: glSettings.colorsetting = 0; case 0: color[0] = elevation * 2. * colorstep; if (color[0] > 1.0) color[0] = 1.0; color[1] = 2. - elevation * 2. * colorstep; if (color[1] > 1.0) color[1] = 1.0; break; case 1: color[1] = elevation * 2. * colorstep; if (color[1] > 1.0) color[1] = 1.0; color[0] = 2. - elevation * 2. * colorstep; if (color[0] > 1.0) color[0] = 1.0; break; case 2: color[0] = elevation * 2. * colorstep; if (color[0] > 1.0) color[0] = 1.0; color[2] = 2. - elevation * 2. * colorstep; if (color[2] > 1.0) color[2] = 1.0; break; case 3: color[1] = color[2] = elevation * 2. * colorstep; if (color[1] > 1.0) color[1] = color[2] = 1.0; color[0] = 2. - elevation * 2. * colorstep; if (color[0] > 1.0) color[0] = 1.0; break; case 4: color[0] = color[1] = color[2] = elevation * colorstep; break; case 5: color[0] = color[1] = color[2] = 1.0 - elevation * colorstep; break; } glColor3fv(color); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3fv(blue); /* set draw color blue */ glLoadIdentity(); glMatrixMode (GL_PROJECTION); glLoadIdentity(); float translation = (glSettings.g.maxval + glSettings.g.minval) / 2, maxo2 = (glSettings.max_side / 2); glOrtho(- maxo2, maxo2, - maxo2, maxo2, maxo2, - 2 * maxo2 * glSettings.scale); glMatrixMode (GL_MODELVIEW); glTranslatef(glSettings.pos[0],glSettings.pos[1],glSettings.pos[2]); glRotatef(glSettings.rot[0],-1,0,0); glRotatef(glSettings.rot[1],0,-1,0); glRotatef(glSettings.rot[2],0,0,-1); glTranslatef(0,0, - (float)translation); glScalef(glSettings.scale,glSettings.scale,glSettings.scale); drawGrid(); /* execute the drawing commands */ glFlush(); } void keypress(unsigned char key, int x, int y) { switch(key) { case 'u': exit(0); break; case 'f': glSettings.fillmode = !glSettings.fillmode; break; case '+': if (glSettings.xres == 1 && glSettings.yres == 1) return; glSettings.xres = (float)glSettings.xres / 1.1; if (glSettings.xres < 1) glSettings.xres = 1; glSettings.yres = (float)glSettings.yres / 1.1; if (glSettings.yres < 1) glSettings.yres = 1; break; case '-': if (glSettings.xres < glSettings.g.ncols) glSettings.xres = (float)glSettings.xres * 1.1; if (glSettings.yres < glSettings.g.nrows) glSettings.yres = (float)glSettings.yres * 1.1; break; case 'l': glSettings.colorsetting++; break; case '0': glSettings.scale = 1.0; break; case '1': glSettings.scale -= .05; break; case '2': glSettings.pos[1] -= (float)glSettings.max_side / 50.; break; case '3': glSettings.pos[2] += (float)glSettings.max_side / 50.; break; case '4': glSettings.pos[0] -= (float)glSettings.max_side / 50.; break; case '5': glSettings.pos[0] = glSettings.pos[1] = glSettings.pos[2] = 0; break; case '6': glSettings.pos[0] += (float)glSettings.max_side / 50.; break; case '7': glSettings.scale += .05; break; case '8': glSettings.pos[1] += (float)glSettings.max_side / 50.; break; case '9': glSettings.pos[2] -= (float)glSettings.max_side / 50.; break; case 'z': if (glSettings.rot[0] <= 0) glSettings.rot[0] = 360; glSettings.rot[0] -= 5.0; break; case 'x': glSettings.rot[0] = 0; break; case 'c': if (glSettings.rot[0] >= 360) glSettings.rot[0] = 0; glSettings.rot[0] += 5.0; break; case 'a': if (glSettings.rot[1] <= 0) glSettings.rot[1] = 360; glSettings.rot[1] -= 5.0; break; case 's': glSettings.rot[1] = 0; break; case 'd': if (glSettings.rot[1] >= 360) glSettings.rot[1] = 0; glSettings.rot[1] += 5.0; break; case 'q': if (glSettings.rot[2] <= 0) glSettings.rot[2] = 360; glSettings.rot[2] -= 5.0; break; case 'w': glSettings.rot[2] = 0; break; case 'e': if (glSettings.rot[2] >= 360) glSettings.rot[2] = 0; glSettings.rot[2] += 5.0; break; default: return; break; } glutPostRedisplay(); } void main_menu(int value) { switch (value){ case 1: /* toggle outline/fill */ glSettings.fillmode = !glSettings.fillmode; break; case 2: glSettings.xres = 1; glSettings.yres = 1; break; case 3: glSettings.colorsetting++; break; case 0: exit(0); default: return; } glutPostRedisplay(); }