Code-Practice

This section will contain the code written for this project

Week 4 Program

**HEADER FILES **

ImageTexture.h

#ifndef ImageTexture_H
#define ImageTexture_H
//
// ImageTexture defines a class that encapsulates a JPEG image
// Note: Requires mkOpenGLJPEGImage.dll
// By: gs.ude.sun.pmoc|gnafa#gs.ude.sun.pmoc|gnafa
#include "GL/glut.h"

struct RGB {
unsigned char R,G,B;
void set(unsigned char r,unsigned char g,unsigned char b) { R=r; G=g; B=b; }
};

class ImageJPEG {
public:
// Image data
RGB *pixels;
int width, height;
public:
ImageJPEG() : pixels(0) {}

// loads a JPEG image from file
bool loadImageFile(const char *filename);

// returns width or height
int getWidth() const { return width; }
int getHeight() const { return height; }

// allocates space for a new image
void alloc(int w, int h) {
if (w==width&&h==height) return;
width=w; height=h;
pixels = new RGB[width*height];
}

// Accessor: returns pixel value at location (i,j)
const RGB pixel(int i,int j) const { return pixels[j*width+i]; }

// Mutator: returns reference to pixel at location (i,j)
RGB &pixel(int i,int j) { return pixels[j*width+i]; }

// OpenGL displays
void drawImage() const;

// Output image to file
void save(const char *filename, int quality=85) const;

// Copy pixels
void copyPixelsFrom(const ImageJPEG *copy);

// Copy from OpenGL framebuffer
void readFramebufferImage(int x,int y,int w,int h);
void readFramebufferImage();
};

class ImageTexture : public ImageJPEG
{
public:
GLuint texture_id;

public:
ImageTexture() { }

// Converts image to texture, returns a texture ID
int initTexture();

// Sets texture as current OpenGL texture image
void bind();

// Draw a textured rectangle, centered at x,y,z
void drawTexturedRect();
};

#endif


++Timer.h

#ifndef Timer_H
#define Timer_H


Timer is an animation tool that invokes
// a given user routine (callback) at specific intervals.
// By: gs.ude.sun.pmoc|gnafa#gs.ude.sun.pmoc|gnafa
//

class Timer
{
public:
void (*callback)(); // User-defined function
float FPS;
int window;
bool is_active;

public:

Timer() : callback(0), window(-1), FPS(30), is_active(false) {}

// Starts the timer (FPS = frames per second)
void start(int window, float FPS, void (*proc)());

// Pauses the timer
void pause();

// Check if timer is running
bool isActive();

// activate the callback
void run();
};

#endif


++Vec2.h

#ifndef Vec2_H
#define Vec2_H

//
// Vec2 defines a simple 2-D Vector/Point class with
// overloaded operators.
// By: gs.ude.sun.pmoc|gnafa#gs.ude.sun.pmoc|gnafa
//

#include <math.h>

class Vec2
{
public:
double X,Y; // These are public for convenience.
public:
Vec2() : X(0), Y(0) {}
Vec2(double x,double y) : X(x), Y(y) {}

void set(double x,double y) { X=x; Y=y; }
void operator+=(const Vec2 &v) { X+=v.X; Y+=v.Y; }
void operator-=(const Vec2 &v) { X-=v.X; Y-=v.Y; }
};

// returns +v
inline const Vec2 &operator+(const Vec2& v) { return v; }

// returns -v
inline Vec2 operator-(const Vec2& v) { return Vec2(-v.X,-v.Y); }

// returns v1 + v2
inline Vec2 operator+(const Vec2& v1,const Vec2& v2) { return Vec2(v1.X+v2.X,v1.Y+v2.Y); }

// returns v1 - v2
inline Vec2 operator-(const Vec2& v1,const Vec2& v2) { return Vec2(v1.X-v2.X,v1.Y-v2.Y); }

// returns v * constant
inline Vec2 operator*(const Vec2& v,double constant) { return Vec2(v.X*constant,v.Y*constant); }

// returns constant * v
inline Vec2 operator*(double constant,const Vec2& v) { return Vec2(v.X*constant,v.Y*constant); }

