Code:
#include <GL/glut.h>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <time.h>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
struct coord
{
float x_c;
float y_c;
float z_c;
};
int x_1,y_1,x_2,y_2;
float xspin,yspin;
int button_down;
bool key;
float xrot, yrot, zrot;
float xtrans, ytrans, ztrans;
int colorChoice = 0;
int shapeChoice = 0;
float sizeChoice = 1;
bool moveOrder = false;
bool oldMoveOrder;
vector <coord> cord;
vector <vector <int> > verts;
float scale_size;
float orig_scale_size;
bool wire_or_solid;
bool cull_or_not;
void find_scale()
{}
void draw_image()
{
//cout << "------------------------FUNCT CALLED-------------"<<endl;
int a,b,c;
float tmp_x,tmp_y,tmp_z;
int from,to;
for(a=0;a<verts.size();a++)
{
c = 0;
for(b=0;b<verts.at(a).size()-1;b++)
{
from = verts.at(a).at(b);
tmp_x = cord[from].x_c;
tmp_y = cord[from].y_c;
tmp_z = cord[from].z_c;
glVertex3f(tmp_x,tmp_y,tmp_z);
//cout << "From: " << tmp_x << " " << tmp_y << " " << tmp_z;
to = verts.at(a).at(b+1);
tmp_x = cord[to].x_c;
tmp_y = cord[to].y_c;
tmp_z = cord[to].z_c;
glVertex3f(tmp_x,tmp_y,tmp_z);
//cout << " TO " << tmp_x << " " << tmp_y << " " << tmp_z << endl;
}
from = verts.at(a).at(b);
tmp_x = cord[from].x_c;
tmp_y = cord[from].y_c;
tmp_z = cord[from].z_c;
glVertex3f(tmp_x,tmp_y,tmp_z);
//cout << "From: " << tmp_x << " " << tmp_y << " " << tmp_z;
b = 0;
to = verts.at(a).at(b);
to = verts.at(a).at(b+1);
tmp_x = cord[to].x_c;
tmp_y = cord[to].y_c;
tmp_z = cord[to].z_c;
glVertex3f(tmp_x,tmp_y,tmp_z);
//cout << " TO " << tmp_x << " " << tmp_y << " " << tmp_z << endl;
find_scale();
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
switch(wire_or_solid)
{
case true:glBegin(GL_LINES); break;
case false:glBegin(GL_POLYGON); break;
}
switch(cull_or_not)
{
case true:glEnable(GL_CULL_FACE); break;
case false:glDisable(GL_CULL_FACE) ;break;
}
if(moveOrder )
{
glTranslatef(xtrans, ytrans, ztrans);
}
glRotatef(xrot,1,0,0);
glRotatef(yrot,0,1,0);
glRotatef(zrot,0,0,1);
if(!moveOrder)
{
glTranslatef(xtrans, ytrans, ztrans);
}
glScalef(scale_size, scale_size, scale_size);
switch(colorChoice)
{
case 0: glColor3f(1,0,0); break;
case 1: glColor3f(0,1,0); break;
case 2: glColor3f(0,0,1); break;
}
//DrawShapeHere
draw_image();
glPopMatrix();
glEnd();
glutSwapBuffers();
}
void initMoves()
{
xrot=0;
yrot=0;
zrot=0;
xspin = 0;
yspin = 0;
xtrans = 0;
ytrans = 0;
ztrans = 0;
}
void show_keys()
{
cout << "-----IN ROTATON MODE----" << endl;
cout << "q: exit" << endl;
cout << "x: xrot += 5" << endl;
cout << "y: yrot += 5" << endl;
cout << "z: zrot += 5" << endl;
cout << "X: xrot -= 5" << endl;
cout << "Y: yrot -= 5" << endl;
cout << "Z: zrot -= 5" << endl;
cout << "r: reset" << endl << endl;
cout << "-----IN ROTATON MODE----" << endl;
cout << "q: exit" << endl;
cout << "x: xtrans += .05" << endl;
cout << "y: ytrans += .05" << endl;
cout << "z: ztrans += .05" << endl;
cout << "X: xtrans -= .05" << endl;
cout << "Y: ytrans -= .05" << endl;
cout << "Z: ztrans -= .05" << endl;
cout << "r: reset" << endl << endl;
cout << "-----MOUSE BUTTONS----" << endl;
cout << "left button : menu" << endl;
cout << "middle button: rotate" << endl;
cout << "right button : translate" << endl;
}
void myinit()
{
initMoves();
x_1 = 0;
x_2 = 0;
y_1 = 0;
y_2 = 0;
xspin = 0;
yspin = 0;
key = false;
float scale_size = 1.0;
bool wire_or_solid = true;
bool cull_or_not = true;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
}
void fileReady()
{
vector <int> temp_verts;
string line;
int num_lines;
int i;
int x1c,y1c,z1c;
coord temp;
int vert_num;
int temp_vert;
int counter;
ifstream myfile ("cube.off");
if (myfile.is_open())
{
myfile >> num_lines;
//cout << "HERE: " << num_lines << endl;
for(i=0;i<num_lines;i++)
{
getline (myfile,line);
//cout << line << endl;
myfile >> x1c;
myfile >> y1c;
myfile >> z1c;
temp.x_c=x1c;
temp.y_c=y1c;
temp.z_c=z1c;
cord.push_back(temp);
//cout << "LINE IS: "<<x1c<<" "<<y1c<<" "<<z1c<<endl;
}
while(!myfile.eof())
{
myfile >> vert_num;
for (i=0;i<vert_num;i++)
{
myfile >> temp_vert;
temp_verts.push_back(temp_vert);
}
verts.push_back(temp_verts);
temp_verts.clear();
}
//MUST DO BECAUSE OF EOF READ
verts.pop_back();
myfile.close();
}
else
{
cout << "Unable to open file";
}
}
void mainMenu(int value)
{
switch(value)
{
case 0: exit(0);break;
case 1: initMoves();break;
}
}
void colorMenu(int value)
{
colorChoice = value;
glutPostRedisplay();
}
void moveMenu(int value)
{
switch (value)
{
case 0: moveOrder = false; break;
case 1: moveOrder = true; break;
}
}
void keysMenu(int value)
{
switch (value)
{
case 0:key = false ; break;
case 1:key = true ; break;
}
}
void scaleMenu(int value)
{
switch (value)
{
case 0: scale_size += .1; break;
case 1: scale_size -+ .1; break;
case 2: scale_size = orig_scale_size; break;
}
}
void displayMenu(int value)
{
switch (value)
{
case 0: wire_or_solid = true;break;
case 1: wire_or_solid = false;break;
}
}
void cullMenu(int value)
{
switch (value)
{
case 0: cull_or_not = true;break;
case 1: cull_or_not = false;break;
}
}
void makeMenus()
{
int topLevel, color, move, keys, scale,display_mode,cull;
//#Increase the model scale by 10%.
//# Decrease the model scale by 10%.
//# Display the model in wireframe mode.
//# Display the model in solid mode.
//# Turn culling of backfaces on.
//# Turn culling of backfaces off.
scale = glutCreateMenu(scaleMenu);
glutAddMenuEntry("+10%", 0);
glutAddMenuEntry("-10%", 1);
glutAddMenuEntry("Original", 2);
display_mode = glutCreateMenu(displayMenu);
glutAddMenuEntry("Wireframe", 0);
glutAddMenuEntry("Solid", 1);
cull = glutCreateMenu(cullMenu);
glutAddMenuEntry("Culling ON", 0);
glutAddMenuEntry("Culling OFF", 1);
color = glutCreateMenu(colorMenu);
glutAddMenuEntry("Red", 0);
glutAddMenuEntry("Green", 1);
glutAddMenuEntry("Blue", 2);
move = glutCreateMenu(moveMenu);
glutAddMenuEntry("Rotate Then Translate", 0);
glutAddMenuEntry("Translate Then Rotate", 1);
keys = glutCreateMenu(keysMenu);
glutAddMenuEntry("Rotate", 0);
glutAddMenuEntry("Translate", 1);
topLevel=glutCreateMenu(mainMenu);
glutAddSubMenu("Change Color", color);
glutAddSubMenu("Change Movement", move);
glutAddSubMenu("Change Keys",keys);
glutAddSubMenu("Change Scale",scale);
glutAddSubMenu("Change Display Mode",display_mode);
glutAddSubMenu("Change Culling",cull);
glutAddMenuEntry("Reset", 1);
glutAddMenuEntry("Exit", 0);
glutAttachMenu(GLUT_LEFT_BUTTON);
}
void keypress(unsigned char c, int x, int y)
{
if (!key)
{
switch (c)
{
case 'q': exit(0);
case 'x': xrot += 5; break;
case 'y': yrot += 5; break;
case 'z': zrot += 5; break;
case 'X': xrot -= 5; break;
case 'Y': yrot -= 5; break;
case 'Z': zrot -= 5; break;
case 'r': initMoves(); break;
}
}
else
{
switch (c)
{
case 'q': exit(0);
case 'x': xtrans += .05; break;
case 'y': ytrans += .05; break;
case 'z': ztrans += .05; break;
case 'X': xtrans -= .05; break;
case 'Y': ytrans -= .05; break;
case 'Z': ztrans -= .05; break;
case 'r': initMoves(); break;
}
}
glutPostRedisplay();
}
void cord_begin(int x, int y)
{
x_1 = x;
y_1 = y;
//cout << "ADDED: " << x << " " << y << endl;
}
void spin(int x, int y)
{
float tempx, tempy;
x_2 = x;
y_2 = y;
tempx = x_2 - x_1;
tempx = tempx / 200;
yspin = tempx;
tempy = y_2 - y_1;
tempy = tempy / 200;
xspin = tempy;
if(xrot > 90 && xrot < 270)
{
//cout << "IF 1" << endl;
yspin = (-1) * tempx;
}
else if(xrot < -90 && xrot > -270)
{
//cout << "IF 2" << endl;
yspin = (-1) * tempx;
}
if(yrot > 90 && yrot < 270)
{
//cout << "IF 3" << endl;
xspin = (-1) * tempy;
}
else if(yrot < -90 && yrot > -270)
{
//cout << "IF 4" << endl;
xspin = (-1) * tempy;
}
//cout << "SPIN: " << xspin << " " << yspin << endl;
}
void move(int x, int y)
{
float mov_x, mov_y;
oldMoveOrder = moveOrder;
moveOrder = true;
//cout << xrot << " " << yrot << " " << zrot << endl << endl;
mov_x = x-250;
mov_x = mov_x/125;
mov_y = 250-y;
mov_y = mov_y/125;
ytrans = mov_y;
xtrans = mov_x;
if(xrot > 90 && xrot < 270)
{
ytrans = (-1) * mov_y;
}
else if(xrot < -90 && xrot > -270)
{
ytrans = (-1) * mov_y;
}
if(yrot > 90 && yrot < 270)
{
xtrans = (-1) * mov_x;
}
else if(yrot < -90 && yrot > -270)
{
xtrans = (-1) * mov_x;
}
//cout << xtrans << " " << ytrans << " " << ztrans << endl;
glutPostRedisplay();
moveOrder = oldMoveOrder;
}
void cord_end(int x, int y, int button)
{
switch (button)
{
case GLUT_MIDDLE_BUTTON: spin(x,y); break;
}
}
void doMouse(int button, int state,int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON: button_down = button; break;
case GLUT_MIDDLE_BUTTON:button_down = button; glutSetCursor(GLUT_CURSOR_CYCLE); break;
case GLUT_RIGHT_BUTTON:button_down = button;glutSetCursor(GLUT_CURSOR_CROSSHAIR); break;
}
switch(state)
{
case GLUT_DOWN : cord_begin(x,y); break;
case GLUT_UP : cord_end(x,y,button); glutSetCursor(GLUT_CURSOR_LEFT_ARROW); break;
}
//cout << "GLOBALS ARE: " << x_1 << " " << y_1 << " "<< x_2 << " " << y_2 << endl;
}
void mouseMotion(int x, int y)
{
if(button_down == GLUT_RIGHT_BUTTON)
{
move(x,y);
}
}
void bound()
{
if(xrot >= 360 || xrot <= -360)
{
xrot = 0;
}
if(yrot >= 360 || yrot <= -360)
{
yrot = 0;
}
}
void doIdle(void)
{
xrot += xspin;
yrot += yspin;
//cout << "ROT: " << xrot << " " << yrot << endl;
bound();
glutPostRedisplay();
}
int main (int argc, char ** argv)
{
glutInit(&argc, argv);
fileReady();
show_keys();
myinit();
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("Stan's Shape Program");
glutDisplayFunc(display);
glutIdleFunc(doIdle);
glutKeyboardFunc(keypress);
glutMouseFunc(doMouse);
glutMotionFunc(mouseMotion);
makeMenus();
myinit();
glutMainLoop();
}