Jump to content
  • Advertisement
Sign in to follow this  
NickyP101

OpenGL Terrain Rendering Issue

This topic is 4888 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Good evening everyone :) Ive just had my first attempt at creating a terrain from a height map (image). I guess its not terrible haha but it not how it should be. Im using OpenGL and Triangle Strips. Here is a screen shot of my terrain looking down on it: So hopefully u can see the liny effect im getting. Below is the code i use for building the terrain. Its not too long so dont be worried :)

public class TerrainBuilder
{

    
    public TerrainBuilder()
    {

    }
    
    public int createDisplayList(String mapFile, GL11 gl){
        
        int dL = 0;
        
        int width = getImageWidth(mapFile);
        int height = getImageHeight(mapFile);
        
        int heightMap[][] = loadMap(mapFile, width, height);

        
        dL = gl.glGenLists(1);
        
        gl.glNewList(dL, gl.GL_COMPILE);   
        

            for(int y = 0; y < height - 2; y++){
                    
                    gl.glBegin(gl.GL_TRIANGLE_STRIP);
                    
                    for(int x = 0; x < width; x++){
                        
                        float xV = x * 2;
                        float yV = (float)(heightMap[y][x]);
                        float zV = -1 * y * 1;
                        
                        float xV1 = x * 2;
                        float yV1 = (float)(heightMap[y + 1][x] );
                        float zV1 = -1 * (y + 1) * 1;
    
                        float vx = yV * zV1 - zV * yV1;
        
                        float vy = zV * xV1 - xV * zV1;
        
                        float vz = xV * yV1 - yV * xV1;
                        
                        float i = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
                        
                        if(yV < 0 || yV1 < 0){
                            System.out.println("Bellow 0 Y at: " + x + ", " + y);
                        }
                        
                        vx = vx / i;
                        vy = vy / i;
                        vz = vz / i;
                        
                        
                        gl.glNormal3f(vx, vy, vz);
            

                        gl.glTexCoord2f(0.0f, 1.0f);
                        gl.glVertex3f(xV, yV, zV);
                        
                        
                        float nx1 = x * 2;
                        float ny1 = (float)(heightMap[y + 1][x]);
                        float nz1 = -1 * (y + 1) * 1;
                        
                        float nx2 = (x + 1) * 2;
                        float ny2 = (float)(heightMap[y + 2][x]);
                        float nz2 = -1 * (y + 2) * 1;
    
                        vx = ny1 * nz2 - nz1 * ny2;
        
                        vy = nz1 * nx2 - nx1 * nz2;
        
                        vz = nx1 * ny2 - ny1 * nx2;
                        
                        i = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
                        
                        vx = vx / i;
                        vy = vy / i;
                        vz = vz / i;
                        
                        gl.glNormal3f(vx, vy, vz);
                        
                        
                        
                        gl.glTexCoord2f(0.0f, 0.0f);
                        gl.glVertex3f(xV1, yV1, zV1);
                        
                    }
                    
                    gl.glEnd();
                    
            }
                        
        gl.glEndList(); 
        
        return dL;
        
    }
    
    public int getImageHeight(String file){
        
        int height = new ImageIcon(file).getIconHeight();
        
        return height;
        
    }
    
    public int getImageWidth(String file){
        
        int width = new ImageIcon(file).getIconWidth();
        
        return width;
        
    }
        
        
    
