A (simple) terrain engine - day 6
Introduction
In the last days of work I’ve merged the 3D engine with the Perlin Noise generator, now I can see a new 3D terrain just pressing a key, so cool!
The current version of the program is quite “rough”, mostly because the program is more a proof of concept than a real application, so I’m not wasting many time thinking about how to manage everything, all you’re going to read above it’s just a description of how the things are at the moment and not a guide about how things should be in a “perfect” engine.
The generation Process
In order to get a textured terrain I’ve created a kind of “generation pipeline”, the main steps are the following:
- the heightmap is generated by the Perlin Noise shader
- the texture is normalized by the normalization shader
- the height values are dumped from the texture and stored in the array passed to the 3D rendering function
- the color texture is generated by the procedural texture generation shader
Everything is done using a single Ping-Pong Texture (a couple of texture attached to a FBO).
Computation and Visualization
Using the same program for GPGPU computing and for 3D visualization requires a bit of code to manage the change from one status to the other one. Above there are the two methods I’ve added to the Screen class to accomplish this change.
The first one is called before the GPGPU phase:
void graphic::Screen::StartComputationMode(GLint w, GLint h)
{
glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, w, h, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, w, h);
}
the main purpose of this method is setting the orthogonal projection and disabling everything that can interfere with the computation, furthermore it updates the viewport to the texture dimension.
It’s important to notice how all the changes are made after matrix pushes, that means it’s possible to restore the GL context just with a couple of matrix pops, like showed in the following method:
void graphic::Screen::EndComputationMode()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glViewport(0, 0, _width, _height);
glPopAttrib();
}
After this method is called, the visualization can restart with no problems.
























































