i give up… i didnt wanna put my code online coz this is for uni assignment but here it is …
plz dont mind the messy object modelling…still need to clean it up…
i think the problem might be in the way im moving the camera…plz take a look at the change(), reshap() and init() functions
if you run it press F1 for help on keys…it’ll pop in the output window
im using visual studio 2008
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <ctime>
#include <math.h>
#define PI 3.1415926
GLfloat diffuse0[] = {1.0,1.0,0.0,1.0};
GLfloat ambient0[] = {0.0,0.0,0.0,1.0};
GLfloat specular0[] = {1.0,1.0,0.0,1.0};
GLfloat diffuse1[] = {0.4,0.4,0.4,1.0};
GLfloat specular1[] = {0.5,0.5,0.5,1.0};
GLfloat diffuse2[] = {0.4,0.4,0.4,1.0};
GLfloat specular2[] = {0.5,0.5,0.5,1.0};
GLfloat diffuse3[] = {0.4,0.4,0.4,1.0};
GLfloat specular3[] = {0.5,0.5,0.5,1.0};
GLfloat mspecular[] = {1.0,1.0,1.0,1.0};
GLfloat mbspecular[] = {0.0,0.0,1.0,1.0};
GLfloat mdiffuse_ambient[] = {1.0,1.0,1.0,1.0};
GLfloat mbdiffuse_ambient[] = {0.0,0.0,1.0,1.0};
GLfloat mshininess[] = {128.0};
GLfloat global_ambient[] = {0.0,0.0,0.0,1.0};
GLfloat spot_dir0[] = {-0.9,-1.0,-1.5};
GLfloat spot_cutoff0[] = {70.0};
GLfloat spot_exp0[] = {128.0};
class point
{
public:
int x,y,z;
};
point mesh2[10000][4];
point mesh[10000][4];
int minx=-400,maxx=400,minz=-1600,maxz=1000,xinc=20,zinc=20;
int stack=0,mesh2count=0; // count for squares
int x=-800,y=500,z=400,cx=0,cy=0,cz=0;
using namespace std;
void initialize()
{
int x=minx,z=minz;
for(z=minz;z<=maxz;z+=zinc) { // row
for(int x=minx;x<=maxx;x+=xinc) { // coloums
mesh[stack][0].x=x;
mesh[stack][0].y=0;
mesh[stack][0].z=z;
mesh[stack][1].x=x;
mesh[stack][1].y=0;
mesh[stack][1].z=z+zinc;
mesh[stack][2].x=x+xinc;
mesh[stack][2].y=0;
mesh[stack][2].z=z+zinc;
mesh[stack][3].x=x+xinc;
mesh[stack][3].y=0;
mesh[stack][3].z=z;
stack++;
}
}
}
void elevate()
{
int yoff=0,d1y=140,d2y=200,d3y,d4y;
int rinc=0;
for(int j=41*1;j<=41*126;j+=41) {
d3y=d1y;
d4y=d2y;
rinc+=1;
for(int i=1;i<=38;i++) {
yoff=d3y+ rand()/(RAND_MAX/(d4y-d3y+1)+1);
mesh[i+j][3].y+=yoff;
if(d3y<=d2y*2 && j<=41*40) {
d3y+=int(rinc/3);
d4y+=int(rinc/3);
}
if(d3y<=d2y*2 && j>=41*60 && j<=41*90) {
d3y+=int(rinc);
d4y+=int(rinc);
}
if(d3y<=d2y*2 && j>=41*90 && i<20) {
d3y+=int(rinc/5);
d4y+=int(rinc/5);
}
if(d3y<=d2y*2 && j>=41*90 && i>20) {
d3y-=int(rinc/5);
d4y-=int(rinc/5);
}
}
if(j>=41*70)
{
d1y+=5;
d2y+=5;
}
if(j <= 41*15) {
d1y+=20;
d2y+=20;
}
else if(d1y>=30 && j<=41*70) {
d1y-=30;
d2y-=30;
}
}
for(int j=82*0;j<=82*63;j+=82) { // copy elevated mesh
for(int i=0;i<=39;i++) {
mesh2[mesh2count][0].x=mesh[i+j][3].x;
mesh2[mesh2count][0].y=mesh[i+j][3].y;
mesh2[mesh2count][0].z=mesh[i+j][3].z;
mesh2[mesh2count][1].x=mesh[i+j+1][3].x;
mesh2[mesh2count][1].y=mesh[i+j+1][3].y;
mesh2[mesh2count][1].z=mesh[i+j+1][3].z;
mesh2[mesh2count][2].x=mesh[i+j+82+1][3].x;
mesh2[mesh2count][2].y=mesh[i+j+82+1][3].y;
mesh2[mesh2count][2].z=mesh[i+j+82+1][3].z;
mesh2[mesh2count][3].x=mesh[i+j+82][3].x;
mesh2[mesh2count][3].y=mesh[i+j+82][3].y;
mesh2[mesh2count][3].z=mesh[i+j+82][3].z;
mesh2count++;
}
}
}
void myInit()
{
glPointSize(4.0);
glClearColor (0.2, 0.2, 0.2, 0.0);
glShadeModel (GL_SMOOTH);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mdiffuse_ambient);
glMaterialfv(GL_FRONT, GL_SHININESS, mshininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, mspecular);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient0);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse0);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular0);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir0);
glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff0);
glLightfv(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exp0);
glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuse1);
glLightfv(GL_LIGHT1,GL_SPECULAR,specular1);
glLightfv(GL_LIGHT2,GL_DIFFUSE,diffuse2);
glLightfv(GL_LIGHT2,GL_SPECULAR,specular2);
glLightfv(GL_LIGHT3,GL_DIFFUSE,diffuse3);
glLightfv(GL_LIGHT3,GL_SPECULAR,specular3);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
//glEnable(GL_LIGHT2);
// glEnable(GL_LIGHT3);
//glEnable(GL_COLOR_MATERIAL);
//glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120, 1, 1.0, 2000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x,y,z,0.0,0.0,-400.0,0.0,1.0,0.0);
GLfloat light_position0[] = { 300,500,100, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
GLfloat light_position1[] = { 800.0,900,-1400.0, 1.0 };
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
GLfloat light_position2[] = { 1000.0,500,-800.0, 1.0 };
glLightfv(GL_LIGHT2, GL_POSITION, light_position2);
GLfloat light_position3[] = { -900.0,400,-800.0, 1.0 };
glLightfv(GL_LIGHT3, GL_POSITION, light_position3);
GLfloat light_position4[] = { -400.0,500,-800.0, 1.0 };
glLightfv(GL_LIGHT4, GL_POSITION, light_position4);
glPushMatrix();
glPopMatrix();
glLoadIdentity();
}
void axis()
{
glBegin(GL_LINES);
glColor3f(0,1,0); // y-axis green
glVertex3i(0,-400,00);
glVertex3i(0,800,00);
glEnd();
}
void normal (point p1,point p2,point p3,point &normal)
{
point a, b;
// calculate the vectors A and B
// a
a.x = p3.x - p2.x;
a.y = p3.y - p2.y;
a.z = p3.z - p2.z;
// b
b.x = p1.x - p2.x;
b.y = p1.y - p2.y;
b.z = p1.z - p2.z;
// calculate the cross product and place the resulting vector
// into the address specified by vertex_t *normal
normal.x = ((a.y * b.z) - (a.z * b.y));
normal.y = ((a.z * b.x) - (a.x * b.z));
normal.z = ((a.x * b.y) - (a.y * b.x));
// normalize
float len = (float)(sqrt((double)((normal.x * normal.x) + (normal.y * normal.y) + (normal.z * normal.z))));
// avoid division by 0
if (len == 0.0f)
len = 1.0f;
// reduce to unit size
normal.x /= len;
normal.y /= len;
normal.z /= len;
}
void draw()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
point norm;
//sphere2(20,20);
//glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE);
for(int i=0;i<stack;i++){ // base mesh
if(mesh[i][3].y==0){
if(mesh[i][3].y >=0 && mesh[i][3].y <=30)
glColor4f(0,0,1,0.6);
glBegin(GL_QUADS);
normal(mesh[i][0],mesh[i][1],mesh[i][2],norm);
glNormal3f(norm.x,norm.y,norm.z);
glVertex3i(mesh[i][0].x,mesh[i][0].y,mesh[i][0].z);
glVertex3i(mesh[i][1].x,mesh[i][1].y,mesh[i][1].z);
glVertex3i(mesh[i][2].x,mesh[i][2].y,mesh[i][2].z);
glVertex3i(mesh[i][3].x,mesh[i][3].y,mesh[i][3].z);
glEnd();
}
}
glBegin(GL_POINTS);
glVertex3i(800.0,800,-1400.0);
glEnd();
for(int i=0;i<=mesh2count;i++) { // print elevated mesh
glColor3f(0.0,0.6,0.0);
int j=0;
if(i>=41*21 && i<=41*28) { // water
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mbdiffuse_ambient);
glMaterialfv(GL_FRONT, GL_SPECULAR, mbspecular);
}
glBegin(GL_QUADS);
normal(mesh[i][0],mesh[i][1],mesh[i][2],norm);
glNormal3f(norm.x,norm.y,norm.z);
//glNormal3f(mesh2[i][0].x,mesh2[i][0].y,mesh2[i][0].z);
glVertex3i(mesh2[i][0].x,mesh2[i][0].y,mesh2[i][0].z);
//glNormal3f(mesh2[i][1].x,mesh2[i][1].y,mesh2[i][1].z);
glVertex3i(mesh2[i][1].x,mesh2[i][1].y,mesh2[i][1].z);
//glNormal3f(mesh2[i][2].x,mesh2[i][2].y,mesh2[i][2].z);
glVertex3i(mesh2[i][2].x,mesh2[i][2].y,mesh2[i][2].z);
//glNormal3f(mesh2[i][3].x,mesh2[i][3].y,mesh2[i][3].z);
glVertex3i(mesh2[i][3].x,mesh2[i][3].y,mesh2[i][3].z);
glEnd();
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mdiffuse_ambient);
glMaterialfv(GL_FRONT, GL_SPECULAR, mspecular);
}
axis();
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
draw();
glFlush();
}
void resetMe()
{
x=-800, y=500, z=400;
myInit();
}
void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120, (float)w/(float)h, 1.0, 2000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x,y,z,cx,cy,cz,0.0,1.0,0.0);
}
void change(float tx, float ty,float tz, float tcx, float tcy, float tcz)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x+=tx,y+=ty,z+=tz,cx+=tcx,cy+=tcy,cz+=tcz,0.0,1.0,0.0);
}
void cameraHelp()
{
cout << "
HOW TO CONTROL THE VIEW ";
cout << "
left key - " << "Move feet left";
cout << "
Right key - " << "Move feet right";
cout << "
Up key - " << "Move feet up";
cout << "
Down key - " << "Move feet down";
cout << "
Home key - " << "Move camera up";
cout << "
Page Up key - " << "Move camera left";
cout << "
Page Down key - " << "Move camera right";
cout << "
End key - " << "Move camera down";
cout << "
F3 - " << "Reset to original view";
cout << "
F4 - Move along -x axis";
cout << "
F - Move along +x axis";
}
void keyboard (int key, int a, int b)
{
float x=0.0, y=0.0, z=0.0, cx=0, cy=0, cz=0; ;
switch (key) {
case GLUT_KEY_LEFT:
z-=20;
cz-=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_RIGHT:
z+=20;
cz+=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_UP :
y+=20;
cy+=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_DOWN :
y-=20;
cy-=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_F1 :
cameraHelp();
case GLUT_KEY_F2 :
change(x, y, z, cx, cy, cz); break;
case GLUT_KEY_F3 :
resetMe(); break;
case GLUT_KEY_F4 :
x+=20;
change(x, y, z, cx, cy, cz);
break;
case GLUT_KEY_F5 :
x-=20;
change(x, y, z, cx, cy, cz);
break;
case GLUT_KEY_PAGE_UP :
cz+=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_PAGE_DOWN :
cz-=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_HOME :
cy+=20;
change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_END :
cy-=20;
change(x, y, z, cx, cy, cz);break;
}
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize(600,600);
glutInitWindowPosition(50,50);
glutCreateWindow("3D Viewing System");
myInit();
initialize();
elevate();
glutSpecialFunc (keyboard);
glutDisplayFunc(myDisplay);
glutIdleFunc (myDisplay);
glutReshapeFunc (reshape);
cout << "
Stack = " << stack;
glutDisplayFunc(myDisplay);
glutMainLoop();
}
thanks
Raza