    public int[][] loadMap(String fileName, int width, int height){
        
        //Scale 0 - 15
        
        Image mapImg = new ImageIcon(fileName).getImage();
        int heightMap[][] = new int[height][width];
        
        BufferedImage map = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = map.createGraphics();
        
        Color color = new Color(map.getRGB(0,0));
        float greyScale = (float)(0.30 * color.getRed() + 0.59 * color.getGreen() + 0.11 * color.getBlue());
        
        float min = greyScale;
        float max = greyScale;
        
        g.drawImage(mapImg, 0, 0, null);
        
        for(int y = 0; y < height; y++){
            for(int x = 0; x < width; x++){
                
                color = new Color(map.getRGB(x,y));
        
                greyScale = (float)(0.30 * color.getRed() + 0.59 * color.getGreen() + 0.11 * color.getBlue());
                
                if(greyScale < min){
                    min = greyScale;
                }
                if(greyScale > max){
                    max = greyScale;
                }
                
                
                heightMap[y][x] = (int)greyScale;
                
            }
        }
        
        System.out.println("Min: " + min + ", Max: " + max);
        
        float diff = max - min;
        float scaleSec = diff / 25;
        
        System.out.println("Scale Sections: " + scaleSec);
        
        for(int y = 0; y < height; y++){
            for(int x = 0; x < width; x++){
                
                heightMap[y][x] = (int)(heightMap[y][x] / scaleSec);
                
            }
        }
        return heightMap;
    }
    
    


}


So yes, im using Java and LWJGL. Im guess the reason i am getting that liney effect is because i may be using the triangle strips incorrectly? Thats just my only thought on wat could be incorrect with my terrain. Im building the terrain with this height map: Any help would be greatly appreciated, Cheers, Nick!!!

Share this post


Link to post
Share on other sites
Advertisement
Are you sure everyting is in order with the image format etc? If you are unsure, try saving the map as a grayscale.

Share this post


Link to post
Share on other sites
hi,

hmm I would bet on a lighting problem. If you try to concentrate on the height, it seems to be continous, So I think there's nothing wrond with the strips iteslf. But the bottom line of vertices in a strip is always black, and I'm pretty sure you made a mistake when you compute the normal of one of the 2 vertex (inside the drawStrip loop)

[edit]
I tried to understand the code that compute the normal, but I don't understand anything, although I compute normals from a heightfield in my engine ^^
And after more looking of your screenshots, most normals seem wrong.

To compute the normals, you need to take at least 3 points in your heightfiel, but in your code, you only take 2 ...

if you want the normal of vertex[x][y], its as follow :


vertex1 = vector3(x * 2, heightMap[x][y], y * 2);
vertex2 = vector3((x + 1) * 2, heightMap[x + 1][y], y * 2);
vertex3 = vector3(x * 2, heightMap[x][y + 1], (y + 1) * 2);
edge1 = vertex2 - vertex1;
edge2 = vertex3 - vertex1;
normal = normalize(crossProduct(edge1, edge2);



I use pseudo functions to make the understanding simpler. Try that, I really think the problem is with the lighting.

One way to check : disable lighting and siwtch to wireframe display

[/edit]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Nick,

Thanks for your replies, just a quick question, how do u switch to wireframe?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Nick,

Thanks for your replies, just a quick question, how do u switch to wireframe?

Share this post


Link to post
Share on other sites
arg, I didn't realize that you're probably in OpenGL ^^'
in DirectX, it's just a d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); but in OpenGL, you can't (as far as I remember ... didn't code in OpenGL since a looooonng time ^^)

Well, at least, to check if your grid is well drawn (no error in the vertices position, replace the loop that draw the strips by a loop that simply draw the vertices (gl.glBegin(gl.GL_POINT_LIST); or similar) This way, you can see if your vertices are well placed. If it's the case (I believe it is) then, the problem clearly comes from the lighting. So, you'll have to correct the code that compute the normals ^^

Share this post


Link to post
Share on other sites
Ok here is a screen from the wireframe view, thanks for the tip btw:



To me it looks like a lighting problem, as suggested by others above, but before i look into the normals can anyone just approve of the diagnosis?

Cheers, Nick :)

Share this post


Link to post
Share on other sites
Your texture coordinates are fixed numbers ... and not only that, I only see 0,0 and 0,1 in the code. Neither of these can be right, surely? . . . try disabling textures and rendering it, so that you know for sure it is lighting and not the thing being lit . . .

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!