| IntroductionNOTE: For the HTML version of
| |
| | below, the code for generating and
|
| this article with graphics and downloads
| |
| | rendering the terrain is very short. To
|
| please visit the following link: have
| |
| | give an overview, the first thing that
|
| always been interested in computer
| |
| | happens is for the windows to get
|
| graphics and their applications. Data
| |
| | created, and then we initialize OpenGL,
|
| representation and visualization is one
| |
| | and read in the BMP file and assign it to
|
| of the main areas of HCI (Human Computer
| |
| | the 2D array we discussed above. Then,
|
| Interaction), and the better you make the
| |
| | the texture is applied to the surface of
|
| interaction between a machine and a
| |
| | the mesh, and the scene rendered to the
|
| human, the more productivity will be
| |
| | screen.Without further ado, the following
|
| generated by both the human and the
| |
| | listing is the the portion of the code
|
| machine. I had some experience with
| |
| | which initializes and generates the
|
| OpenGL during my undergraduate studies
| |
| | terrain:.
|
| while attending the California
| |
| | .
|
| Polytechnic University. Unfortunately, I
| |
| | .
|
| never got a chance to pursue the more
| |
| | // InitializeTerrain()
|
| advanced features of the OpenGL library,
| |
| | // desc: initializes the heightfield
|
| given my time and work
| |
| | terrain data
|
| responsibilities.You can find more about
| |
| | void InitializeTerrain()
|
| OpenGL at There are also a bunch of good
| |
| | {// loop through all of the heightfield
|
| literature available on the topic of
| |
| | points, calculating// the coordinates for
|
| Computer Graphics and OpenGL that you can
| |
| | each pointfor (int z = 0; z < MAP_Z;
|
| refer for further advancements. Please
| |
| | z++){for (int x = 0; x < MAP_X;
|
| check the Background/Reference section
| |
| | x++){terrain[x][z][0] =
|
| for a list of some reference material
| |
| | float(x)*MAP_SCALE;terrain[x][z][1] =
|
| that I have used, in general, for
| |
| | (float)imageData[(z*MAP_Z+x)*3];terrain[x
|
| computer graphics.The following project
| |
| | ][z][2] = -float(z)*MAP_SCALE;}}
|
| is a very simple example demonstrating
| |
| | }
|
| how to generate a terrain based on a
| |
| | .
|
| bitmap file. The objective of the project
| |
| | .
|
| is to generate a three dimensional
| |
| | .
|
| terrain based on some data file. Please
| |
| | The code above is the implementation of
|
| note, that this could have been any data
| |
| | what we discussed about applying
|
| file, but for the purpose of our example,
| |
| | MAP_SCALE, which allows us to scale the
|
| we are going to be using a 32x32
| |
| | terrain to our likings. So, it basically
|
| dimensional bitmap file. We could have
| |
| | assigns the vertex coordinates for each
|
| easily used a text file, and defined
| |
| | grid location, the MAP_SCALE factor,
|
| logic for each word or letter to
| |
| | which is multiplying it with the grid
|
| represent it graphically.The project also
| |
| | location index based on the coordinate
|
| contains a good Windows framework that
| |
| | element. It extends along the X and
|
| can be used for your other OpenGL
| |
| | Z-axis, with the Y-Axis representing the
|
| applications. The current project allows
| |
| | terrain height.The function is called
|
| you to rotate the camera using your
| |
| | after the bitmap has been loaded into the
|
| mouse.Once again, this is a simple
| |
| | memory from the Initialize() function..
|
| approach to terrain generation, which can
| |
| | .
|
| be a very difficult task in complex
| |
| | .
|
| environments.Background/Reference
| |
| | // Render
|
| Since Computer Graphics is kind of an
| |
| | // desc: handles drawing of scene
|
| advanced topic, it is necessary to have
| |
| | void Render()
|
| at least some king of understanding and
| |
| | {radians = float(PI*(angle-90.0f)
|
| exposure to the concepts and theories in
| |
| | 180.0f);// calculate the camera's
|
| the field. However, this does not mean
| |
| | position// multiplying by mouseY makes
|
| that you will not be able to use the
| |
| | the// camera get closer/farther away with
|
| following code or understand it. I have
| |
| | mouseYcameraX = lookX +
|
| made it as simple as possible, and
| |
| | sin(radians)*mouseY;cameraZ = lookZ +
|
| hopefully, it will give you a good start,
| |
| | cos(radians)*mouseY;cameraY = lookY +
|
| or some additional source of information
| |
| | mouseY / 2.0f;// calculate the camera
|
| that you can use for your projects. Also,
| |
| | look-at coordinates// as the center of
|
| please note that you will need to have a
| |
| | the terrain maplookX = (MAP_X*MAP_SCALE)
|
| good understanding of C/C++
| |
| | 2.0f;lookY = 150.0f;lookZ =
|
| programming.Some books I have used for
| |
| | -(MAP_Z*MAP_SCALE)/2.0f;// clear screen
|
| learning Computer Graphics and OpenGL
| |
| | and depth
|
| programming:Books I used while attending
| |
| | bufferglClear(GL_COLOR_BUFFER_BIT |
|
| the California Polytechnic University:
| |
| | GL_DEPTH_BUFFER_BIT);glLoadIdentity();//
|
| OpenGL Programming Guide, or better know
| |
| | set the camera positiongluLookAt(cameraX,
|
| as the Red Book.
| |
| | cameraY, cameraZ,lookX, lookY, lookZ,
|
| Computer Graphics Using OpenGL, 2nd
| |
| | 0.0, 1.0, 0.0);// set the current texture
|
| Edition.
| |
| | to the land
|
| Books I used while attending the
| |
| | textureglBindTexture(GL_TEXTURE_2D,
|
| California Lutheran University:
| |
| | land);// we are going to loop through all
|
| OpenGL: A Premier, 2nd Edition.
| |
| | / of our terrain's data points,// but we
|
| Interactive Computer Graphics: A
| |
| | only want to draw one triangle// strip
|
| Top-Down Approach Using OpenGL, 4th
| |
| | for each set along the x-axis.for (int z
|
| Edition.What is a Terrain?
| |
| | = 0; z < MAP_Z-1;
|
| Some background information on a terrain
| |
| | z++){glBegin(GL_TRIANGLE_STRIP);for (int
|
| and their uses in a game application: A
| |
| | x = 0; x < MAP_X-1; x++){// for each
|
| terrain in an environment is one of the
| |
| | vertex, we calculate// the grayscale
|
| most critical components in the scene
| |
| | shade color,// we set the texture
|
| that is being rendered. It could easily
| |
| | coordinate,// and we draw the vertex.//
|
| be the largest 3D object in the project.
| |
| | draw vertex 0glColor3f(terrain[x][z][1]
|
| Rendering the terrain can become a
| |
| | 255.0f,terrain[x][z][1]
|
| daunting task, taking the most time to
| |
| | 255.0f,terrain[x][z][1]
|
| render in a scene. To keep the terrain
| |
| | 255.0f);glTexCoord2f(0.0f,
|
| engine running in real time can be a
| |
| | 0.0f);glVertex3f(terrain[x][z][0],terrain
|
| difficult task, and it requires some
| |
| | [x][z][1], terrain[x][z][2]);// draw
|
| thought out processes and modeling for it
| |
| | vertex 1glTexCoord2f(1.0f,
|
| to be sufficient.To be effective, the
| |
| | 0.0f);glColor3f(terrain[x+1][z][1]
|
| terrain needs to meet a number of
| |
| | 255.0f,terrain[x+1][z][1]
|
| requirements, many of which can be
| |
| | 255.0f,terrain[x+1][z][1]
|
| contradicting each other. A terrain
| |
| | 255.0f);glVertex3f(terrain[x+1][z][0],
|
| should appear to be continuous to the end
| |
| | terrain[x+1][z][1],terrain[x+1][z][2]);//
|
| user, yet the mesh should be simplified
| |
| | draw vertex 2glTexCoord2f(0.0f,
|
| or culled where possible, to reduce the
| |
| | 1.0f);glColor3f(terrain[x][z+1][1]
|
| load on the graphics card.In a gaming
| |
| | 255.0f,terrain[x][z+1][1]
|
| system, for example, some engines draw
| |
| | 255.0f,terrain[x][z+1][1]
|
| the terrain just beyond the point a
| |
| | 255.0f);glVertex3f(terrain[x][z+1][0],
|
| player can reach, and then use a terrain
| |
| | terrain[x][z+1][1],terrain[x][z+1][2]);//
|
| drawn onto a skybox to simulate hills or
| |
| | draw vertex
|
| mountains in the distance. The terrain
| |
| | 3glColor3f(terrain[x+1][z+1][1]
|
| should appear realistic to the setting
| |
| | 255.0f,terrain[x+1][z+1][1]
|
| for the environment, yet this can be
| |
| | 255.0f,terrain[x+1][z+1][1]
|
| taxing on the video card, and a balance
| |
| | 255.0f);glTexCoord2f(1.0f,
|
| needs to be maintained. Detail textures
| |
| | 1.0f);glVertex3f(terrain[x+1][z+1][0],ter
|
| are often used close to the camera,
| |
| | rain[x+1][z+1][1],terrain[x+1][z+1][2]);}
|
| allowing the areas further off to be
| |
| | glEnd();}// enable
|
| rendered more quickly.What is a Height
| |
| | blendingglEnable(GL_BLEND);// enable
|
| Map?
| |
| | read-only depth
|
| The first thing required for terrain
| |
| | bufferglDepthMask(GL_FALSE);// set the
|
| rendering is a representation of the
| |
| | blend function// to what we use for
|
| terrain's shape. While there are a number
| |
| | transparencyglBlendFunc(GL_SRC_ALPHA,
|
| of structures that can be used to perform
| |
| | GL_ONE);// set back to normal depth
|
| the job, the most widely used is the
| |
| | buffer mode
|
| height map. Others include: NURBS, which
| |
| | (writable)glDepthMask(GL_TRUE);// disable
|
| can be maintained through a number of
| |
| | blendingglDisable(GL_BLEND);glFlush();//
|
| control points, and voxels, which allow
| |
| | bring backbuffer to
|
| for overhangs and caves.There is one
| |
| | foregroundSwapBuffers(g_HDC);
|
| drawback to a height map, and that is,
| |
| | }
|
| for every point on the XZ-plane, there
| |
| | .
|
| can only be one height value. You can see
| |
| | .
|
| that this limits the representation of
| |
| | .
|
| overhangs and caves by a height map. This
| |
| | The first thing you see in the Render()
|
| can be overcome by using two separate
| |
| | function is the conversion of the angle
|
| models.Another drawback is that height
| |
| | into radians, by using the formula:
|
| maps take a large amount of memory, as
| |
| | radians = float(PI*(angle-90.0f)
|
| each height must be represented. On the
| |
| | 180.0f);. This makes it easier to compute
|
| other hand, height maps lend themselves
| |
| | the cameraX, cameraY, and cameraZ
|
| to the creation of regular meshes easily.
| |
| | positions using the sin() and cos()
|
| It is also easy to determine the height
| |
| | functions.The next block of code sets the
|
| at any given location, which is useful
| |
| | look-at coordinates of the camera at the
|
| for collision against the terrain as well
| |
| | center of the terrain. Then, we clear the
|
| as laying dynamic shadows onto the
| |
| | screen and depth buffer using
|
| terrain.A height map is represented by a
| |
| | glClear(GL_COLOR_BUFFER_BIT |
|
| 2D array of values, where for any point
| |
| | GL_DEPTH_BUFFER_BIT);. We set the camera
|
| (X, Y, Z), the X and Z are the indexes
| |
| | position based on the camera (X, Y, Z)
|
| into the array, and the value of the
| |
| | values and the look-at we computed.We
|
| array is the Y value which is equivalent
| |
| | then bind the texture using the
|
| to the height value.The following is an
| |
| | glBindTexture(GL_TEXTURE_2D, texture);
|
| example of such a representation:int
| |
| | function. This tells OpenGL that we are
|
| height[5][5] ={
| |
| | going to use that particular texture to
|
| { 0, 0, 1, 1, 2 },
| |
| | apply to our surfaces that will be
|
| { 0, 1, 2, 2, 3 },
| |
| | drawn.So far, all the code was just to
|
| { 0, 1, 3, 2, 3 },
| |
| | setup the camera position and bind the
|
| { 0, 1, 2, 1, 2 },
| |
| | texture, the next block of code is what
|
| { 0, 0, 1, 1, 1 } };The Approach!
| |
| | actually draws the terrain and applies
|
| There are many advanced algorithms to
| |
| | the texture to the surface. We have two
|
| generate terrains; I am using a very
| |
| | for loops which go through the 2D array
|
| simple solution for the purpose of this
| |
| | we have created that stores the terrain
|
| project.In a nutshell, I used a 32 x 32
| |
| | data, and as we discussed earlier, we
|
| grayscale bitmap to represent a
| |
| | process four vertices at a time. In the
|
| height-field that is used to generate the
| |
| | process, we calculate the grayscale shade
|
| terrain. The terrain itself is divided
| |
| | color, we set the texture, and then we
|
| into a grid of height values, the result
| |
| | draw the vertex.That is pretty much all
|
| of which is a mesh representing the
| |
| | you need to do to generate a terrain,
|
| terrain in the scene.We create a grid of
| |
| | given a 24-bit bitmap file.Points of
|
| vertices that are spaced evenly apart but
| |
| | Interest
|
| have varying heights, based on the
| |
| | If you are reading this, you most likely
|
| height-field data. The color value of
| |
| | are interested in computer graphics and
|
| each bit is used to determine the height
| |
| | want to learn more about the techniques
|
| value of each grid location; in this
| |
| | available to do really cool stuff.
|
| case, for a 24-bit grayscale bitmap, the
| |
| | Computer graphics can be very complex in
|
| values for the color range from 0 to
| |
| | theory, but thanks to libraries such as
|
| 255.Once the bitmap has been read and the
| |
| | OpenGL, the implementation of complex
|
| values loaded in memory, we have the data
| |
| | models/scenes can be done easily. Upon
|
| needed to represent the terrain. We also
| |
| | writing this article, I got the latest
|
| use a variable called a MAP_SCALE to
| |
| | issue of Dr. Dobb's Journal (June 2006,
|
| allow us to scale the map up or down.
| |
| | Issue No. 385), and to my surprise, there
|
| This is a scale factor; we use this to
| |
| | is an article about OpenGL and Mobile
|
| set the distance between each height
| |
| | Devices. It is under the name of OpenGL
|
| vertex. This allows us to increase or
| |
| | ES and it is a subset of OpenGL 1.3. That
|
| decrease the size of the terrain.When we
| |
| | will make it possible to do real time 3D
|
| actually assign the vertex coordinates
| |
| | graphics on hand-held devices. Imagine
|
| for each grid location, we need to apply
| |
| | the kind of nice looking applications
|
| the MAP_SCALE factor, which is
| |
| | games that can be developed for your PDA
|
| multiplying it with the grid location
| |
| | or cell phones! Not all the functionality
|
| index based on the coordinate element,
| |
| | is available due to the limitations of
|
| i.e.:Terrain[X][Z][0] =
| |
| | the hand-held hardware. But I assume, in
|
| Float(X)*MAP_SCALE;
| |
| | the near term future, you will be able to
|
| Terrain[X][Z][1] = (float)
| |
| | create as fascinating graphics on the
|
| imageData[(Z*MAP_SCALE+X)*3];
| |
| | handhelds as you can on your regular
|
| Terrain[X][Z][2] = Float(Z)*MAP_SCALE;
| |
| | desktop machines.On another note, I am
|
| The terrain map is represented in a grid
| |
| | going to start working on a new article
|
| of height values, which is internally
| |
| | which will describe the
|
| stored in a 2D array of vertex
| |
| | LoadBitmapFile(char *filename,
|
| coordinates. It extends along the X and
| |
| | BITMAPINFOHEADER *bitmapInfoHeader)
|
| Z-axis, with the Y-Axis representing the
| |
| | function. I am looking forward to hearing
|
| terrain height.To render the terrain map,
| |
| | your comments and input, for future
|
| we use GL_TRIANGLE_STRIP for each row of
| |
| | articles.About Vahe KaramianI have been
|
| grid values along the Z-axis. To render
| |
| | programming since the age of 15. Started
|
| the terrain correctly, we need to specify
| |
| | with BASIC on Apple II computers then
|
| the point in a specific order.This
| |
| | moved on to Pascal. I wrote the game of
|
| requires us to start at the end of the
| |
| | Tetris using both languages on Apple II.
|
| row and move along the positive X-axis by
| |
| | At the age of 16 I got my first computer,
|
| drawing the vertices in a Z
| |
| | and I started transferring the code over
|
| pattern:(*)==========>(*)///////////
| |
| | to Quick Basic. I then moved into C/C++
|
| (*)=========>(*) ....Using the Code
| |
| | and have been developing in C/C++ until
|
| I will only list the code that deals
| |
| | about 2 years ago when I switched over to
|
| with the terrain generation here. There
| |
| | C#.My interests are in the field of
|
| is more code in the project that you can
| |
| | Computer Graphics and Computer Vision. I
|
| look at. It is well documented, so you
| |
| | am working on my graduate degree
|
| shouldn't have any problems. The solution
| |
| | emphasizing on Computer Vision. I will
|
| was compiled using MS Visual Studio 2003,
| |
| | try to be writing more articles in this
|
| so you should be able to compile and run
| |
| | field for future submissions.Currently I
|
| it easily. You will need to have the
| |
| | am employed at a BioTech company in
|
| OpenGL libraries and DLL, which I will
| |
| | California, and I work on interesting
|
| also provide as a download option just in
| |
| | projects ranging in many areas, except
|
| case you do not have them. Make life a
| |
| | Computer Vision Hence my
|
| little easier so you do not have to
| |
| | graduate emphasis on the subject.You can
|
| search for them online.So the majority of
| |
| | find more C/C++ samples on my site. There
|
| the code is for preparing the windows to
| |
| | is a lot of good code for undergraduate
|
| render the scene properly. As you can see
| |
| | Computer Science students.
|