So,I was working on a isometric view 3D game based on GLUT lib, but I ran into problems like mapping textures to objects. I just can’t seem to map textures into objects. The loader can’t load the files. Need a mouse control event like when Right Clicking a cylinder will be shot by the ball. Deadline is on this Sunday.
I couldn’t do all the coding.
Using tutorials from Lighthouse 3D and some other places. I modified, added, removed many parts of the codes.
The code is given:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
//camera modifiers
int camX = 0, camY = 0, camZ= 0;
// angle of rotation for the camera direction
float angle = 0.0f;
double refresh = 30.0;
// actual vector representing the camera's direction
float lx=0.0f,lz=-1.0f;
int mouseXd,mouseYd;
int mouseXu,mouseYu;
// XZ position of the camera
float x=0.0f, z=5.0f;
// the key states. These variables will be zero
// when no key is being pressesed
float deltaAngle = 0.0f;
float deltaMove = 0;
int xOrigin = -1;
// color for the snowman's nose
float red = 1.0f, blue=0.5f, green=0.5f;
// scale of snowman
float scale = 1.0f;
// default font
void *font = GLUT_STROKE_ROMAN;
// width and height of the window
int h,w;
// variables to compute frames per second
int frame;
long time, timebase;
char s[60];
char currentMode[80];
float light_pos=0;
// this string keeps the last good setting
// for the game mode
char gameModeString[40] = "640x480";
/*POINT STRUCTURE*/
typedef struct
{
float X;
float Y;
float Z;
} Point;
//CUBE POINTS
Point p[22];
//IMAGE DATA
static GLubyte image[20][2048][1768][4];
//a linear array to store image data
static GLubyte linearImage[20][2048*1768*4];
//IMAGE HEIGHT AND WIDTH
unsigned int imagewidth=0, imageheight=0;
//total size of the image file
unsigned long fileSize;
//texture object number
static GLuint texName[20];
void init();
void changeSize(int ww, int hh)
{
h = hh;
w = ww;
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if (h == 0)
h = 1;
float ratio = w * 1.0 / h;
// Use the Projection Matrix
glMatrixMode(GL_PROJECTION);
// Reset Matrix
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(45.0f, ratio, 0.1f, 100.0f);
// Get Back to the Modelview
glMatrixMode(GL_MODELVIEW);
}
void update(int value)
{
refresh += 1 ;
light_pos += 0.1f;
if(refresh >250)
{
refresh -= 250 ;
}
glutPostRedisplay() ;
glutTimerFunc(20, update, 0) ;
}
void drawGround()
{
glBegin(GL_QUADS);
glColor3f(0.3f,0.5f, 0.6f);
glVertex3f(-1000.0f, 0.0f, -1000.0f);
glVertex3f(-1000.0f, 0.0f, 1000.0f);
glVertex3f( 1000.0f, 0.0f, 1000.0f);
glVertex3f( 1000.0f, 0.0f, -1000.0f);
glEnd();
}
void buildings()
{
//Left
glPushMatrix();
glTranslated(0,0,-100+refresh);
glTranslated(-10,0,0);
for(int loop=0; loop<10; loop++)
{
glTranslated(0,0,-10);
glColor3f(0.8,0.1,0.1);
glutSolidCube(5);
}
for(int loop=0; loop<10; loop++)
{
glTranslated(0,0,-100);
glColor3f(0.8,0.1,0.1);
glutSolidCube(5);
}
glPopMatrix();
//Distant Right
glPushMatrix();
glTranslated(0,0,-100+refresh);
glTranslated(30,0,5);
for(int loop=0; loop<10; loop++)
{
glTranslated(0,0,-10);
glColor3f(0.1,0.8,0.2);
glutSolidCube(5);
}
for(int loop=0; loop<10; loop++)
{
glTranslated(0,0,-100);
glColor3f(0.96,0.3,0.1);
glutSolidCube(8);
}
glPopMatrix();
//Close Right
glPushMatrix();
glTranslated(0,0,-100+refresh);
glTranslated(15,0,0);
for(int loop=0; loop<300; loop+=60)
{
glTranslated(0,0,-5);
glColor3f(0.8,0.1,0.1);
glutSolidCube(10);
}
glPopMatrix();
}
void character(int xUp, int xDown, int yUp, int yDown)
{
glPushMatrix();
glTranslated( 10*lx,3,0);
glColor3f(1,1,1);
glutSolidSphere(0.5,20,20);
glPopMatrix();
}
void drawRoad()
{
glBegin(GL_QUADS);
glColor3f(0.1f,0.2f, 0.3f);
glVertex3f(-5.0f, 1.0f, -1000.0f);
glVertex3f(-5.0f, 1.0f, 1000.0f);
glVertex3f( 5.0f, 1.0f, 1000.0f);
glVertex3f( 5.0f, 1.0f, -1000.0f);
glEnd();
}
void roadMark()
{
for(int _val=-10000; _val<50000; _val+=10)
{
glPushMatrix();
glTranslated(0,0,refresh+_val);
glBegin(GL_QUADS);
glColor3f(0.8f,0.8f, 0.8f);
glVertex3f(-0.5f, 1.1f, -1.0f);
glVertex3f(-0.5f, 1.1f, 1.0f);
glVertex3f( 0.5f, 1.1f, 1.0f);
glVertex3f( 0.5f, 1.1f, -1.0f);
glEnd();
glPopMatrix();
}
}
void setLight()
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 2 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glShadeModel (GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
}
void Sun()
{
glColor3f(1.0f,0.6f, 0.3f);
glTranslatef(0.0f,100.0f,0.0f);
glutSolidSphere(0.75f,20,20);
}
void Tree()
{
glColor3f(0.3f,0.2f,0.1f);
glTranslatef(1.0,1.0,1.0);
glutSolidCone(0.1,50,5,20);
}
void drawSnowMan()
{
glScalef(scale, scale, scale);
glColor3f(1.0f, 1.0f, 1.0f);
// Draw Body
glTranslatef(0.0f,0.75f, 0.0f);
glutSolidSphere(0.75f,20,20);
// Draw Head
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.25f,20,20);
// Draw Eyes
glPushMatrix();
glColor3f(0.0f,0.0f,0.0f);
glTranslatef(0.05f, 0.10f, 0.18f);
glutSolidSphere(0.05f,10,10);
glTranslatef(-0.1f, 0.0f, 0.0f);
glutSolidSphere(0.05f,10,10);
glPopMatrix();
// Draw Nose
glColor3f(red, green, blue);
glRotatef(0.0f,1.0f, 0.0f, 0.0f);
glutSolidCone(0.08f,0.5f,10,2);
glColor3f(1.0f, 1.0f, 1.0f);
}
void renderBitmapString(
float x,
float y,
float z,
void *font,
char *string)
{
char *c;
glRasterPos3f(x, y,z);
for (c=string; *c != '\0'; c++)
{
glutBitmapCharacter(font, *c);
}
}
void renderStrokeFontString(
float x,
float y,
float z,
void *font,
char *string)
{
char *c;
glPushMatrix();
glTranslatef(x, y,z);
glScalef(0.002f, 0.002f, 0.002f);
for (c=string; *c != '\0'; c++)
{
glutStrokeCharacter(font, *c);
}
glPopMatrix();
}
void restorePerspectiveProjection()
{
glMatrixMode(GL_PROJECTION);
// restore previous projection matrix
glPopMatrix();
// get back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
void setOrthographicProjection()
{
// switch to projection mode
glMatrixMode(GL_PROJECTION);
// save previous matrix which contains the
//settings for the perspective projection
glPushMatrix();
// reset matrix
glLoadIdentity();
// set a 2D orthographic projection
gluOrtho2D(0, w, h, 0);
// switch back to modelview mode
glMatrixMode(GL_MODELVIEW);
}
void computePos(float deltaMove)
{
x += deltaMove * lx * 0.1f;
z += deltaMove * lz * 0.1f;
}
void convertToLinearArray()
{
int len;
int index;
for(index=0; index<6; index++)
{
len=0;
for(unsigned int r=0; r<imageheight; r++)
{
for(unsigned int c=0; c<imagewidth; c++)
{
for(int k=2; k>=0; k--)
{
linearImage[index][len++] = image[index][r][c][k];
}
linearImage[index][len++] = (GLubyte)255;
}
}
}
}
int loadImage(char *f_name,int index)
{
FILE *fp;
unsigned char blueValue, redValue, greenValue;
unsigned int r,c;
//opens the file
if(!(fp = fopen(f_name, "r")))
{
printf("File Open Error
");
return 0;
}
//seeking bytes from initial position
fseek(fp,2,0);
//reads file size
fread(&fileSize,4,1,fp);
//seeking bytes from initial position
fseek(fp,18,0);
//reading image height and width
fread(&imagewidth,4,1,fp);
fseek(fp,22,0);
fread(&imageheight,4,1,fp);
// printf("%d %d
",imagewidth,imageheight);
//now starts data reading
fseek(fp,54,0);
for(r=0; r<imageheight; r++)
{
for(c=0; c<imagewidth; c++)
{
fread(&blueValue, sizeof(char), 1, fp);
fread(&greenValue, sizeof(char), 1, fp);
fread(&redValue, sizeof(char), 1, fp);
image[index][r][c][0] = (GLubyte)blueValue;
image[index][r][c][1] = (GLubyte)greenValue;
image[index][r][c][2] = (GLubyte)redValue;
image[index][r][c][3] = (GLubyte)255;
}
}
//end of reading
fclose(fp);
return 1;
}
void initializeImages()
{
char file_name[100];
//opening file with filename
strcpy(file_name, "pic0.bmp");
//loading image file
if(!loadImage(file_name,0))
{
printf("
0File Error
");
}
}
void renderScene(void)
{
if (deltaMove)
computePos(deltaMove);
// Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.7,0.7,0.9,1.0);
// Reset transformations
glLoadIdentity();
// Set the camera
//gluLookAt( x, 1.0f, z,
// x+lx, 1.0f, z+lz,
// 0.0f, 1.0f, 0.0f);
gluLookAt( -10+camX-8, 15.0f+camY+9, 10+camZ-8,
1+camX-8, 1.0f+camY+9, 1+camZ-8,
0.0f, 1.0f, 0.0f);
// Draw ground
//----------------------------------
drawGround();
drawRoad();
roadMark();
character(mouseXu,mouseXd,mouseYu,mouseYd);
buildings();
//----------------------------------------
// Draw 36 SnowMen
char number[3];
for(int i = -3; i < 3; i++)
for(int j=-3; j < 3; j++)
{
glPushMatrix();
glTranslatef(i*10.0f, 0.0f, j * 10.0f);
//sprintf(number,"%d",(i+3)*6+(j+3));
// renderStrokeFontString(0.0f, 0.5f, 0.0f, (void *)font ,number);
glPopMatrix();
}
// Code to compute frames per second
frame++;
time=glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000)
{
sprintf(s,"FPS:%4.2f",
frame*1000.0/(time-timebase));
timebase = time;
frame = 0;
}
setOrthographicProjection();
void *font= GLUT_BITMAP_8_BY_13;
glPushMatrix();
glLoadIdentity();
renderBitmapString(30,15,0,font,(char *)"Project: Game [Beta Testing]");
renderBitmapString(30,30,0,font,s);
renderBitmapString(30,45,0,font,(char *)"F1 - Game Mode 640x480 32 bits");
renderBitmapString(30,60,0,font,(char *)"F2 - Game Mode 800x600 32 bits");
renderBitmapString(30,75,0,font,(char *)"F3 - Game Mode 1024x768 32 bits");
renderBitmapString(30,90,0,font,(char *)"F4 - Game Mode 1280x1024 32 bits");
renderBitmapString(30,105,0,font,(char *)"F5 - Game Mode 1920x1200 32 bits");
renderBitmapString(30,120,0,font,(char *)"F7 - Game Mode 1280x720 32 bits");
renderBitmapString(30,135,0,font,(char *)"F6 - Window Mode");
renderBitmapString(30,150,0,font,(char *)"Esc - Quit");
renderBitmapString(30,165,0,font,currentMode);
glPopMatrix();
restorePerspectiveProjection();
Sun();
glutSwapBuffers();
}
// -----------------------------------
// KEYBOARD
// -----------------------------------
void processNormalKeys(unsigned char key, int xx, int yy)
{
switch (key)
{
case 27:
if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) != 0)
glutLeaveGameMode();
exit(0);
break;
}
}
void NormalKey(unsigned char key, int xx, int yy)
{
switch(key)
{
case 'w':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camZ+=1;
break;
case 'a':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camX+=1;
break;
case 's':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camZ-=1;
break;
case 'd':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camX-=1;
break;
case '8':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camY+=1;
break;
case '2':
printf("Camera: X: %d Y: %d Z: %d
", camX, camY, camZ);
camY-=1;
break;
case '0':
camX=0;
camY=0;
camZ=0;
break;
}
glutPostRedisplay();
}
void pressKey(int key, int xx, int yy)
{
switch (key)
{
case GLUT_KEY_UP :
deltaMove = 0.5f;
break;
case GLUT_KEY_DOWN :
deltaMove = -0.5f;
break;
case GLUT_KEY_F1:
// define resolution, color depth
glutGameModeString("640x480:32");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"640x480:32");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
case GLUT_KEY_F2:
// define resolution, color depth
glutGameModeString("800x600:32");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"800x600:32");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
case GLUT_KEY_F3:
// define resolution, color depth
glutGameModeString("1024x768:32");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"1024x768:32");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
case GLUT_KEY_F4:
// define resolution, color depth
glutGameModeString("1280x1024:32");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"1280x1024:32");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
case GLUT_KEY_F5:
// define resolution, color depth
glutGameModeString("1920x1200");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"1920x1200");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
case GLUT_KEY_F6:
// return to default window
w = 800;
h = 600;
if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) != 0)
{
glutLeaveGameMode();
//init();
}
break;
case GLUT_KEY_F7:
// define resolution, color depth
glutGameModeString("1280x720:32");
// enter full screen
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
glutEnterGameMode();
sprintf(gameModeString,"1280x720:32");
// register callbacks again
// and init OpenGL context
init();
}
else
glutGameModeString(gameModeString);
break;
}
if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE) == 0)
sprintf(currentMode,"Current Mode: Window");
else
sprintf(currentMode,
"Current Mode: Game Mode %dx%d at %d hertz, %d bpp",
glutGameModeGet(GLUT_GAME_MODE_WIDTH),
glutGameModeGet(GLUT_GAME_MODE_HEIGHT),
glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE),
glutGameModeGet(GLUT_GAME_MODE_PIXEL_DEPTH));
}
void releaseKey(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
camZ+=1;
break;
case 'a':
camX+=1;
break;
case 's':
camZ-=1;
break;
case 'd':
camX-=1;
break;
}
}
// -----------------------------------
// MOUSE
// -----------------------------------
void mouseMove(int x, int y)
{
// this will only be true when the left button is down
if (xOrigin >= 0)
{
// update deltaAngle
deltaAngle = (x - xOrigin) * 0.001f;
// update camera's direction
lx = sin(angle + deltaAngle);
lz = -cos(angle + deltaAngle);
}
}
void mouseButton(int button, int state, int x, int y)
{
// only start motion if the left button is pressed
if (button == GLUT_LEFT_BUTTON)
{
// when the button is released
if (state == GLUT_UP)
{
angle += deltaAngle;
xOrigin = -1;
}
else // state = GLUT_DOWN
{
xOrigin = x;
}
}
if ((button == GLUT_RIGHT_BUTTON)) // It's a wheel event
{
if(state == GLUT_UP)
{
glPushMatrix();
glTranslated(10*lx,3,-refresh);
glutSolidCone(0.5,2,20,20);
glPopMatrix();
}
}
else
{
}
}
void init()
{
// register callbacks
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glutIgnoreKeyRepeat(1);
glutKeyboardFunc(NormalKey);
glutSpecialFunc(pressKey);
glutKeyboardUpFunc(releaseKey);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMove);
// OpenGL init
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
// -----------------------------------
// MAIN
// -----------------------------------
int main(int argc, char **argv)
{
// init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Lighthouse3D - GLUT Tutorial");
// register callbacks
init();
setLight();
initializeImages();
// enter GLUT event processing cycle
glutTimerFunc(100, update, 0) ;
glutMainLoop();
return 1;
}