#include #include #include using namespace std; // Constant for changing degrees into radians const double Deg2Rad = 0.0174532925199432957692369076848861; // The texture handle GLuint Tex; // A guy with a camera : CameraMan class CameraMan { private: float x, y, z; // Position in world float yaw, pitch, roll; // Rotations static const float StandingHeight = 3.0; static const float CrouchingHeight = 1.5; public: CameraMan() : x(0.0), y(StandingHeight), z(0.0), yaw(0.0), pitch(0.0), roll(0.0) {} ~CameraMan() {} // Walk forwards or backwards by d void Walk(float d) { float nyaw = (-yaw - 90.0) * Deg2Rad; x += cos(nyaw) * d; z += sin(nyaw) * d; } // Sidestep left or right by d void Sidestep(float d) { float nyaw = -yaw * Deg2Rad; x += cos(nyaw) * d; z += sin(nyaw) * d; } // Crouch at the speed of d void Crouch(float d) { if(y > CrouchingHeight) y -= d; if(y < CrouchingHeight) y = CrouchingHeight; } // Adjust rotations at a certain speed void Yaw(float d) { yaw += d; } void Pitch(float d) { pitch += d; } void Roll(float d) { roll += d; } // Update the CameraMan for one logic frame void Update() { // Move roll, pitch, and height towards default values roll *= 0.98; pitch *= 0.98; if(y < StandingHeight) y += 0.05; } // Apply CameraMan's transformations to the 3D world void ApplyTransformations() { glRotatef(-pitch, 1.0, 0.0, 0.0); glRotatef(-roll, 0.0, 0.0, 1.0); glRotatef(-yaw, 0.0, 1.0, 0.0); glTranslatef(-x, -y, -z); } }; // Timer interrupt system volatile int Time = 0; void TimerFunc() { Time++; } END_OF_FUNCTION(TimerFunc); void Init() { // Start up Allegro and AllegroGL systems allegro_init(); install_allegro_gl(); install_timer(); install_keyboard(); // Set up the timer interrupts LOCK_VARIABLE(Time); LOCK_FUNCTION(TimerFunc); install_int_ex(TimerFunc, BPS_TO_TIMER(50)); // Set some AllegroGL options allegro_gl_set(AGL_DOUBLEBUFFER, true); allegro_gl_set(AGL_COLOR_DEPTH, 16); allegro_gl_set(AGL_RENDERMETHOD, true); allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER | AGL_COLOR_DEPTH | AGL_RENDERMETHOD); // Set up a suitable viewing window set_color_depth(16); set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0); // Enable texturing glEnable(GL_TEXTURE_2D); // Set up culling glCullFace(GL_BACK); glEnable(GL_CULL_FACE); // We are using 24 bit textures in this case. allegro_gl_set_texture_format(GL_RGB8); // Load the texture BITMAP* temp_bmp = load_bitmap("layer0.bmp", 0); Tex = allegro_gl_make_texture(temp_bmp); glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); destroy_bitmap(temp_bmp); // Set up a perspective projection glMatrixMode(GL_PROJECTION); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); // Set the background color to black glClearColor(0.0, 0.0, 0.0, 0.0); } int main() { Init(); float speed = 0.1, rspeed = 1.0; CameraMan cm; while(!key[KEY_ESC]) { while(Time > 0) { // Move CameraMan according to user input if(key[KEY_LEFT]) cm.Yaw(rspeed); if(key[KEY_RIGHT]) cm.Yaw(-rspeed); if(key[KEY_UP]) cm.Pitch(rspeed); if(key[KEY_DOWN]) cm.Pitch(-rspeed); if(key[KEY_Z]) cm.Roll(rspeed); if(key[KEY_X]) cm.Roll(-rspeed); if(key[KEY_W]) cm.Walk(speed); if(key[KEY_S]) cm.Walk(-speed); if(key[KEY_D]) cm.Sidestep(speed); if(key[KEY_A]) cm.Sidestep(-speed); if(key[KEY_LCONTROL]) cm.Crouch(speed); // Update the CameraMan cm.Update(); Time--; } // Clear the screen glClear(GL_COLOR_BUFFER_BIT); // Load the identity matrix, then apply the CameraMan's transformations glLoadIdentity(); cm.ApplyTransformations(); // Draw the "floor" glBindTexture(GL_TEXTURE_2D, Tex); glBegin(GL_QUADS); glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2i(0, 1); glVertex3f(-20.0, 0.0, -20.0); glTexCoord2i(0, 0); glVertex3f(-20.0, 0.0, 20.0); glTexCoord2i(1, 0); glVertex3f(20.0, 0.0, 20.0); glTexCoord2i(1, 1); glVertex3f(20.0, 0.0, -20.0); glEnd(); // Flush drawing commands and flip the backbuffer glFlush(); allegro_gl_flip(); } return 0; } END_OF_MAIN();