#include <cstdlib>
#include <iostream>
#include <string>
#include <GL/glut.h>
using namespace std;
//debug
bool debug = false;
//experimental
bool writing = false;
bool passed = false;
int i = 0;
unsigned char thestring[256];
bool echotext = false;
//display options
float incang = 2.0f;
float angle = 30.0f;
float cameraAngle = 0.0f;
bool clear_all = true;
bool fog = true;
//color and fog density
float red = 1.0f;
float green = 1.0f;
float blue = 1.0f;
float density = 0.05f;
float fog_color = 0.5f;
//bool values for if we are reversing a animation
bool red_rev = false;
bool green_rev = false;
bool blue_rev = false;
bool density_rev = true;
//clears chat
void reset()
{
for (int c = 0; c < i; c++) {
thestring[c] = ' ';
}
i = 0;
}
//reset menus to be redone
void clearmenus()
{
for (int a = 1; a < 5; a++) {
glutSetMenu(a);
int c = glutGet(GLUT_MENU_NUM_ITEMS);
while (c > 0) {
glutRemoveMenuItem(c);
c--;
}
}
}
//regenerate menus
void makemenu()
{
clearmenus();
if (glIsEnabled(GL_LIGHTING)) {
glutSetMenu(4);
glutAddMenuEntry("Lighting", 'l');
} else {
glutSetMenu(3);
glutAddMenuEntry("Lighting", 'e');
}
if (clear_all) {
glutSetMenu(4);
glutAddMenuEntry("Clear color", 'a');
} else {
glutSetMenu(3);
glutAddMenuEntry("Clear color", 'a');
}
if (fog) {
glutSetMenu(4);
glutAddMenuEntry("Fog", 'f');
} else {
glutSetMenu(3);
glutAddMenuEntry("Fog", 'f');
}
if (debug) {
glutSetMenu(4);
glutAddMenuEntry("Debug", 'v');
} else {
glutSetMenu(3);
glutAddMenuEntry("Debug", 'v');
}
if (writing) {
glutSetMenu(2);
glutAddMenuEntry("Text writing", 'w');
} else {
glutSetMenu(1);
glutAddMenuEntry("Text writing", 't');
}
for (int a = 1; a < 5; a++) {
glutSetMenu(a);
glutAddMenuEntry("Cancel", 0);
}
}
// process menu options
void menu(int op)
{
switch (op) {
case 'a': //color clearing
clear_all = !clear_all;
break;
case 'd': //degrement the speed
incang -= 0.1f;
break;
case 'e': //enable lighting
glEnable(GL_LIGHTING);
break;
case 'f': //yes or no fog
fog = !fog;
break;
case 'l': //disable lighting
glDisable(GL_LIGHTING);
break;
case 'q': //quit
exit(0);
break;
case 'r': //reset chat
reset();
break;
case 's': //stop movement
incang = 0.0f;
break;
case 't': //turn on writing
writing = true;
break;
case 'u': //increment the speed
incang += 0.1f;
break;
case 'v': //debug output
debug = !debug;
break;
case 'w': //turn off writing
writing = false;
break;
}
makemenu();
}
//display text
void echo()
{
glColor3f(0.5f, 0.8f, 0.5f);
glRasterPos2f(2.0f, 2.0f);
for (int b = 0; b < i; b++) {
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, thestring[b]);
}
}
//key presses
void handleKeypress(unsigned char key, int x, int y)
{
if (writing) {
if (key != 8) { //backspace
if (i < 250) {
if (key != 13) { //enter key
thestring[i] = key;
} else {
thestring[i] = '\n'; //epic fail I'll get it working eventually
}
i++;
} else {
if (!passed) {
thestring[i + 1] = '.';
thestring[i + 2] = '.';
thestring[i + 3] = '.';
i += 4;
passed = true;
}
}
}
}
if (writing) {
switch (key) {
case 8:
i--;
thestring[i] = ' ';
break;
}
}
}
//nothing usefull yet
void mouseClick(int button, int state, int x, int y)
{
cout << button << " | " << state << " | " << x << " | " << y << endl;
}
void initRendering()
{
//enable some opengl stuff
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_NORMALIZE);
glEnable(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glEnable(GL_FOG);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}
void handleResize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double) w / (double) h, 1.0, 200.0);
}
//rectangle function
void rec(float x, float y, float z)
{
glBegin(GL_QUADS); // Draw The Cube Using quads
glColor3f(red, green, blue);
glVertex3f(x, y, -z); // Top Right Of The Quad (Top)
glVertex3f(-x, y, -z); // Top Left Of The Quad (Top)
glVertex3f(-x, y, z); // Bottom Left Of The Quad (Top)
glVertex3f(x, y, z); // Bottom Right Of The Quad (Top)
glColor3f(red, blue, green);
glVertex3f(x, -y, z); // Top Right Of The Quad (Bottom)
glVertex3f(-x, -y, z); // Top Left Of The Quad (Bottom)
glVertex3f(-x, -y, -z); // Bottom Left Of The Quad (Bottom)
glVertex3f(x, -y, -z); // Bottom Right Of The Quad (Bottom)
glColor3f(blue, green, red);
glVertex3f(-x, y, z); // Top Right Of The Quad (Left)
glVertex3f(-x, y, -z); // Top Left Of The Quad (Left)
glVertex3f(-x, -y, -z); // Bottom Left Of The Quad (Left)
glVertex3f(-x, -y, z); // Bottom Right Of The Quad (Left)
glColor3f(blue, red, green);
glVertex3f(x, y, -z); // Top Right Of The Quad (Right)
glVertex3f(x, y, z); // Top Left Of The Quad (Right)
glVertex3f(x, -y, z); // Bottom Left Of The Quad (Right)
glVertex3f(x, -y, -z); // Bottom Right Of The Quad (Right)
glColor3f(green, red, blue);
glVertex3f(x, y, z); // Top Right Of The Quad (Front)
glVertex3f(-x, y, z); // Top Left Of The Quad (Front)
glVertex3f(-x, -y, z); // Bottom Left Of The Quad (Front)
glVertex3f(x, -y, z); // Bottom Right Of The Quad (Front)
glColor3f(green, blue, red);
glVertex3f(x, -y, -z); // Top Right Of The Quad (Back)
glVertex3f(-x, -y, -z); // Top Left Of The Quad (Back)
glVertex3f(-x, y, -z); // Bottom Left Of The Quad (Back)
glVertex3f(x, y, -z); // Bottom Right Of The Quad (Back)
glEnd(); // End Drawing The Cube
}
//set fog to zero slowly
float fogToZero()
{
if (fog_color > 0.0f) {
fog_color -= 0.0025f;
}
return fog_color;
}
//set fog to grey slowly
float fogToGrey()
{
if (fog_color < 0.5f) {
fog_color += 0.0025f;
}
return fog_color;
}
//Draws the 3D scene
void drawScene()
{
//are we clearing everything?
if (clear_all) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} else {
glClear(GL_DEPTH_BUFFER_BIT);
}
//is it a foggy day?
if (fog) {
glEnable(GL_FOG);
glClearColor(fogToGrey(), fogToGrey(), fogToGrey(), 1.0f);
} else {
glDisable(GL_FOG);
glClearColor(fogToZero(), fogToZero(), fogToZero(), 1.0f);
}
//fog stuff
GLfloat fogcolor[] = {0.5f, 0.5f, 0.5f, 1.0f};
glFogfv(GL_FOG_COLOR, fogcolor);
glFogi(GL_FOG_MODE, GL_EXP2);
//glFogf(GL_FOG_START, 1.0f); //uncomment glFogf if
//glFogf(GL_FOG_END, 15.0f); //GL_LINEAR is enabled
glFogf(GL_FOG_DENSITY, density); //then comment this line
glHint(GL_FOG_HINT, GL_NICEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//lighting
GLfloat colors[] = {0.3f, 0.3f, 0.3f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, colors);
GLfloat colors2[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat pos[] = {0.0f, 0.0f, 0.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, colors2);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
GLfloat colors3[] = {red, green, blue, 1.0f};
GLfloat pos1[] = {blue * 3, 4.0f, green * 5, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, colors3);
glLightfv(GL_LIGHT1, GL_POSITION, pos1);
glRotatef(-cameraAngle, 0.0f, 1.0f, 0.0f);
//2D drawing stuff
//should we draw text?
glTranslatef(-5.0f, -2.0f, -5.0f);
if (writing) {
echo();
}
//draw 3d stuff
//remember that colors on this section represent heights
//and not really color
glScalef(1.0f, 1.0f, 1.0f);
glTranslatef(0.0f, 0.0f, -5.0f);
glTranslatef(-red * 3, green * 2, -blue * 10);
glRotatef(angle, 1.0f * blue, 2.0f * red, 3.0f * green);
glRotatef(angle, 1.0f, 1.0f, 1.0f);
rec(green * 1.0f, red * 0.5f, blue * 1.5f);