// returns v / constant
inline Vec2 operator/(const Vec2& v,double constant) { return v*(1/constant); }

// returns the dot product of v1 and v2
inline double operator*(const Vec2& v1,const Vec2& v2) { return v1.X*v2.X+v1.Y*v2.Y; }

// returns the square of the magnitude of v
inline double getNorm2(const Vec2 &v) { return v*v; }

// returns the magnitude of v
inline double getNorm(const Vec2 &v) { return sqrt(getNorm2(v)); }

#endif

========================================================================

Source Files

++ImageTexture.cpp

#include "ImageTexture.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <setjmp.h>
#include <iostream>

using namespace std;

struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;

void my_error_exit(j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}

bool ImageJPEG::loadImageFile(const char *filename)
{
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE * infile = fopen(filename, "rb");
if (infile == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return 0;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);

alloc(cinfo.image_width,cinfo.image_height);

int row_stride = cinfo.output_width * cinfo.output_components;
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(&pixels[cinfo.image_width*(cinfo.image_height-cinfo.output_scanline)],buffer[0],3*cinfo.image_width);
}

jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);

return true;
}

void ImageJPEG::save(const char *filename, int quality) const
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
FILE *outfile = fopen(filename, "wb");
if (outfile == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = width; /* image width and height, in pixels */
cinfo.image_height = height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
int row_stride = width * 3;
// JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
while (cinfo.next_scanline < cinfo.image_height) {
// memcpy(buffer[0],&pixels[cinfo.image_width*(cinfo.image_height-cinfo.next_scanline)],3*cinfo.image_width);
row_pointer[0] = (unsigned char*) &pixels[cinfo.image_width*(cinfo.image_height-cinfo.next_scanline)];
// (void) jpeg_write_scanlines(&cinfo, buffer, 1);
int err= jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
}

void ImageJPEG::copyPixelsFrom(const ImageJPEG *copy)
{
memcpy(pixels,(unsigned char*) copy->pixels,width*height*3);
}

void ImageJPEG::readFramebufferImage()
{
int dims[4];
glGetIntegerv(GL_VIEWPORT,dims);
readFramebufferImage(0,0,dims[2],dims[3]);
}

void ImageJPEG::readFramebufferImage(int x,int y,int w,int h)
{
alloc(w,h);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BYTE,(GLvoid*)pixels);
}

void ImageJPEG::drawImage() const
{
if (pixels==0) return;
int dims[4];
glGetIntegerv(GL_VIEWPORT,dims);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glPixelZoom( float(dims[2])/width, float(dims[3])/height ); // to fill viewport, otherwise set to 1.0,1.0
glDrawPixels(width,height, GL_RGB,GL_UNSIGNED_BYTE, (unsigned char *) pixels);
}

int ImageTexture::initTexture()
{
glGenTextures(1,&texture_id);
glBindTexture(GL_TEXTURE_2D,texture_id);

glPixelStorei(GL_UNPACK_ALIGNMENT,1); // May not be power of 2
GLenum gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB,
GL_UNSIGNED_BYTE, (GLvoid *)pixels);
if (gluerr!=0) {
fprintf(stderr,"ImageTexture: Problem initializing texture image: %s\n",gluErrorString(gluerr));
exit(-1);
}

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

return texture_id;
}

void ImageTexture::bind()
{
glBindTexture(GL_TEXTURE_2D,texture_id);
}

void ImageTexture::drawTexturedRect()
{
float aspect = float(width)/height;
bind();
glBegin(GL_POLYGON);
glTexCoord2f(0,0);
glVertex2f(-aspect,-1);
glTexCoord2f(1,0);
glVertex2f(+aspect,-1);
glTexCoord2f(1,1);
glVertex2f(+aspect,1);
glTexCoord2f(0,1);
glVertex2f(-aspect,1);
glEnd();
}


Timer.cpp

#include "Timer.h"
#include <time.h>
#include <GL/glut.h>
#include <assert.h>
#include <iostream>

using namespace std;

static Timer *active = 0;

static float gettime(void)
{
// This function returns the elapsed time between successive calls.

static clock_t __told=0;

clock_t tnew,ris;
tnew=clock();
ris=tnew-__told;
__told=tnew;
return(ris/(float)CLOCKS_PER_SEC);
}

