PDA

View Full Version : movement in a 3D terrain using GLUT and OOP



moogoo
04-01-2004, 07:24 PM
I'm programming a fun little scene that consists of 4 quads, one being the terrain and than 3 walls enclosing it. I want to create an object, for now something simple like a cube, and be able to move it around the terrain via the arrow keys.

I am implementing this using GLUT 3.7 and using an classes and C++ OOP design for all of my objects.

I am able to draw a cube in the middle of the terrain, but i can not move it. Any suggestions? code for the terrain, robot and main are posted below.


/*
GLTerrain.cpp

GLTerrain class implementation

Author: Michael Le
Date Created: 3.4.04
Dependencies: openGL libraries

*/
#include "GLTerrain.h"
#include "textureLoader.h"

GLTerrain::GLTerrain(){
_terrainBmp = "";
_wallBmp = "";
}

GLTerrain::GLTerrain(char* terrainBmp, char* wallBmp){
_terrainBmp = terrainBmp;
_wallBmp = wallBmp;
}

GLTerrain::~GLTerrain(){
delete _terrainBmp;
delete _wallBmp;
}

void GLTerrain::initTex(char * terrainBmp, char* wallBmp){
setTerrainBmp(terrainBmp);
setWallBmp(wallBmp);
}

void GLTerrain::setTerrainBmp(char* terrainBmp){
_terrainBmp = terrainBmp;
}

void GLTerrain::setWallBmp(char* wallBmp){
_wallBmp = wallBmp;
}

void GLTerrain::setupTextures(){
textureLoader* texLoader = new textureLoader();
_terrainTex = texLoader->LoadGLTexture(_terrainBmp);
_wallTex = texLoader->LoadGLTexture(_wallBmp);
delete texLoader;
}

void GLTerrain::drawTerrain(){
setupTextures();
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, _terrainTex);
// terrain
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 600.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(800.0f, 0.0f, 600.0f);
glTexCoord2f(1.0f, 0.75f); glVertex3f(800.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.75f); glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, _wallTex);
glBegin(GL_QUADS);
// left wall
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 600.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.5f); glVertex3f(0.0f, 300.0f, 0.0f);
glTexCoord2f(0.0f, 0.5f); glVertex3f(0.0f, 300.0f, 600.0f);
glEdgeFlag(GL_TRUE);

// back wall
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(800.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.375f); glVertex3f(800.0f, 300.0f, 0.0f);
glTexCoord2f(0.0f, 0.375f); glVertex3f(0.0f, 300.0f, 0.0f);
glEdgeFlag(GL_TRUE);

// right wall
glTexCoord2f(0.0f, 0.0f); glVertex3f(800.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(800.0f, 0.0f, 600.0f);
glTexCoord2f(1.0f, 0.5f); glVertex3f(800.0f, 300.0f, 600.0f);
glTexCoord2f(0.0f, 0.5f); glVertex3f(800.0f, 300.0f, 0.0f);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}

/*
glRobot.cpp

Implementation of glRobot class

Author: Michael Le
Date Created: 3.4.04
Dependencies: openGL libraries
*/

#include "glRobot.h"
#include "textureLoader.h"

//GLUquadricObj *robot;

glRobot::glRobot(){
_x = 0.0f;
_y = 0.0f;
_z = 0.0f;
_spin = 0.0f;
_robotBmp = "";
}

glRobot::glRobot(GLfloat x, GLfloat y, GLfloat z, GLfloat spin, char * robotBmp, char* robot2Bmp){
_x = x;
_y = y;
_z = z;
_spin = spin;
_robotBmp = robotBmp;
_robot2Bmp = robot2Bmp;
}

glRobot::~glRobot(){
delete _robotBmp;
delete _robot2Bmp;
}

void glRobot::setupTexture(){
textureLoader* texLoader = new textureLoader();
_robotTex = texLoader->LoadGLTexture(_robotBmp);
_robot2Tex = texLoader->LoadGLTexture(_robot2Bmp);
delete texLoader;
}

void glRobot::drawRobot(){
setupTexture();
glTranslatef(_x, _y, _z);
glRotatef(_spin, 0.0f, 1.0f, 0.0f);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, _robotTex);
/*
robot = gluNewQuadric();
gluQuadricTexture(robot, GL_TRUE);
gluQuadricDrawStyle(robot, GLU_FILL);
gluQuadricNormals(robot, GLU_SMOOTH);
gluCylinder(robot, 16.0, 16.0, 48.0, 0, 1);
glDisable(GL_TEXTURE_2D);
gluDisk(robot, 0.0, 16.0, 0, 1);
glPushMatrix();
glShadeModel(GL_SMOOTH);
glRotatef(90.0, -1.0, 0.0, 0.0);
glTranslatef(_x, _y, _z);
glRotatef(_spin, 0.0, 1.0, 0.0);
glPopMatrix();
*/

glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 32.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(32.0f, 0.0f, 32.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(32.0f, 32.0f, 32.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 32.0f, 32.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, _robot2Tex);
glBegin(GL_QUADS);
// left side
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 32.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.0f, 32.0f, 32.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 32.0f, 0.0f);
// backside
glTexCoord2f(0.0f, 0.0f); glVertex3f(32.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.0f, 32.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(32.0f, 32.0f, 0.0f);
// right side
glTexCoord2f(0.0f, 0.0f); glVertex3f(32.0f, 0.0f, 32.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(32.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(32.0f, 32.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(32.0f, 32.0f, 32.0f);
// top
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 32.0f, 32.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(32.0f, 32.0f, 32.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(32.0f, 32.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 32.0f, 0.0f);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}

void glRobot::moveForward(){
_z = _z + 5.0f;
//glutPostRedisplay();
}

void glRobot::moveBack(){
_z = _z - 5.0f;
//glutPostRedisplay();
}

void glRobot::rotateLeft(){
_spin = _spin + 10.0f;
if (_spin > 360.0f)
_spin = _spin - 360.0f;
//glutPostRedisplay();
}

void glRobot::rotateRight(){
_spin = _spin - 10.0f;
if (_spin < 0.0f)
_spin = _spin + 360.0f;
//glutPostRedisplay();
}



/*
TCT.cpp

This is the main program. it is relatively simple.

This file creates a GLUT handler so that we can interface with glut through the C++
wrapper. It then creates a demo window and makes that window the current
idle window and begins the GLUT main loop.
*/

// this first line takes care of windows complaining about a win32 MAIN API crap...
#pragma comment( linker, "/entry:\"mainCRTStartup\"" )

#include <GL/glut.h>
#include <GL/glaux.h>
#include "GLTerrain.h"
#include "glRobot.h"
#include <windows.h>
#include <iostream>

#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking ( NEW )
#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking ( NEW )
#pragma comment( lib, "glaux.lib" )

GLTerrain _terrain = GLTerrain("data/grass2.bmp", "data/sky.bmp");
//glRobot _robot = glRobot(400.0f, 0.0f, 300.0f, 180.0f, "data/robot.bmp", "data/robot2.bmp");

void initialize(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void drawScene(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
_terrain.drawTerrain();
//_robot.drawRobot();
//glRotatef(_robot.getSpin(), 0.0, 1.0, 0.0);
//glTranslatef(_robot.getX(), _robot.getY(), _robot.getZ());
//glColor3f(1.0,1.0,1.0);
//glBegin(GL_QUADS);
// glVertex3f(0.0f, 0.0f, 32.0f);
// glVertex3f(32.0f, 0.0f, 32.0f);
// glVertex3f(32.0f, 0.0f, 0.0f);
// glVertex3f(0.0f, 0.0f, 0.0f);
//glEnd();
glPopMatrix();
glutSwapBuffers();
}

void reshape(int w, int h){
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, (GLfloat) w/ (GLfloat) h, 1.0f, 750.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(400.0f, 343.0f, 605.0f, 400.0f, 0.0f, 300.0f, 0.0f, 1.0f, -1.0f);
}

void keyboard(unsigned char key, int x, int y){
switch(key){
case 27:
glutLeaveGameMode();
exit(0);
break;
default:
break;
}
}

void rotateRight(){
//_robot.rotateRight();
glutPostRedisplay();
}

void rotateLeft(){
// _robot.rotateLeft();
glutPostRedisplay();
}

void moveForward(){
// _robot.moveForward();
glutPostRedisplay();
}

void moveBack(){
// _robot.moveBack();
glutPostRedisplay();
}

void arrowKeys(int key, int x, int y){
switch(key){
case GLUT_KEY_RIGHT:
glutIdleFunc(rotateRight);
break;
case GLUT_KEY_LEFT:
glutIdleFunc(rotateLeft);
break;
case GLUT_KEY_UP:
glutIdleFunc(moveForward);
break;
case GLUT_KEY_DOWN:
glutIdleFunc(moveBack);
default:
break;
}
}


int main(int argc, char** argv){
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutGameModeString("800x600:16");
if(glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
glutEnterGameMode();
else{
MessageBox(NULL,"Can not enter gamemode.","Error",MB_ICONSTOP);
return -1;
}
initialize();

glutDisplayFunc(drawScene);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
//glutSpecialFunc();
//glutIdleFunc(drawScene);
glutMainLoop();
return 0;
}Thanks, any help is greatly appreciated!!!!