#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <gl\glut.h>
// Colors.
#define COLOR_RED 1
#define COLOR_GREEN 2
#define COLOR_BLUE 3
#define COLOR_ORANGE 4
#define COLOR_WHITE 5
#define COLOR_YELLOW 6
static int yRotNew = 0;
static int yRotOld = 0;
static int xRotNew = 0;
static int xRotOld = 0;
// Light values and coordinates.
GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
void DrawColor(int color)
{
switch (color)
{
case 1: glColor3ub(255, 0, 0);
break;
case 2: glColor3ub(0, 255, 0);
break;
case 3: glColor3ub(0, 0, 255);
break;
case 4: glColor3ub(255, 128, 0);
break;
case 5: glColor3ub(255, 255, 255);
break;
case 6: glColor3ub(255, 255, 0);
break;
}
}
void DrawCoordSystem(void)
{
glBegin(GL_LINES);
DrawColor(1); // Rot
glVertex3f(0, 0, 0);
glVertex3f(1.5, 0, 0);
DrawColor(2); // Grün
glVertex3f(0, 0, 0);
glVertex3f(0, 1.5, 0);
DrawColor(3); // Blau
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 1.5);
glEnd();
}
// Cube neigen, sodass 3 Seiten sichtbar werden.
void DipCube()
{
glRotatef(25, 1, 0, 0);
glRotatef(65, 0, 1, 0);
}
//////////////////////////////////////////////
void DrawSurface1(void)
{
glBegin(GL_QUADS);
// Oben links.
DrawColor(1);
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.8f, 0.8f, 0.8f);
glVertex3f( -0.3f, 0.8f, 0.8f);
glVertex3f( -0.3f, 0.3f, 0.8f);
glVertex3f( -0.8f, 0.3f, 0.8f);
// Oben mitte.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.25f, 0.8f, 0.8f);
glVertex3f( 0.25f, 0.8f, 0.8f);
glVertex3f( 0.25f, 0.3f, 0.8f);
glVertex3f( -0.25f, 0.3f, 0.8f);
// Oben rechts.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.8f, 0.8f, 0.8f);
glVertex3f( 0.3f, 0.8f, 0.8f);
glVertex3f( 0.3f, 0.3f, 0.8f);
glVertex3f( 0.8f, 0.3f, 0.8f);
// Mitte links.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.8f, 0.25f, 0.8f);
glVertex3f( -0.3f, 0.25f, 0.8f);
glVertex3f( -0.3f, -0.25f, 0.8f);
glVertex3f( -0.8f, -0.25f, 0.8f);
// Mitte mitte.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.25f, 0.25f, 0.8f);
glVertex3f( 0.25f, 0.25f, 0.8f);
glVertex3f( 0.25f, -0.25f, 0.8f);
glVertex3f( -0.25f, -0.25f, 0.8f);
// Mitte rechts.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.8f, 0.25f, 0.8f);
glVertex3f( 0.3f, 0.25f, 0.8f);
glVertex3f( 0.3f, -0.25f, 0.8f);
glVertex3f( 0.8f, -0.25f, 0.8f);
// Unten links.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.8f, -0.3f, 0.8f);
glVertex3f( -0.3f, -0.3f, 0.8f);
glVertex3f( -0.3f, -0.8f, 0.8f);
glVertex3f( -0.8f, -0.8f, 0.8f);
// Unten mitte.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( -0.25f, -0.3f, 0.8f);
glVertex3f( 0.25f, -0.3f, 0.8f);
glVertex3f( 0.25f, -0.8f, 0.8f);
glVertex3f( -0.25f, -0.8f, 0.8f);
// Unten rechts.
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.8f, -0.3f, 0.8f);
glVertex3f( 0.3f, -0.3f, 0.8f);
glVertex3f( 0.3f, -0.8f, 0.8f);
glVertex3f( 0.8f, -0.8f, 0.8f);
glEnd();
}
void DrawSurface2(void)
{
}
void DrawSurface3(void)
{
}
void DrawSurface4(void)
{
}
void DrawSurface5(void)
{
}
void DrawSurface6(void)
{
}
void DrawCube(void)
{
DrawSurface1();
DrawSurface2();
DrawSurface3();
DrawSurface4();
DrawSurface5();
DrawSurface6();
}
// This function does any needed initialization on the rendering context.
void SetupRC()
{
// Black background
glClearColor(0.5f, 0.5f, 0.5f, 0.5f );
// Enable Depth Testing
glEnable(GL_DEPTH_TEST);
// Enable lighting
glEnable(GL_LIGHTING);
// Setup and enable light 0
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glEnable(GL_LIGHT0);
// Enable color tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// All materials hereafter have full specular reflectivity
// with a high shine
glMaterialfv(GL_FRONT, GL_SPECULAR,specref);
glMateriali(GL_FRONT,GL_SHININESS,128);
}
void ChangeSize(int w, int h)
{
GLfloat lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };
GLfloat nRange = 1.9f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
}
void Up(void)
{
for (int i = xRotOld; i >= xRotNew; i--)
{
Sleep(5);
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
DipCube();
glRotatef(i, 0, 0, 1);
glRotatef(yRotNew, 0, 1, 0);
DrawCube();
DrawCoordSystem();
// Restore transformations
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
xRotOld = xRotNew;
}
void Down(void)
{
for (int i = xRotOld; i <= xRotNew; i++)
{
Sleep(5);
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
DipCube();
glRotatef(i, 0, 0, 1);
glRotatef(yRotNew, 0, 1, 0);
DrawCube();
DrawCoordSystem();
// Restore transformations
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
xRotOld = xRotNew;
}
void Left(void)
{
for (int i = yRotOld; i >= yRotNew; i--)
{
Sleep(5);
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
DipCube();
glRotatef(i, 0, 1, 0);
glRotatef(xRotNew, 0, 0, 1);
DrawCoordSystem();
DrawCube();
// Restore transformations
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
yRotOld = yRotNew;
}
void Right(void)
{
for (int i = yRotOld; i <= yRotNew; i++)
{
Sleep(5);
// Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
DipCube();
glRotatef(i, 0, 1, 0);
glRotatef(xRotNew, 0, 0, 1);
DrawCoordSystem();
DrawCube();
// Restore transformations
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
}
yRotOld = yRotNew;
}
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP)
{
xRotNew -= 90;
Up();
}
else if (key == GLUT_KEY_DOWN)
{
xRotNew += 90;
Down();
}
else if (key == GLUT_KEY_LEFT)
{
yRotNew -= 90;
Left();
}
else if (key == GLUT_KEY_RIGHT)
{
yRotNew += 90;
Right();
}
}
// Called to draw scene
void RenderScene(void)
{
}
void EnableAntialiasing(bool enable)
{
if (enable)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
}
else
{
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_POINT_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("RubiksCubeGL by Florian Ulitzka & Timm Krause");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
EnableAntialiasing(true);
SetupRC();
glutMainLoop();
return 0;
}