Go Back
#include <GL/glut.h>
#include "ppmimage.h"
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#define PI 3.14159265358979
#define TOL 1E-5
// Window and Light Variables
int window;
float light_diffuse[] = {.05, .05, .10, 1.0};
float light_position[] = {100.0, 100.0, -5.0, 0.0};
float mat_specular[] = {1.0, 1.0, 1.0, 1.0};
float mat_shininess[] = {010};
float mat_emission[] = {0.375, 0.3, 0.25};
// Rotation of the entire system (around both axes)
int doxrot=0, doyrot=0;
// Zooming amount
float zoom = 1.0;
// Image to draw
image pic;
// Window control functions
void init();
void display();
void mouse(int button, int state, int x, int y);
void keypress(unsigned char key, int x, int y);
int main(int argc, char **argv)
{
// Load the image;
pic.load("/home/atlas1/gsivek/supercomp/cowoutln.ppm");
// Initialize OpenGL Stuff
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400,400);
// Create window and set window functions
window = glutCreateWindow("Bovine Mountain");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keypress);
// Do the OpenGL loop until the program is exited.
glutMainLoop();
return 0;
}
void init()
{
// Initialize view settings
glLoadIdentity();
gluPerspective(31.0, 1.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
// Enable lights and light settings
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
// Look from (0,0,5) to (0,0,0) with the y-axis being up
gluLookAt(0.0,0.0,5.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
}
void setNorm(double ax, double ay, double az,
double bx, double by, double bz,
double cx, double cy, double cz)
{
// Given three points (ax,ay,az),(bx,by,bz),(cx,cy,cz), calculate
// the appropiate normal vector for lighting effects. This uses
// the cross-product to do so.
float norm[3];
double d, d1[3], d2[3];
// Define vectors as differences of points...
d1[0]=bx-ax;
d1[1]=by-ay;
d1[2]=bz-az;
d2[0]=cx-bx;
d2[1]=cy-by;
d2[2]=cz-bz;
// ... and take their cross product.
norm[0] = d1[1]*d2[2] - d1[2]*d2[1];
norm[1] = d1[2]*d2[0] - d1[0]*d2[2];
norm[2] = d1[0]*d2[1] - d1[1]*d2[0];
d=sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]);
if (d < TOL) return;
norm[0] /= d;
norm[1] /= d;
norm[2] /= d;
// Assign the normal vector to the triangle!
glNormal3fv(norm);
}
void drawImage(image myImage)
{
int i, j;
double col1, col2, col3, col4;
// Change in position between pixels on the image.
double dwidth = 1/double(myImage.width);
double dheight = 1/double(myImage.height);
for (i = 0; i < myImage.width-1; i++)
{
glBegin(GL_TRIANGLE_STRIP);
// Get the first two points in a triangle strip...
col1 = myImage.getColor(i,0,RED);
col2 = myImage.getColor(i+1,0,RED);
glColor3f(0.75*col1, 0.6*col1, 0.5*col1);
glVertex3f((double(i)*dwidth)-0.5,
0.5,
-6.0*(1.0-col1)+3.0);
glColor3f(0.5*col2, 0.5*col2, 0.75*col2);
glVertex3f((double(i+1)*dwidth)-0.5,
0.5,
-6.0*(1.0-col2)+3.0);
for (j = 1; j < myImage.height; j++)
{
// ...and then proceed down the strip.
col3 = myImage.getColor(i,j,RED);
col4 = myImage.getColor(i+1,j,RED);
glColor3f(col3/10, col3/10, col3/10);
glVertex3f((double(i)*dwidth)-0.5,
(0.5-double(j)*dheight),
-6.0*(1.0-col3)+3.0);
// This makes a new triangle, so set the normal vector
setNorm(0,dheight,3-6*(1.0-col1),
dwidth,dheight,3-6*(1.0-col2),
0,0,5-10*(1.0-col3));
glColor3f(col4/10, col4/10, col4/10);
glVertex3f((double(i+1)*dwidth)-0.5,
(0.5-double(j)*dheight),
-6.0*(1.0-col4)+3.0);
// This makes a new triangle, so set the normal vector
setNorm(0,dheight,3-6*(1.0-col1),
dwidth,dheight,3-6*(1.0-col2),
0,0,5-10*(1.0-col3));
// Rotate the values; the two points calculated in this
// iteration become the old ones for the next iteration.
col1 = col3;
col2 = col4;
}
}
glEnd();
}
void display()
{
glClearColor(0.0, 0.0, 0.4, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
// Set user-specified zooming and rotation
glScalef(zoom, zoom, zoom);
glRotatef(doxrot, 1.0, 0.0, 0.0);
glRotatef(doyrot, 0.0, 1.0, 0.0);
// Rotate the screen some more anyway
glRotatef(70, 1, 0, 0);
glPushMatrix();
// This stuff draws the platform and outline.
glScalef(0.9, 0.9, 0.1);
glColor3f(0.5, 0.5, 0.75);
glPushMatrix();
glTranslatef(0.0, 0.0, 3.0);
glutSolidCube(1.0);
glLineWidth(2);
glColor3f(0.0, 0.0, 0.0);
glutWireCube(1.0);
glLineWidth(1);
glPopMatrix();
// Using the same translation (so we don't draw outside
// the cube), draw the image right above the platform.
drawImage(pic);
glPopMatrix();
glPopMatrix();
// Force drawing with double buffering.
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
// If left-click, rotate one way.
// If right-click, rotate the other way.
if (state==GLUT_DOWN)
{
if (button==0)
doxrot += 5;
else if (button==2)
doxrot -= 5;
}
}
void keypress(unsigned char key, int x, int y)
{
// If "z" then zoom out. If "Z" then zoom in.
// If "r" then rotate the camera. If "R" then rotate it the other way.
if (key == 'z')
{
zoom *= 1.2;
if (zoom > 2.0) zoom = 2.0;
}
else if (key == 'Z')
{
zoom /= 1.2;
if (zoom < 0.25) zoom = 0.25;
}
else if (key == 'r')
{
doyrot += 5;
}
else if (key == 'R')
{
doyrot -= 5;
}
}