static float getelapsedtime(void)
{
return clock()/(float)CLOCKS_PER_SEC;
}

static void callback_timer(int wid)
{
if (active==0) return;
active->run();
}

void Timer::start(int window_, float FPS_, void (*proc)())
{
if (active != 0) {
cerr « "Can't start multiple global timers.\n";
return;
}

window = window_;
FPS = FPS_;
callback = proc;
is_active = true;

active = this;

callback_timer(window);
glutPostRedisplay();
}

void Timer::run()
{
double begin_time = getelapsedtime();

glutSetWindow(window);

(*callback)();

// loop to next frame at given FPS
if (is_active==false) { active=0; return; }

double delta = 1.0/FPS;
double tsleep = delta - (getelapsedtime()-begin_time);
if (tsleep<0) tsleep = 0; // This means draw() was "paused" somehow…
glutTimerFunc( int(1000*tsleep), callback_timer, 0);
}

void Timer::pause()
{
is_active = false;
active = 0;
}

bool Timer::isActive()
{
assert( !is_active || this==active );
return is_active;
}


flytext.cpp

#include <iostream>
#include <math.h>
#include <GL/glut.h>
#include "Vec2.h"
#include "FTGLTextureFont.h"
#include "Timer.h"
#include "ImageTexture.h"

using namespace std;

static const float FPS = 20; // Frames-per-second (reduce this for slow systems)
static FTFont* font; // FTGL font for rendering
static Timer timer; // Timer, for animation callback
static float t = 0; // Global elapsed time variable

static ImageTexture *nus = 0; // A sample image, textured rectangle
static ImageTexture *isfit = 0; // A sample picture of Norway
static ImageTexture *isfit2 = 0; // Sample Picture 2
static ImageTexture *isfit3 = 0; // Sample Picture 3
const float deg2rad = 3.14159/180; // added by me to convertdeg to rad

// Sample Truetype font files included with zip file
#define DEFAULT_FONT "GARA.TTF" // "ARIAL.TTF" is also included

// Generates a random floating-point number between 0-1
static float frand() {
return rand()/(float)RAND_MAX;
}

// Initialize font, graphics context and OpenGL states
void cb_init()
{
glClearColor(0.0, 0.0, 0.0, 0.0); // Background is black
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Required only for polygonal fonts.

// Initialize textured text
font = new FTGLTextureFont( DEFAULT_FONT );

int point_size = 36; // Doesn't really matter, we can glScale to resize
if (!font->FaceSize(point_size)) {
cerr « "ERROR: Unable to set font face size " « point_size « "\n";
}

// Loads a sample image, converts it to a texture
nus = new ImageTexture();
nus->loadImageFile("nuslogo.jpg");
nus->initTexture();
isfit = new ImageTexture();
isfit->loadImageFile("isfit1.jpg");
isfit->initTexture();
isfit2 = new ImageTexture();
isfit2->loadImageFile("isfit2.jpg");
isfit2->initTexture();
isfit3 = new ImageTexture();
isfit3->loadImageFile("isfit3.jpg");
isfit3->initTexture();
}

