I know this is a really big ask, but I am having hugh problems with this peice of code, I can not get the rotation of this object to work, I want to rotate the first window using left click on the mouse, then second, third, forth window and finally stop on subsequent mouse clicks.
So far to no avail
I would be very apprieciative and grateful for any help anyone could offer me
here is the code
#include <GL/glut.h>
#include <fstream>
#include "math.h"
using namespace std;
#define NUM_OBJECTS 3
GLuint objectlist;
char *datafile[]= {"lamp2.txt", "coffeetable2.txt", "phone2.txt" };
bool spinning = false;
int window = 0;
int angle = 90;
struct Vertex
{
GLfloat vertices[3];
GLfloat avgnormal[3];
};
struct Faces
{
int face[3];
GLfloat normals[3];
};
struct Materials
{
GLfloat ambient[4], diffuse[4], specular[4], emission[4];
GLfloat shininess, transparency;
};
struct Mesh
{
int numVertices, numFaces, matsIndex;
Vertex* objVertices;
Faces* objFaces;
};
class Obj
{
public:
Obj();
int numMaterials, numMesh;
Mesh* objMesh;
Materials *objMats;
bool LoadFile(char* datafile);
void DrawObj();
void CalNormals();
};
Obj* obj[NUM_OBJECTS];
Obj::Obj()
{
numMaterials = 0;
numMesh = 0;
objMesh = NULL;
objMats = NULL;
}
bool Obj::LoadFile(char* datafile)
{
float unused;
ifstream instream(datafile);
instream >> numMesh;
objMesh = new Mesh[numMesh];
for(int ctrMesh = 0; ctrMesh < numMesh; ctrMesh++)
{
instream >> objMesh[ctrMesh].matsIndex;
instream >> objMesh[ctrMesh].numVertices;
objMesh[ctrMesh].objVertices = new Vertex[objMesh[ctrMesh].numVertices];
for(int ctrVert = 0; ctrVert < objMesh[ctrMesh].numVertices; ctrVert++)
{
instream >> unused;
instream >> objMesh[ctrMesh].objVertices[ctrVert].vertices[0];
instream >> objMesh[ctrMesh].objVertices[ctrVert].vertices[1];
instream >> objMesh[ctrMesh].objVertices[ctrVert].vertices[2];
instream >> unused;
instream >> unused;
instream >> unused;
objMesh[ctrMesh].objVertices[ctrVert].avgnormal[0]= 0.0f;
objMesh[ctrMesh].objVertices[ctrVert].avgnormal[1]= 0.0f;
objMesh[ctrMesh].objVertices[ctrVert].avgnormal[2]= 0.0f;
}
instream >>objMesh[ctrMesh].numFaces;
objMesh[ctrMesh].objFaces = new Faces[objMesh[ctrMesh].numFaces];
for(int ctrFaces = 0; ctrFaces < objMesh[ctrMesh].numFaces; ctrFaces++)
{
instream >> unused;
instream >> objMesh[ctrMesh].objFaces[ctrFaces].face[0];
instream >> objMesh[ctrMesh].objFaces[ctrFaces].face[1];
instream >> objMesh[ctrMesh].objFaces[ctrFaces].face[2];
instream >> unused;
instream >> unused;
instream >> unused;
instream >> unused;
}
}
instream >> numMaterials;
objMats = new Materials[numMaterials];
for(int ctrMats=0; ctrMats < numMaterials; ctrMats++)
{
instream >> objMats[ctrMats].ambient[0];
instream >> objMats[ctrMats].ambient[1];
instream >> objMats[ctrMats].ambient[2];
instream >> objMats[ctrMats].ambient[3];
instream >> objMats[ctrMats].diffuse[0];
instream >> objMats[ctrMats].diffuse[1];
instream >> objMats[ctrMats].diffuse[2];
instream >> objMats[ctrMats].diffuse[3];
instream >> objMats[ctrMats].specular[0];
instream >> objMats[ctrMats].specular[1];
instream >> objMats[ctrMats].specular[2];
instream >> objMats[ctrMats].specular[3];
instream >> objMats[ctrMats].emission[0];
instream >> objMats[ctrMats].emission[1];
instream >> objMats[ctrMats].emission[2];
instream >> objMats[ctrMats].emission[3];
instream >> objMats[ctrMats].shininess;
instream >> objMats[ctrMats].transparency;
}
instream.close();
return true;
}
void normal(GLfloat p[])
{
/* normalize a vector */
//function taken of Edward Angel Interactive computer graphics
//double sqrt();
float d = 0.0;
int i;
for(i=0; i<3; i++)
d+=p[i]*p[i];
d=sqrt(d);
if(d>0.0)
for(i=0; i<3; i++)
p[i]/=d;
}
void Obj::CalNormals()
{
GLfloat u[3], v[3];
for(int ctrMesh=0; ctrMesh < numMesh; ctrMesh++)
{
for(int ctrFaces=0; ctrFaces < objMesh[ctrMesh].numFaces; ctrFaces++)
{
for(int ctrNorm=0; ctrNorm<3; ctrNorm++)
u[ctrNorm] = objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[0]].vertices[ctrNorm]
- objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].vertices[ctrNorm];
for(int ctrNorm=0; ctrNorm<3; ctrNorm++)
v[ctrNorm] = objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].vertices[ctrNorm]
- objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[2]].vertices[ctrNorm];
normal(u);
normal(v);
objMesh[ctrMesh].objFaces[ctrFaces].normals[0] = (u[1]*v[2]) - (u[2]*v[1]);
objMesh[ctrMesh].objFaces[ctrFaces].normals[1] = (u[2]*v[0]) - (u[0]*v[2]);
objMesh[ctrMesh].objFaces[ctrFaces].normals[2] = (u[0]*v[1]) - (u[1]*v[0]);
for(int ctrNorm=0; ctrNorm<3; ctrNorm++) {
objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[0]].avgnormal[ctrNorm] += objMesh[ctrMesh].objFaces[ctrFaces].normals[ctrNorm];
objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].avgnormal[ctrNorm] += objMesh[ctrMesh].objFaces[ctrFaces].normals[ctrNorm];
objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[2]].avgnormal[ctrNorm] += objMesh[ctrMesh].objFaces[ctrFaces].normals[ctrNorm];
}
for(int ctrNorm=0; ctrNorm<3; ctrNorm++) {
normal(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[0]].avgnormal);
normal(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].avgnormal);
normal(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[2]].avgnormal);
}
}
}
}
void Obj::DrawObj()
{
GLenum mode;
int win = glutGetWindow();
if(win==2) glShadeModel(GL_FLAT);
if(win==3) glShadeModel(GL_SMOOTH);
//if(win==4)
if(win == 1)
mode = GL_LINE_STRIP;
else mode = GL_TRIANGLES;
for(int ctrMesh=0; ctrMesh < numMesh; ctrMesh++)
{
glPushMatrix();
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, objMats[objMesh[ctrMesh].matsIndex].ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, objMats[objMesh[ctrMesh].matsIndex].diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, objMats[objMesh[ctrMesh].matsIndex].specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, objMats[objMesh[ctrMesh].matsIndex].emission);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, objMats[objMesh[ctrMesh].matsIndex].shininess);
for(int ctrFaces=0; ctrFaces < objMesh[ctrMesh].numFaces; ctrFaces++)
{
glBegin(mode);
if(win ==4) glNormal3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[0]].avgnormal);
else if (win == 3)glNormal3fv(objMesh[ctrMesh].objFaces[ctrFaces].normals);
glVertex3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[0]].vertices);
if(win ==4)glNormal3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].avgnormal);
glVertex3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[1]].vertices);
if(win ==4)glNormal3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[2]].avgnormal);
glVertex3fv(objMesh[ctrMesh].objVertices[objMesh[ctrMesh].objFaces[ctrFaces].face[2]].vertices);
glEnd();
}
glPopMatrix();
}
}
void init()
{
GLfloat lightPos[] = { 0.0, 0.0, 0.0, 0.0 };
GLfloat modelAmbient[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, specular);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmbient);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
glFrontFace(GL_CW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_DEPTH_TEST);
objectlist = glGenLists (NUM_OBJECTS);
for(int i = 0; i<NUM_OBJECTS; i++)
{
obj[i] = new Obj;
glNewList(objectlist + i, GL_COMPILE);
if(obj[i]->LoadFile(datafile[i]))
{
obj[i]->CalNormals();
obj[i]->DrawObj();
}
glEndList();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-70, 70, -50, 50, -50, 50);
glMatrixMode(GL_MODELVIEW);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(int i=0; i < NUM_OBJECTS; i++)
{
glPushMatrix();
glLoadIdentity();
if(i == 0)
glTranslatef(20.0,0.0,0.0);
if(i!=2)
glRotatef(90, 0.0, 1.0, 0.0);
glRotatef(-90, 1.0, 0.0, 0.0);
glCallList(objectlist + i);
glPopMatrix();
}
glutSwapBuffers();
}
void idle()
{
DON'T KNOW WHAT TO PUT IN HERE
}
void mouse_click(int button, int state, int x, int y)
{
if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON && window < 4)
{
glutSetWindow(window+1);
} else if (window == 4) window = 0;
if (window != 0)
{
glutIdleFunc(idle);
}
}
void reshape (int w, int h)
{
if ( w == h) glViewport(0,0,w,h);
else if ( w > h) glViewport(0,0,h,h);
else glViewport(0,0,w,w);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-70, 70, -50, 50, -50, 50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutInitWindowPosition(0, 0);
glutCreateWindow("Window 1: Wired Frame");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse_click);
glutInitWindowSize(400, 400);
glutInitWindowPosition(450, 0);
glutCreateWindow("Window 2: Flat Shading");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse_click);
glutInitWindowSize(400, 400);
glutInitWindowPosition(0, 450);
glutCreateWindow("Window 3: Gouraud Shading");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse_click);
glutInitWindowSize(400, 400);
glutInitWindowPosition(450, 450);
glutCreateWindow("Window 4: Gouraud Shading with Averaging Normals ");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse_click);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}