Landscape Terrain Using JOGL

Posted: January 9, 2010 in Game Programming
Tags: , ,

Terrain, is very common in video game to create realistic environment. in this article, for generating terrain, i ued heighmap technique. jOGL is intereresting port of OpenGL in Java Environtment.

Heightmap is a simple 2D images formed by black, white, and 254 kinds of gray. Gradient gray color represents the difference in height. The brighter the color, the higher terrainnya. Each color has a gradation of height differences in the size of meters, which vary based on programs that take pictures. The advantages of this heightmap is easy to make, easy to make changes in large-scale, rapid iteration time, and realistic.

The disadvantage is difficult to make changes in small scale, requires a lot of time to fix it, and produce similar terrain heightmap others.

IMPLEMENTATION

Skysphere

Sphere is a geometric object that perfect round shape in three-dimensional space like a perfectly round circle in three-dimensional space. Sphere completely symmetrical around the center, with all points of distance equal to r at the center point. Implementation sphere what this application is to use the GLUT function gluSphere (). gluSphere pulled a ball of radius given by centered around the origin.

private void drawSky()
{
        Vector3 camPosition = camera.getCameraPosition();
        _gl.glBindTexture(GL.GL_TEXTURE_2D, skyTexture);
        enableCullingMode(false);

        // draw upper sphere
        _gl.glPushMatrix(); // save state
        _gl.glRotatef(-91.7f, 1.0f, 0.0f, 0.0f);
        _gl.glRotatef(skyMovCounter, 0.0f, 0.0f, 1.0f);
        _gl.glTranslatef(camPosition.X, camPosition.Y, camPosition.Z - MAP_SIZE * scaleValue * 0.5f);
        double[] clipPlane1 = {0.0f, 0.0f, 1.0f, 0.5f};
        _gl.glClipPlane(GL.GL_CLIP_PLANE1, clipPlane1, 0);
        _gl.glEnable(GL.GL_CLIP_PLANE1);
        glu.gluSphere(quadric, 5000, 50, 5);
        _gl.glDisable(GL.GL_CLIP_PLANE1);
        _gl.glPopMatrix();  // restore state

        // draw bottom sphere
        _gl.glPushMatrix(); // save state
        _gl.glRotatef(-91.7f, 1.0f, 0.0f, 0.0f);
        _gl.glTranslatef(camPosition.X, camPosition.Y, camPosition.Z - MAP_SIZE * scaleValue * 0.5f);
        double[] clipPlane2 = {0.0f, 0.0f, -1.0f, 0.5f};
        _gl.glClipPlane(GL.GL_CLIP_PLANE2, clipPlane2, 0);
        _gl.glEnable(GL.GL_CLIP_PLANE2);
        glu.gluSphere(quadric, 5000, 50, 5);
        _gl.glDisable(GL.GL_CLIP_PLANE2);
        _gl.glPopMatrix();  // restore state

        skyMovCounter += 0.2f;  // add rotation angle
}

Clipping

In rendering, clipping is useful to cut the viewing volume. So that part does not want to ditampulkan be eliminated thereby increasing efficiency and performance.

_gl.glPushMatrix(); // save state
_gl.glRotatef(-91.7f, 1.0f, 0.0f, 0.0f);
_gl.glRotatef(skyMovCounter, 0.0f, 0.0f, 1.0f);
_gl.glTranslatef(camPosition.X, camPosition.Y, camPosition.Z - MAP_SIZE * scaleValue * 0.5f);
double[] clipPlane1 = {0.0f, 0.0f, 1.0f, 0.5f};
_gl.glClipPlane(GL.GL_CLIP_PLANE1, clipPlane1, 0);
_gl.glEnable(GL.GL_CLIP_PLANE1);
glu.gluSphere(quadric, 5000, 50, 5);
_gl.glDisable(GL.GL_CLIP_PLANE1);
_gl.glPopMatrix();  // restore state

Culling

In computer graphics, culling is a method for determining whether a graphical object visible. This is a step in the graphics pipeline used to test whether the points in a polygon appear in clockwise or counterclockwise in order to be seen when projected onto a screen. Culling process makes rendering faster and more efficient by reducing the number of polygons that must be drawn.