// GLUT callback for window resize
void cb_reshape(int w, int h)
{
// Use the entire window space
glViewport(0, 0, w, h);

// Sets up a 2-D orthographic projection
// with coordinate origin at center of viewport.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-w/2, w/2, -h/2, h/2);

// Turn on texturing and blending
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

// GLUT callback for keystrokes
void cb_keystroke(unsigned char key, int x, int y)
{
switch (key) {
case 'q': case 27: // Esc or 'q' Quits the program.
exit(1);
case ' ':
t =0; break; // Reset global time
default:
break;
}
}

// Creates a simple on-ramp/off-ramp function, useful
// for those fading operations.
float ease_inout(float x) {
float y = 2 * ( 1.0-fabs(2*(x-.5)) );
return (y>1)?1:y;
}

// GLUT callback for display
void draw_scene()
{
// TODO: Make and animate scene.

// Color - white, opaque
glColor4f(1.0, 1.0, 1.0, 1.0);
restart1:
//Scene 1 - Introduction
if( t<5)
{
const char *str= "~~Welcome~~";
float strwidth = font->Advance(str); // Width of string in pixels
float strheight = font->LineHeight(); // Height of string in pixels
//glRotatef(t*10, 0, 0, 1);
glColor4f(t, t/5, t/6, 1/t);
glTranslatef(-t*50,0,0);
font->Render(str);

const char *str2= "~~to~~";
float str2width = font->Advance(str2); // Width of string in pixels
float str2height = font->LineHeight(); // Height of string in pixels
//glRotatef(t*10, 0, 0, 1);
glColor4f(t, t/5, t/6, 1/t);
glTranslatef(-200+t*25,t*25,0);
font->Render(str2);
}
if ( t >= 5 && t < 10)
{
const char *str3= "~~ISFIT 2007~~";
float str3width = font->Advance(str3); // Width of string in pixels
float str3height = font->LineHeight(); // Height of string in pixels
glTranslatef(-175,0,0);

//glRotatef(+(t-5)*40, 0, 0, 1);
glColor4f((t-5)/10, t/7, t/15, 1);
glTranslatef(-200+t*25,(10-t)*25,0);
font->Render(str3);
}

if ( t>=10 && t<12)
{
char ch1[12];
ch1[0] = 'I';
ch1[1] = 'N';
ch1[2] = 'T';
ch1[3] = 'E';
ch1[4] = 'R';
ch1[5] = 'N';
ch1[6] = 'A';
ch1[7] = 'T';
ch1[8] = 'I';
ch1[9] = 'O';
ch1[10] = 'L';

ch1[11]='\0';
float ch1width = font->Advance(ch1); // Width of string in pixels
float ch1height = font->LineHeight(); // Height of string in pixels

glColor4f(0, 0, 1, 1);
glTranslatef(-220,100,1);
glRotatef(180*t,0,0,1);
font->Render(ch1);

}

if ( t>=12 && t<14)
{
char ch1[8];
ch1[0] = 'S';
ch1[1] = 'T';
ch1[2] = 'U';
ch1[3] = 'D';
ch1[4] = 'E';
ch1[5] = 'N';
ch1[6] = 'T';
ch1[7]='\0';
float ch1width = font->Advance(ch1); // Width of string in pixels
float ch1height = font->LineHeight(); // Height of string in pixels

glColor4f(0, 1, 0, 1);
glTranslatef(-160,60,1);
glRotatef(180*t,0,0,1);
font->Render(ch1);

}

if ( t>=14 && t<16)
{
char ch1[9];
ch1[0] = 'F';
ch1[1] = 'E';
ch1[2] = 'S';
ch1[3] = 'T';
ch1[4] = 'I';
ch1[5] = 'V';
ch1[6] = 'A';
ch1[7] = 'L';

ch1[8]='\0';
float ch1width = font->Advance(ch1); // Width of string in pixels
float ch1height = font->LineHeight(); // Height of string in pixels

glColor4f(1, 0, 0, 1);
glTranslatef(-120,50,1);
glRotatef(180*t,0,0,1);
font->Render(ch1);

}
if ( t>=16 && t<18)
{
char ch1[3];
ch1[0] = 'I';

ch1[1] = 'N';
ch1[2]='\0';
float ch1width = font->Advance(ch1); // Width of string in pixels
float ch1height = font->LineHeight(); // Height of string in pixels

glColor4f(1, 1, 0, 1);
glTranslatef(-100,40,1);
glRotatef(180*t,0,0,1);
font->Render(ch1);

}
if ( t>=18 && t<20)
{
char ch1[10];
ch1[0] = 'T';
ch1[1] = 'R';
ch1[2] = 'O';
ch1[3] = 'N';
ch1[4] = 'D';
ch1[5] = 'H';
ch1[6] = 'E';
ch1[7] = 'I';
ch1[8] = 'M';
ch1[9]='\0';
float ch1width = font->Advance(ch1); // Width of string in pixels
float ch1height = font->LineHeight(); // Height of string in pixels

glColor4f(0, 1, 1, 1);
glTranslatef(-80,40,1);
glRotatef(180*t,0,0,1);
font->Render(ch1);

}
if ( t >= 20 && t < 24 )
{

glTranslatef( -(20 +t),10,0 );
glScalef(50+t*3,50+t*3,1); // Unscaled image is 2x2 pixels
isfit->drawTexturedRect(); // Origin is at center of image
}

if ( t >= 24 && t < 28 )
{

glTranslatef( 0,0,0 );
glScalef(200-t*4,200-t*4,1); // Unscaled image is 2x2 pixels
isfit2->drawTexturedRect(); // Origin is at center of image
}

if ( t >= 28 && t < 32 )
{

glTranslatef( t/12,t/12,0 );
glScalef(200-t,200-t,1); // Unscaled image is 2x2 pixels
isfit3->drawTexturedRect(); // Origin is at center of image
}
if ( t>=32)
{
t=0;
goto restart1;

}

}

void cb_display(void)
{
glClear(GL_COLOR_BUFFER_BIT); // Clear screen
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // Reset modelview matrix
draw_scene(); // Draw scene
glutSwapBuffers(); // Double-buffered switch
t += 1.0/FPS; // Update global time
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowPosition(50, 120);
glutInitWindowSize(500, 350);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
int wid = glutCreateWindow("CS3241 Lab #2 - Flytext");
glutDisplayFunc(cb_display);
glutReshapeFunc(cb_reshape);
glutKeyboardFunc(cb_keystroke);

cb_init();
timer.start(wid, FPS, cb_display); // This will repeatedly call cb_display.

glutMainLoop();
return 0;
}

=========================================================================

In the above code some portions I have taken from the lab i did for my computer graphics module

=========================================================================

** WEEK 5 Program **

===================
===================

Header Files


++Eyecamera.h

//This class implemets "Helicopter Vision"

class Eyecamera
{

private:

double cosx,cosz,tilt,eyex,eyey,eyez,centrex,centrey,centrez,xangle; // gluLookAt parameters
void InitLookAt(); // Executes gluLookAt

public:

double speed,length,height; //Parameters which will change Eye position

void updateposition(); // To keep the eye moving automatically
void InitCamera(); // Initialise the internal parameters for gluLookAt
void rise(double high); // To move Eye up or down
void turn(double angle); // to rotate around the vertical axis
void twist(double angle);// to tilt the camera about vertical axis

};


++terrain.h

// Number of rows and columns
const int NR = 250;
const int NC = 250;

class terrain
{
private:
void normalise(); // Normalises the height values between 1 and 0
double frand(double min, double max);To generate a floating point random number between max and min
void InitHeights(); // resets heights to zero
void createhill(int px, int py, double r);
to create a hill at position px,py
double distance(double ax, double ay, double bx, double by);

public:
double heights[NR][NC];
int rows,columns;
double gridsize,maxheight,minheight;
terrain(int x, int y);
void generateterrain( int numhill);
};


++Timer.h

#ifndef Timer_H
#define Timer_H

Timer is an animation tool that invokes
// a given user routine (callback) at specific intervals.
// By: gs.ude.sun.pmoc|gnafa#gs.ude.sun.pmoc|gnafa
//
class Timer
{
public:
void (*callback)(); // User-defined function
float FPS;
int window;
bool is_active;

public:
Timer() : callback(0), window(-1), FPS(30), is_active(false) {}

// Starts the timer (FPS = frames per second)
void start(int window, float FPS, void (*proc)());

// Pauses the timer
void pause();

// Check if timer is running
bool isActive();

// activate the callback
void run();
};

#endif


========================================================================

** Source Files**

++Eyecamera.cpp

#include "Eyecamera.h"
#include <math.h>
#include <GL/glut.h>
#include <stdio.h>

const double PI = 3.14159265;

void Eyecamera :: updateposition()
{
eyex+=cosx*speed;
eyez+=cosz*speed;
centrex=eyex + cosx*length;
centrez=eyez+ cosz*length;

InitLookAt();
}

void Eyecamera ::InitCamera()
{
eyey=height;
centrey=height;
eyex=length/2;
eyez=length/2;
xangle=90;
cosx=0;
cosz=1;
}

void Eyecamera ::InitLookAt()
{
gluLookAt(eyex,eyey,eyez,
centrex,centrey,centrez,
0.0 , 1.0 , 0.0);
}

void Eyecamera ::rise(double high)
{
eyey += high;
}

void Eyecamera ::turn(double angle)
{
xangle += angle;
cosx = cos(xangle * PI/180);
cosz = sin(xangle * PI/180);
}

void Eyecamera ::twist(double angle)
{
centrey+=angle;
if(centrey<(-6*height))centrey=-6*height;
if(centrey>4*height)centrey=4*height;
}


++terrain.cpp

#include "terrain.h"
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>

terrain ::terrain(int x, int y)
{
rows = x;
columns = y;
}

void terrain ::InitHeights()
{
int i,j;
for(i=0;i<rows;i++)
{ for(j=0;j<columns;j++)
{
heights[i][j]=0;
}
}
maxheight=NR*0.5;
minheight=NR*0.25;
}

void terrain::createhill(int px, int py, double r)
{
double rec=1/r;
int i,j;
double dist;

for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
{
dist=distance(i,j,px,py);
if(dist<(r))
heights[i][j]+=r*(1+cos(3.1415*dist*dist*rec*rec)); //Falls withing radius

}
}

double terrain::distance(double ax, double ay, double bx, double by)
{
return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}

void terrain::generateterrain(int numhill)
{

InitHeights();

for(int h=0;h<numhill;h++)
{
createhill((int)frand(0,rows),(int)frand(0,columns),frand((int)maxheight,(int)minheight));
}

normalise();
}

void terrain::normalise()
{
int i,j;
double actMax,actMin;

actMax=actMin=heights[0][0];

for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
{
if(heights[i][j]>actMax)actMax=heights[i][j];
if(heights[i][j]<actMin)actMin=heights[i][j];
}

for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
{
heights[i][j] =(heights[i][j]-actMin) / (actMax-actMin);
heights[i][j]*=maxheight;
}
}

double terrain::frand(double min, double max)
{
double num;

num=((double)rand())/RAND_MAX;
return ((max-min)*(double)num + (double)min);

}


++Timer.cpp

// See Timer.h for description.

#include "Timer.h"
#include <time.h>
#include <GL/glut.h>
#include <assert.h>
#include <iostream>

using namespace std;

static Timer *active = 0;

static float gettime(void)
{
// This function returns the elapsed time between successive calls.

static clock_t __told=0;

clock_t tnew,ris;
tnew=clock();
ris=tnew-__told;
__told=tnew;
return(ris/(float)CLOCKS_PER_SEC);
}

static float getelapsedtime(void)
{
return clock()/(float)CLOCKS_PER_SEC;
}

static void callback_timer(int wid)
{
if (active==0) return;
active->run();
}

void Timer::start(int window_, float FPS_, void (*proc)())
{
if (active != 0) {
cerr « "Can't start multiple global timers.\n";
return;
}

window = window_;
FPS = FPS_;
callback = proc;
is_active = true;

active = this;

callback_timer(window);
glutPostRedisplay();
}

void Timer::run()
{
double begin_time = getelapsedtime();

glutSetWindow(window);

(*callback)();

// loop to next frame at given FPS
if (is_active==false) { active=0; return; }

double delta = 1.0/FPS;
double tsleep = delta - (getelapsedtime()-begin_time);
if (tsleep<0) tsleep = 0; // This means draw() was "paused" somehow…
glutTimerFunc( int(1000*tsleep), callback_timer, 0);
}

void Timer::pause()
{
is_active = false;
active = 0;
}

bool Timer::isActive()
{
assert( !is_active || this==active );
return is_active;
}


++Terrain-soln.cpp

#include <stdio.h>
#include <GL/glut.h>
#include "Timer.h"
#include<time.h>
#include <stdlib.h>
#include "terrain.h"
#include<math.h>
#include"Eyecamera.h"

static Timer T; //Frame timer
Eyecamera Eye;

terrain heightMap(NR,NC);

int mousex,mousey;
int keypress = 0;
int first=0;

static void reshape_callback(int w, int h)
{
// Resets the matrices to identity and sets up
// a perspective projection on the PROJECTION matrix.
//
// Todo: register this function using glutReshapeFunc in main.

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75.0,(w/(float)h),0.1,500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,w,h);
}

