OpenGL: optimal way to draw environment from height array?

danglingPointer picture danglingPointer · Apr 15, 2014 · Viewed 9.3k times · Source

So I am writing a openGL program with height-mapping to make a 3D out-door environment. As with all height-mapping each point is the same distance from its neighbor in the x&z axis, but the y axis differs for each vertex depending on the heightmap read in by the program.

So far I my program stores reads in the heightmap and stores in an array of y-heights equal in size to (image_width)*(image_height). My question is, what is the most efficient way to draw the environment of quads given this data?

I would think that using glDrawArrays in some way is the answer, but no mode would work with the given data initially. For example, I could use GL_TRIANGLE_STRIP if my data array alternated between rows and if I stopped each strip at the end of a column, however this would require the data array sent into glDrawArrays to store values from each row multiple times. It would also require an array to be x3 in size from my initial array considering the initial array only stores the y-value. But surely specifying each quad every frame given the data would not be efficient at all?

Answer

stridecolossus picture stridecolossus · Apr 15, 2014

The simplest (though not necessarily most efficient in terms of speed or memory) is to generate two triangles for each quad and upload that to the GPU as a single VBO.

As you pointed out though this till means you essentially have three times the amount of data compared to the height-map itself. (An index buffer should be used so there are no duplicate vertices).

This is a good tutorial IMHO covering this approach: http://3dgep.com/?p=1116

Another method is to use triangle-strips and link each row of the terrain using degenerate triangles so that you only have one draw call. Still has the memory overhead though.

Depending on how proficient you are with OpenGL (and how modern your graphics card is) you could look at tesselation shaders which get around the above problems by using the height-map 'texture' directly:

http://codeflow.org/entries/2010/nov/07/opengl-4-tessellation/