Code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <GL/glut.h>
#include "imageloader.h"
using namespace std;
const float BOX_SIZE = 7.0f; // The length of each side of the cube
float _angle = 0; // The rotation of the box
// Okay, we're going to attempt to change images here... Here goes:
char picture1[]="Ruby1.bmp";
char picture2[]="Ruby2.bmp";
// This should track of the picture in the cube, ie, 0=Ruby1.bmp, 1=Ruby2.bmp:
short int pic=0;
// This will tell another part of the programme that space has been pressed:
short int space=0;
// This is just to check that the first default picture is only loaded onces:
short int once=0;
// Here is our global variable of image
// If only this would update dynamically!!!
Image* image;
GLuint _textureId; // The OpenGL id of the texture
// This routine or sub-routine or method or function checks for key events:
void handleKeypress(unsigned char key, int x, int y)
{
switch (key)
{
if (pic>1)
{
pic=0;
}
case 0x20: //Space key
pic=pic+1;
space=1;
break;
case 0x58: // X key
_angle=_angle+0.75f;
break;
case 0x5a: // Z key
_angle=_angle-0.75f;
break;
case 0x1b: //Escape key
exit(0);
break;
default:
space=0;
break;
}
}
// Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image)
{
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
image->width, image->height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return textureId;
}
// Here is the rendering routine.../function/whatever that sets everything up:
void initRendering()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
// This should only load the default picture once:
if(once==0)
{
image=loadBMP(picture1);
++once;
}
_textureId = loadTexture(image);
delete image;
}
// What the following is trying to do is to load another BMP image in, or flip the
// pictures, as Image* image is declared as a global as far as I can tell.
void loadImage()
{
// We'll also check if Space has actually been depressed too, just to stop
// any unnecessary switching of pictures - if it worked that is:
if(pic==0 && space==1)
{
image=loadBMP(picture1);
space=0;
}
else
if(pic==1 && space==1)
{
image=loadBMP(picture2);
space=0;
}
delete image;
}
// Presumabely, this handles windows resizing:
void handleResize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}
// This draws the filled vector that we has set up:
void drawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -20.0f);
GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat lightPos[] = {-2 * BOX_SIZE, BOX_SIZE, 4 * BOX_SIZE, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glRotatef(-_angle, 1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
// Top face
glColor3f(1.0f, 1.0f, 0.0f);
glNormal3f(0.0, 1.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
// Bottom face
glColor3f(1.0f, 0.0f, 1.0f);
glNormal3f(0.0, -1.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
// Left face
glNormal3f(-1.0, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
// Right face
glNormal3f(1.0, 0.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
// Front face
glNormal3f(0.0, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
// Back face
glNormal3f(0.0, 0.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
// Called every 25 milliseconds - I wonder how many cycles to the ms?
void update(int value)
{
// Commented out as this is now handled elsewhere:
//_angle += 0.5f;
if (_angle>360)
{
_angle-=360;
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
// And here is our main bit:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 400);
glutCreateWindow("Donkeysoft MMXI");
loadImage();
initRendering();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);
glutMainLoop();
return 0;
}