#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <GL/glut.h>
#include <math.h>
#include <list>
using namespace std;
bool toUpdate = true, goToAngle = false;
GLfloat xrot = 0, yrot = 0;
GLfloat butterflyX = -100,
butterflyY = -50;
GLfloat butterflyXTemp = -100,
butterflyYTemp = -50;
GLfloat yRotGoal = 0.0, yRotDirection = 1;
GLfloat angleIt = 0;
GLfloat theta = 0.0;
GLfloat dtheta = 2 * 3.14159/360.0;
GLfloat butterflyAngle = 0.0;
float xToIncrease = 4, yToIncrease = 4;
int oldTimeSinceStart = 0;
float variation[22];
bool getNewVar;
int totalTime, totalTimeGoal;
float xIncrease = 1;
float increaseVariable = 1;
//camera moving
GLfloat eyeX = 0.0,
eyeY = -200.0,
eyeZ = 400.0;
GLfloat eyeStartX = 0.0,
eyeStartY = -200.0,
eyeStartZ = 400.0;
GLdouble upX = 0.0,
upY = 0.0,
upZ = 1.0;
GLfloat cameraAngle1 = 180,
cameraAngle2 = 45;
GLfloat cameraDistance = 200.0;
float tempX, tempY;
float initialCoordX, initialCoordY;
float currentX, currentY;
bool isLeftMouse, isRightMouse;
bool isDrawing;
float widthToMove;
float heightToMove;
int coords2[][2] = {{131, 55},
{160, 38},
{194, 26},
{228, 20},
{240, 22},
{244, 25},
{245, 30},
{244, 34},
{239, 41},
{228, 48},
{216, 55},
{202, 71},
{191, 79},
{193, 85},
{193, 94},
{188,103},
{186,106},
{176,116},
{163,123},
{149,127},
{138,124},
{131,119}};
int coords3[][2] = {{131, 59},
{173, 38},
{190, 35},
{193, 36},
{196, 39}, //*
{202, 43},
{203, 45},
{204, 48},
{200, 54},
{193, 62},
{190, 70},
{189, 72},
{184, 77},
{181, 84},
{180, 94},
{178, 98}, //*
{177,101},
{166,109},
{160,111}, //*
{154,113},
{142,114},
{131,114}};
int coords4[][2] = {{146, 80},
{152, 80},
{156, 85},
{160,117},
{156,185},
{153,188},
{151,188},
{148,180},
{143,117},
{145, 85}};
void calculateCameraLocation();
void init(void)
{
glEnable (GL_DEPTH_TEST); //enable the depth testing
glViewport (0, 0, (GLsizei) 100, (GLsizei) 100);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(-250.0, 250.0, -250.0, 250.0);
gluPerspective (60, 1.0, 0.0, 1.0); //set the perspective (angle of sight, width, height, , depth)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor (0.0, 0.0, 0.0, 1.0);
glShadeModel (GL_SMOOTH);
for(int i = 0; i < 22; i++)
variation[i] = 0;
getNewVar = false;
totalTime = 0;
srand(time(NULL));
calculateCameraLocation();
}
void idle()
{
//Call the display function when the program is idle
glutPostRedisplay();
}
void calculateCameraLocation()
{
eyeX = cameraDistance * cos(cameraAngle2/114.59155*2) * sin(cameraAngle1/114.59155);
eyeY = cameraDistance * cos(cameraAngle2/114.59155*2) * cos(cameraAngle1/114.59155);
eyeZ = cameraDistance * sin(cameraAngle2/114.59155*2);
}
void drawBody(int xT, int yT, bool invert)
{
glColor3f(0,0,0);
float x, y;
glBegin(GL_POLYGON);
for(int i = 0; i < 10; i++)
{
x = xT + coords4[i][0] - 26;
y = -(yT + coords4[i][1]) + 33;
glVertex2f(x, y);
}
glEnd();
}
void drawRightWing(int xT, int yT, bool invert)
{
glColor3f(0.92, 0.53, 0.14);
glBegin(GL_POLYGON);
float x, y;
float newVariation = (rand() % 20)/100.0 - (rand() % 20)/100.0;
for(int i = 0; i < 22; i++)
{
if(i == 0 && getNewVar)
{
variation[0] = newVariation;
for(int i = 21; i > 0; i--)
{
variation[i] = variation[i-1];
}
getNewVar = false;
}
glColor3f(0.92 + variation[i], 0.53 + variation[i], 0.14 + variation[i]);
x = (invert) ? -(xT + coords2[i][0]) + 250 : xT + coords2[i][0];
y = -(yT + coords2[i][1]);
glVertex2f(x, y);
}
glEnd();
}
void drawWingBorder(int xT, int yT, bool invert)
{
glColor3f(0,0,0);
float x, y;
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i < 22; i++)
{
x = (invert) ? -(xT + coords2[i][0]) + 250 : xT + coords2[i][0];
y = -(yT + coords2[i][1]);
glVertex2f(x, y);
x = (invert) ? -(xT + coords3[i][0]) + 250 : xT + coords3[i][0];
y = -(yT + coords3[i][1]);
glVertex2f(x, y);
}
glEnd();
}
void update(int deltaTime)
{
float perSecond = deltaTime / 1000.0;
totalTime += deltaTime;
xrot += xIncrease * increaseVariable * 200.0 * perSecond;
if(xrot * xIncrease > 40)
increaseVariable = .3;
else
increaseVariable = 1;
if(xrot * xIncrease > 50)
xIncrease *= -1;
xToIncrease = 1000 * perSecond * sin((yrot-180)/114.159*2);
yToIncrease = 1000 * perSecond * cos((yrot-180)/114.159*2);
butterflyX += xToIncrease;
butterflyY += yToIncrease;
if(goToAngle)
{
yrot += 200.0 * perSecond * yRotDirection;
for(yrot; yrot < 0; yrot = 360);
for(yrot; yrot > 360; yrot = 0);
//cout << "goal: " << yRotGoal << " current:" << yrot << " to Angle: " << abs(yrot - yRotGoal) << " smallest: " << 200.0 * perSecond << " yDir: " << yRotDirection << endl;
if(abs(yrot - yRotGoal) < 200.0 * perSecond)
{
yrot = yRotGoal;
goToAngle = false;
}
}
else
{
yRotGoal = rand()%360;
int sign1 = (yRotGoal - yrot < 0) ? -1 : 1;
int sign2 = 1;
if(abs(yRotGoal - yrot) > 180)
sign2 = -1;
yRotDirection = sign1 * sign2;
cout << "yRotDir: " << yRotDirection << endl;
goToAngle = true;
}
if(totalTime > 100)
{
totalTime = 0;
getNewVar = true;
}
}
void print_bitmap_string(void* font, string str)
{
for(int i = 0; i < str.size(); i++)
{
glutBitmapCharacter(font, str[i]);
}
}
string convertInt(int number)
{
stringstream ss;
ss << number;
return ss.str();
}
void stuffToDraw()
{
glColor3f(1.0, 0.0, 0.0);
//--------------------------BODY----------------------------
glTranslated(butterflyX + 120, -butterflyY - 80, 0);
glColor3f(0.0, 0.0, 1.0);
glPushMatrix();
glutWireCube(8);
glPopMatrix();
glRotatef(yrot, 0.0, 0.0, 1.0);
glTranslated(-butterflyX - 120, butterflyY + 80, 0);
drawBody(butterflyX, butterflyY, 0);
//-------------------------RIGHT WING----------------------
glTranslated(butterflyX + 130, -butterflyY, 0);
glRotatef(-xrot, 0.0, 1.0, 0.0);
glTranslated(-butterflyX - 130, butterflyY, 0);
drawWingBorder(butterflyX, butterflyY, 0);
drawRightWing(butterflyX, butterflyY, 0);
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ, 0.0, 0.0, 0.0, upX, upY, upZ);
//------------------------LEFT WING--------------------------
glTranslated(butterflyX + 120, -butterflyY - 80, 0);
glRotatef(yrot, 0.0, 0.0, 1.0);
glTranslated(-butterflyX - 120, butterflyY + 80, 0);
glTranslated(butterflyX + 120, -butterflyY, 0);
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
glutWireCube(8);
glPopMatrix();
glRotatef(xrot, 0.0, 1.0, 0.0);
glTranslated(-butterflyX - 120, butterflyY, 0);
drawWingBorder(-butterflyX, butterflyY, 1);
drawRightWing(-butterflyX, butterflyY, 1);
//--------------------GROUND----------------------------
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ, 0.0, 0.0, 0.0, upX, upY, upZ);
glColor3f(0.0, 1.0, 0.0);
for(int xT = -100; xT < 100; xT++)
for(int yT = -100; yT < 100; yT++)
{
glBegin(GL_LINE_LOOP);
glVertex3f( xT * 100, yT * 100, -200);
glVertex3f( xT * 100, yT * 100 + 100, -200);
glVertex3f(xT * 100 + 100, yT * 100 + 100, -200);
glVertex3f(xT * 100 + 100, yT * 100, -200);
glEnd();
}
glColor3f(1, 0, 0);
for(int i = 0; i < 20; i++)
{
glTranslated(xToIncrease * i * 3, yToIncrease * i * 3, 5);
glPushMatrix();
glutWireCube(5);
glPopMatrix();
glTranslated(-xToIncrease * i * 3, -yToIncrease * i * 3, -5);
}
}
void display (void)
{
//Calculate delta time (time elapsed in milliseconds), and call update
int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
int deltaTime = timeSinceStart - oldTimeSinceStart;
oldTimeSinceStart = timeSinceStart;
if(toUpdate)
update(deltaTime);
//Clear the background of our window to white, draw stuff, swap buffer
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity();
gluLookAt (eyeX, eyeY, eyeZ, 0.0, 0.0, 0.0, upX, upY, upZ); //camera position, x,y,z, looking at x,y,z, Up Positions of the camera
stuffToDraw();
glutSwapBuffers();
}
void keyboard (unsigned char key, int x, int y)
{
int keyInt = key;
if (key==',')
{
butterflyX += 5;
//eyeX += -50;
}
if (keyInt == 32)
{
toUpdate = !toUpdate;
cout << "toUpdate: " << toUpdate << endl;
}
if (key=='o')
{
butterflyY += 5;
//eyeX += 50;
}
if (key=='.')
{
eyeY += -50;
}
if (key=='e')
{
eyeY += 50;
}
if (key=='p')
{
eyeZ += -50;
}
if (key=='u')
{
eyeZ += 50;
}
if (key==27)
{
exit(0);
}
}
void mousePress(int button, int state, int x, int y)
{
currentX = x - 250;
currentY = 250 - y;
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
{
isLeftMouse = true;
initialCoordX = tempX = currentX;
initialCoordY = tempY = currentY;
}
//left click up
else
{
isLeftMouse = false;
display();
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
{
isRightMouse = true;
initialCoordX = tempX = currentX;
initialCoordY = tempY = currentY;
}
else
{
isRightMouse = false;
display();
}
break;
default:
break;
}
}
void mouseDraw(int x, int y)
{
currentY = 250 - y;
currentX = x - 250;
if(isLeftMouse)
{
float distance1 = sqrt(eyeX * eyeX + eyeY * eyeY);
float distance2 = sqrt(eyeZ * eyeZ + eyeY * eyeY);
cameraAngle1 += (tempX - currentX)/2.0;
cameraAngle2 += (tempY - currentY)/2.0;
for(cameraAngle1; cameraAngle1 > 360; cameraAngle1 = -360);
for(cameraAngle1; cameraAngle1 < -360; cameraAngle1 = 360);
for(cameraAngle2; cameraAngle2 > 360; cameraAngle2 = -360);
for(cameraAngle2; cameraAngle2 < -360; cameraAngle2 = 360);
display();
}
else if(isRightMouse)
{
cameraDistance += cameraDistance/100.0 * (tempY - currentY);
}
calculateCameraLocation();
tempX = currentX;
tempY = currentY;
}
void mouseMove(int x, int y)
{
currentY = 250 - y;
currentX = x - 250;
display();
}
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("OpenGL Text Example");
init();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMouseFunc(mousePress);
glutMotionFunc(mouseDraw);
glutPassiveMotionFunc(mouseMove);
glutMainLoop();
}