void drawVertex( int x, int y ) // Adds a new vertex
{
double p=1-(heightMap.heights[x][y]-heightMap.minheight)/(heightMap.maxheight-heightMap.minheight);

glColor3f( (1-p), (0.1*p), p );
glVertex3f(x*heightMap.gridsize,heightMap.heights[x][y]*heightMap.gridsize,y);

}

void drawZLines()
{

int x,z;

for(z=0;z<heightMap.columns;z++)
{
glBegin(GL_LINE_STRIP);
for(x=0;x<heightMap.rows;x++)
{
drawVertex(x,z);
}
glEnd();
}

}

void drawXLines() //Draws lines with different Xs
{
int x,z;
for(x=0;x<heightMap.rows;x++)
{
glBegin(GL_LINE_STRIP);
for(z=0;z<heightMap.columns;z++)
{
drawVertex(x,z);
}
glEnd();
}

}

void init() // Initializes camera
{
Eye.length=NR*heightMap.gridsize;
Eye.speed=0.15;
Eye.height=heightMap.maxheight*heightMap.gridsize;
Eye.InitCamera();
}

void setup() //Generates terrain and initializes camera
{

heightMap.gridsize=0.9;
heightMap.generateterrain(90);
init();
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Eye.updateposition();
drawXLines();
drawZLines();
glutSwapBuffers();
}

