#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
#include <ctime>
#ifdef OSX
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include "smVector.H"
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
#endif
using namespace std;
bool SMOOTH_SHADING = false;
class Triangle;
class Object;
class Camera;
class Transform;
class Light;
class Triangle {
public:
int vertices[3];
int &operator[] (int i) {return vertices[i];};
};
class Transform {
public:
static const int ROTATE;
static const int TRANSLATE;
static const int SCALE;
Transform(){};
~Transform(){};
Transform(const Transform &that);
Transform &operator=(const Transform &that);
int type; // ROTATE, TRANSLATE, or SCALE
SmVector3 axis, translate, scale;
double angle;
void apply(); // apply the transform to the OpenGL stack
};
const int Transform::ROTATE = 1;
const int Transform::TRANSLATE = 2;
const int Transform::SCALE = 3;
class Object {
public:
Object() {};
Object(const Object &that);
~Object() {vertices.clear(); triangles.clear();};
Object &operator=(const Object &that);
void readObject(char *fname);
void drawObject(); // draw the object
vector<SmVector3> vertices;
vector<Triangle> triangles;
vector<Transform> transforms;
SmVector3 color;
float ka, kd, ks;
GLuint dlid; // display list id
vector<SmVector3> vertexNormals; // a normal for each vertex, for smooth shading
vector<SmVector3> faceNormals; // a normal for each face, for flat shading
void computeNormals(); // compute the normals
};
class Light {
public:
Light() {};
Light(const Light &that);
Light &operator=(const Light &that);
GLfloat ambient[4]; // ambient color, RGBA
GLfloat diffuse[4]; // diffuse color, RGBA
GLfloat specular[4]; // specular color, RGBA
GLfloat pos[4]; // position XYZW
GLenum id; // light identifier
void apply(); // add the light to the scene
};
class Camera {
public:
Camera &operator=(const Camera &that);
SmVector3 eye; // eye point, cop
SmVector3 center; // point the eye is looking at
SmVector3 up; // up direction
float fov, nearplane, farplane; // field of view, near and far clipping planes
};
class Viewport {
public:
int w, h; // width and height
};
// copy constructor, *this = that
Object::Object(const Object &that) {
vertices = that.vertices;
triangles = that.triangles;
transforms = that.transforms;
color = that.color;
ka = that.ka;
kd = that.kd;
ks = that.ks;
computeNormals();
}
// overloaded = operator
Object &Object::operator=(const Object &that) {
vertices = that.vertices;
triangles = that.triangles;
transforms = that.transforms;
color = that.color;
ka = that.ka;
kd = that.kd;
ks = that.ks;
computeNormals();
return *this;
}
// load an object from obj file fname
void Object::readObject(char *fname) {
ifstream in(fname, ios::in);
char c;
SmVector3 pt;
Triangle t;
if (!in.good()) {
cerr<<"Unable to open file \""<<fname<<"\""<<endl;
abort();
}
while (in.good()) {
in >> c;
if (!in.good()) break;
if (c == 'v') {
in >> pt[0] >> pt[1] >> pt[2];
vertices.push_back(pt);
} else if (c == 'f') {
in >> t[0] >> t[1] >> t[2];
t[0]-=1; t[1]-=1; t[2]-=1;
triangles.push_back(t);
}
}
}
void Object::drawObject() {
cout<<"I want to draw object "<<dlid<<" but there's no code here yet"<<endl;
// here you draw the object
// you will need to set material properties
// and normals as well as actually draw the triangles
// this is also where you call apply transformations
// remember to push and pop your matrices
}
void Object::computeNormals() {
// here you compute normals
// you should compute both face normals (cross product) for flat shading
// and vertex normals (area-weighted averages of face normals) for
// smooth shading
// remember to normalize your normals
}
// copy constructor for Transform class
Transform::Transform(const Transform &that) {
type = that.type;
axis = that.axis;
translate = that.translate;
scale = that.scale;
angle = that.angle;
}
// overloaded = operator
Transform &Transform::operator=(const Transform &that) {
type = that.type;
axis = that.axis;
translate = that.translate;
scale = that.scale;
angle = that.angle;
return *this;
}
void Transform::apply() {
cout<<"applying transform"<<endl;
// here you have to apply the transformation
// to the transform stack, probably with a switch
// statement and calls to glTranslated, glRotated, glScaled
}
// Light copy constructor
Light::Light(const Light &that) {
ambient[0] = that.ambient[0];
ambient[1] = that.ambient[1];
ambient[2] = that.ambient[2];
ambient[3] = that.ambient[3];
diffuse[0] = that.diffuse[0];
diffuse[1] = that.diffuse[1];
diffuse[2] = that.diffuse[2];
diffuse[3] = that.diffuse[3];
specular[0] = that.specular[0];
specular[1] = that.specular[1];
specular[2] = that.specular[2];
specular[3] = that.specular[3];
pos[0] = that.pos[0];
pos[1] = that.pos[1];
pos[2] = that.pos[2];
pos[3] = that.pos[3];
id = that.id;
}
// Light = operator
Light &Light::operator=(const Light &that) {
ambient[0] = that.ambient[0];
ambient[1] = that.ambient[1];
ambient[2] = that.ambient[2];
ambient[3] = that.ambient[3];
diffuse[0] = that.diffuse[0];
diffuse[1] = that.diffuse[1];
diffuse[2] = that.diffuse[2];
diffuse[3] = that.diffuse[3];
specular[0] = that.specular[0];
specular[1] = that.specular[1];
specular[2] = that.specular[2];
specular[3] = that.specular[3];
pos[0] = that.pos[0];
pos[1] = that.pos[1];
pos[2] = that.pos[2];
pos[3] = that.pos[3];
id = that.id;
return *this;
}
// add the light to the scene
void Light::apply() {
cout<<"Applying light "<<id<<endl;
// this function tells openGL about the light
// it is called from myDisplay().
// Use glLightfv to set the different properties
// of the light and glEnable() to turn the light on.
}
// Camera = operator
Camera &Camera::operator=(const Camera &that) {
eye = that.eye;
center = that.center;
up = that.up;
fov = that.fov;
nearplane = that.nearplane;
farplane = that.farplane;
return *this;
}
// Global Variables
vector<Object> objects;
vector<Light> lights;
Camera camera, origCamera;
Viewport viewport;
// this function reads the input file
void parseInputFile(char *fname) {
ifstream in(fname, ios::in);
Object obj;
Transform t;
char str[80];
int numObjects,numLights,i;
if (!in.good()) {
cerr<<"Unable to open file \""<<fname<<"\""<<endl;
abort();
}
// read camera info
in >> camera.fov >> camera.nearplane >> camera.farplane;
in >> camera.eye[0] >> camera.eye[1] >> camera.eye[2];
in >> camera.center[0] >> camera.center[1] >> camera.center[2];
in >> camera.up[0] >> camera.up[1] >> camera.up[2];
origCamera = camera;
in >> numObjects;
objects.resize(numObjects);
for (i=0; i<numObjects; i++) {
objects[i].dlid = (GLuint) i+1;
in >> objects[i].color[0] >> objects[i].color[1] >> objects[i].color[2];
in >> objects[i].ka >> objects[i].kd >> objects[i].ks;
int done = 0;
// this loop reads an arbitrary number of transformations
// then reads the obj file name
while (!done) {
in >> str;
if (strstr(str, "translate")) {
t.type = Transform::TRANSLATE;
in >> t.translate[0] >> t.translate[1] >> t.translate[2];
objects[i].transforms.push_back(t);
} else if (strstr(str, "rotate")) {
t.type = Transform::ROTATE;
in >> t.angle >> t.axis[0] >> t.axis[1] >> t.axis[2];
objects[i].transforms.push_back(t);
} else if (strstr(str, "scale")) {
t.type = Transform::SCALE;
in >> t.scale[0] >> t.scale[1] >> t.scale[2];
objects[i].transforms.push_back(t);
} else {
objects[i].readObject(str);
done = 1;
}
}
// we've got the geometry, lets compute the normals
objects[i].computeNormals();
}
// read lights
in >> numLights;
lights.resize(numLights);
for (i=0; i<numLights; i++) {
in >> lights[i].ambient[0] >> lights[i].ambient[1] >> lights[i].am
- 1
- 2
- 3
前往页