8 Replies - 1814 Views - Last Post: 27 February 2011 - 02:56 PM Rate Topic: -----

#1 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Heightmap + Normals Question

Posted 26 February 2011 - 08:46 PM

I'm planning out how I would read in heightmap data and generate terrain and I feel I see a problem coming.

First off, how I plan on creating my terrain is by reading in the data from the image file into a two dimensional array, and then using that data in some nested loops. Here is the code I am envisioning:

// Imagine these variables as having been initialized...
int MAP_WIDTH;
int MAP_HEIGHT;
unsigned char HEIGHT_DATA[MAP_WIDTH + 1][MAP_HEIGHT + 1];

// create the quads that make up the terrain
for (int i = 0; i < MAP_WIDTH; i++)
{
    glBegin(GL_QUAD_STRIP);
    glVertex3f(i, HEIGHT_DATA[i][0], 0);
    glVertex3f(i + 1, HEIGHT_DATA[i + 1][0], 0);

    for (int j = 1; j < MAP_HEIGHT; j++)
    {
        glVertex3f(i, HEIGHT_DATA[i][j], j);
        glVertex3f(i + 1, HEIGHT_DATA[i + 1][j], j);
    }
    glEnd();
}



Now, what I see as being an issue is that I know when you define a GL_QUAD the order of the points matters. You want the points to be going in a counterclockwise order, but there is no way to do that when defining a strip. Are all of the normals going to be messed up and will my ground be looking all funny? If so, how do I fix this? If not, why is that?

EDIT: Noticed I forgot my glEnd() call!

This post has been edited by ghillieLEAD: 26 February 2011 - 08:49 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Heightmap + Normals Question

#2 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Heightmap + Normals Question

Posted 26 February 2011 - 10:33 PM

I wouldn't read your data into a 2D in the first instance - I would actually read it into a linear buffer and index through the buffer as is it were a 2D array, so if we were to have a 2D array like this

array2D[i][j];



in a loop, we could instead have

array2D[(i * MAX_X) + y];



Which is a linear array. Now why have it this way? It gives you cleaner code and it isn't pre-formatted into a 2D array there keeping its 'raw' data properties enabling you to process the data in a number of ways. This also should facilitate your problem. :)
Was This Post Helpful? 3
  • +
  • -

#3 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Re: Heightmap + Normals Question

Posted 26 February 2011 - 11:15 PM

Although I can see benefits to that in situations I don't get how it helps here.

Lets say I am trying to create this strip of quads:

Posted Image

When you are entering the points for the GL_QUAD_STRIP it is easy enough to see that the points should be entered in this order:

[furthest left frame of first pic]
Posted Image

After that I would think point 5 would be the low point and 6 the high point. This would mean points 1, 4, 5, and 6 would be forming the inner quad.

Where it gets hazy for me is the next quad. If the points are used in the order you have been entering them then points 5 and 6 are already going in a counter clockwise direction. Wouldn't that mean the normal would be facing in the wrong direction no matter what way you enter your points? Or does OpenGL ignore the ordering of the points being used from the previous quad and only use the ordering of the new points you are entering to determine the direction of the normal?
Was This Post Helpful? 0
  • +
  • -

#4 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,197
  • Joined: 14-February 08

Re: Heightmap + Normals Question

Posted 27 February 2011 - 04:06 AM

I think you have made a small logic error, for a start your vertices would be in this order
Attached Image

as top left would be vertex(0,0,0) which is the first value of your loop.
glVertex3f(i, HEIGHT_DATA[i][0], 0); // i = 0 at this point



plus your next value actually takes you clockwise not anti-clockwise
glVertex3f(i + 1, HEIGHT_DATA[i + 1][0], 0);


you have incremented in the x axis.

I'm gonna suggest that you use triangle strips instead of quad strips and here's the loop I would use, follow it for a few iterations :)

for (int i = 0; i < mapWidth; i++)
{
   for (int j = 0; j < mapHeight; j++)
   {
       glBegin(GL_TRIANGLE_STRIP);        
       glVertex3f(i, HEIGHT_DATA[i][j], j);            
       glVertex3f(i, HEIGHT_DATA[i][j + 1], j + 1);            
       glVertex3f(i + 1, HEIGHT_DATA[i + 1][j], j);            
       glVertex3f(i + 1, HEIGHT_DATA[i + 1][j + 1], j + 1);           
       glEnd();
   }
}



I hope that helped some :)

*Edit*
You can have your vertices in a clockwise order by using glFrontFace(GL_CW); this means that drawing your vertices in a clockwise direction will still keep them front facing.

This post has been edited by stayscrisp: 27 February 2011 - 04:26 AM

Was This Post Helpful? 3
  • +
  • -

#5 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Re: Heightmap + Normals Question

Posted 27 February 2011 - 09:00 AM

Ah yes a bit of a logic fail there. :whistling:

I still don't get how the normal is determined, especially when using the triangle strip example you gave.

I followed the order the points would be created. If I didn't screw up again it would be top left, bottom left, top right, bottom right.

The first triangle is going anti-clockwise. The second triangle is reusing the top right and bottom left points as well as the new point.

So how does OpenGL know which direction the normal should be pointing for the second triangle? If it went off the order that the reused points were entered the order would be bottom left, top right, new point. That order would be clockwise, so the normal would be facing the incorrect direction.

Does it simply go in reverse order that the points were entered, giving you the point order top right, bottom left, new point?
Was This Post Helpful? 0
  • +
  • -

#6 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,197
  • Joined: 14-February 08

Re: Heightmap + Normals Question

Posted 27 February 2011 - 09:28 AM

For your terrain you are going to have to compute your own per vertex normals to get a good smooth lighting effect. I would think that in the case of the triangle strips OpenGL would calculate the normal per face and therefore an average of the normals of the 3 points would be computed.

In the case of the second triangle, since it is sharing 2 front facing vertex normals then it would be computed as a front facing triangle and so on.
Was This Post Helpful? 1
  • +
  • -

#7 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Re: Heightmap + Normals Question

Posted 27 February 2011 - 09:43 AM

Oh, that makes sense. Thanks.
Was This Post Helpful? 0
  • +
  • -

#8 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,197
  • Joined: 14-February 08

Re: Heightmap + Normals Question

Posted 27 February 2011 - 10:20 AM

I would also recommend that you take 's advice and look into vertex buffers, this will greatly speed up your terrain rendering and is pretty much the de facto way of doing this kind of thing.
Was This Post Helpful? 0
  • +
  • -

#9 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Re: Heightmap + Normals Question

Posted 27 February 2011 - 02:56 PM

I did. I also want to post here a website I found for people who may stumble across this thread looking for help on loading/creating terrain.

http://www.lighthous...hp?introduction
Was This Post Helpful? 2
  • +
  • -

Page 1 of 1