static void normalkey(unsigned char k, int x, int y) //Responds to keyboard commands
{
switch(k)
{
case 27: // Escape key
exit(0);
break;

case 's':
Eye.rise(0.5);;

break;

case 'x':
Eye.rise(-0.5);;

break;

case 'a':
Eye.speed+=0.05;
break;

case 'z':
Eye.speed-=0.05;
break;

case 'r':
init();
break;

case 'g':
setup();
break;
}

}

static void specialkey(int k, int x, int y) //Responds to arrow-keys
{
switch(k)
{ // Arrow keys
case GLUT_KEY_LEFT:
Eye.turn(1.62);
break;

case GLUT_KEY_RIGHT:
Eye.turn(-1.62);
break;

case GLUT_KEY_DOWN:
Eye.twist(4.2);
break;

case GLUT_KEY_UP:
Eye.twist(-4.2);

break;
}
}

static void mouse_motion(int x, int y) //Responds to mouse-movement
{
if(keypress==0)
{
if(first==1)
{
first=0;
mousex=x;
mousey=y;
return;
}
Eye.turn(0.2*(mousex-x));
Eye.twist(0.2*(y-mousey));
mousex=x;
mousey=y;
}

}

static void mouse_button(int button, int state, int x, int y) //Responds to mouse-clicks
{
if(!button)
{ //Left-button
first=1;
keypress=state;
}

}

int main(int argc, char *argv[])
{
fprintf(stderr,"Loading…");
srand(time(0));
setup();
glEnable(GL_DEPTH_TEST);

glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

int wid=glutCreateWindow("CS3241 Lab 3 - Terrain ");
glutDisplayFunc(display);
glutReshapeFunc(reshape_callback);
glutKeyboardFunc(normalkey);
glutSpecialFunc(specialkey);
glutMouseFunc(mouse_button);
glutMotionFunc(mouse_motion);

fprintf(stderr,"\n\nCS3241 Lab 3 ");
fprintf(stderr,"\n\n<a> Increase speed");
fprintf(stderr,"\n<z> Decrease speed");
fprintf(stderr,"\n<s> Increase height ");
fprintf(stderr,"\n<x> Decrease height ");
fprintf(stderr,"\n<g> Generate terrain");
fprintf(stderr,"\n<r> Reset eye position");
fprintf(stderr,"\n<arrows> Turn view");
fprintf(stderr,"\n<escape> Exit");

T.start(wid, 35, display);
glutMainLoop();
return 0;
}


=======================================================================

I will be modifying the above code to make it my base code for my FYP

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License