private void enableCullingMode(boolean value)
    {
        if(value)
        {
            _gl.glCullFace(_gl.GL_BACK);
            _gl.glEnable(_gl.GL_CULL_FACE);
            _gl.glFrontFace(_gl.GL_CCW);
        }
        else
            _gl.glDisable(_gl.GL_CULL_FACE);
    }

Terrain

This is code for generating terrain

private void renderHeightMap(GL gl, byte[] pHeightMap)
{
        if(renderType == RenderType.LINE)
            gl.glBegin(gl.GL_LINES);
        else
            gl.glBegin(gl.GL_QUADS);

        for (int X = 0; X < (MAP_SIZE - STEP_SIZE); X += STEP_SIZE)
            for (int Y = 0; Y < (MAP_SIZE - STEP_SIZE); Y += STEP_SIZE)
            {
                // downleft vertex
                int x = X;
                int y = height(pHeightMap, X, Y);
                int z = Y;
                if(renderType == RenderType.TEXTURED)
                    gl.glTexCoord2f((float)x / (float)MAP_SIZE, (float)z / (float)MAP_SIZE);  // kalau pakai tekstur
                else
                    setVertexColor(gl, pHeightMap, x, z);   // kalau tanpda tekstur
                gl.glVertex3i(x, y, z);

                // upleft vertex
                x = X;
                y = height(pHeightMap, X, Y + STEP_SIZE);
                z = Y + STEP_SIZE;
                if(renderType == RenderType.TEXTURED)
                    gl.glTexCoord2f((float)x / (float)MAP_SIZE, (float)(z + 1) / (float)MAP_SIZE);
                else
                    setVertexColor(gl, pHeightMap, x, z);
                gl.glVertex3i(x, y, z);

                // upright vertex
                x = X + STEP_SIZE;
                y = height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE);
                z = Y + STEP_SIZE;
                if(renderType == RenderType.TEXTURED)
                    gl.glTexCoord2f((float)(x + 1) / (float)MAP_SIZE, (float)(z + 1) / (float)MAP_SIZE);
                else
                    setVertexColor(gl, pHeightMap, x, z);
                gl.glVertex3i(x, y, z);

                // downright vertex
                x = X + STEP_SIZE;
                y = height(pHeightMap, X + STEP_SIZE, Y);
                z = Y;
                if(renderType == RenderType.TEXTURED)
                    gl.glTexCoord2f((float)(x + 1) / (float)MAP_SIZE, (float)z / (float)MAP_SIZE);
                else
                    setVertexColor(gl, pHeightMap, x, z);
                gl.glVertex3i(x, y, z);
            }

        gl.glEnd();
        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // reset
}

Texture Mapping

Final Project In this group we use three methods to texture mapping. All three methods are:
a) Nearest Filtered
Is a way giving the most rapid texture. The concept is to give texture to the color Texel closest to the image pixel position is used as a source texture. But the results are not too good because it provides a significant amount of aliasing.
b) Linear Filtered
Linear Filtered taking color interpolation by looking at the colors of the closest and then calculates the ratio based on the position of the point that will be textured to linear interpolation of the source texture
c) Mipmapping
Mipmapping is a good way to giving texture. With this method, the texture can be produced by quite well with the excess in the event of reduction in the dimensions of the fields be textured because mipmapping modeled as a square with 4 parts, Red; Green; Blue; and similar square smaller (recursively).

// Nearest Filtered Texture
_gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
makeRGBTexture(_gl, glu, texture, GL.GL_TEXTURE_2D, false);

// Linear Filtered Texture
_gl.glBindTexture(GL.GL_TEXTURE_2D, textures[1]);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
makeRGBTexture(_gl, glu, texture, GL.GL_TEXTURE_2D, false);

// Mipmapped Texture
_gl.glBindTexture(GL.GL_TEXTURE_2D, textures[2]);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
_gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
makeRGBTexture(_gl, glu, texture, GL.GL_TEXTURE_2D, true);

for download the code (i’m using netbeans) :
HeightmapTerrain.zip

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s