• Advertisement
Sign in to follow this  

Terrain rendering slowdown.

This topic is 3734 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

I'm calling the following method for each tile of a 64x64 terrain grid onscreen, and I'm finding that each call takes the equivalent of about 10,000 clock cycles.  Clearly, I must be doing something wrong.

    protected void renderTo(Viewer v, GL rGL) {
      
      currTex = type.texture;
      currUV = UV[1][1];
      currTex.bindTex(rGL);
      rGL.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, WHITE, 0);
      rGL.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, WHITE, 0);
      rGL.glMaterialfv(GL.GL_FRONT, GL.GL_EMISSION, BLACK, 0);
      rGL.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, BLACK, 0);
      rGL.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, 0);
      
      rGL.glTexCoordPointer(2, GL.GL_FLOAT, 0, currUV);
      rGL.glVertexPointer(3, GL.GL_FLOAT, 0, vertB);
      rGL.glNormalPointer(GL.GL_FLOAT, 0, normB);
      
      rGL.glDrawArrays(GL.GL_TRIANGLES, 0, 12);
    }
As you can see, I'm using JOGL. (bindTex(), by the way, is no more than:
     if(cached) bGL.glBindTexture(GL.GL_TEXTURE_2D, glID);
...for a Texture that's already been bound, so I've no real idea why this should be so expensive.) I'm using a shiny new 2.2 GHz Intel Core 2 Duo Macbook, with a GeForce 8600M GT.  Each terrain tile is simply a set of 4 polys arranged around a centre of origin.  What can I do to optimise? Much obliged.

Share this post


Link to post
Share on other sites
Advertisement

Hi Pelagius. It has to be glDrawArrays. You should probably switch to VBO and use indexed primitives. It would be an easy task since you already have Vertex Arrays up and running.

kind regards,
Nicolai

Edited by ndhb

Share this post


Link to post
Share on other sites
Quote:
Hi Pelagius. It has to be glDrawArrays. You should probably switch to VBO and use indexed primitives. It would be an easy task since you already have Vertex Arrays up and running.

I've done a little more benchmarking, and you seem to be on the money. glDrawArrays eats up about 75% of rendering time, but given the array is only 4 vertices long I didn't think throughput would be a major concern, and the remaining 25% is still pretty damn slow. (Paradoxically, If I replace glDrawArrays with individual vertex calls, it's actually a bit faster.)

I'm working on a system to render terrain tiles with similar texture states in one batch, so I can push all the associated data into a handful of big arrays and render them all together. It seems to be a lot more efficient (e.g, 20x or so.) Thanks for that.

Share this post


Link to post
Share on other sites
You can still use Vertex Arrays, just instead of glDrawArrays(), use glDrawElements(), which allows you to send the vertex data once, meaning no repetition of vertices and then send an array of indices which specify the order in which the vertices are drawn. This is the basis of indexed primitives.

Share this post


Link to post
Share on other sites
Quote:
Original post by PelagiusI'm working on a system to render terrain tiles with similar texture states in one batch, so I can push all the associated data into a handful of big arrays and render them all together. It seems to be a lot more efficient (e.g, 20x or so.) Thanks for that.


Of course it is and you should always try to render as much as possible in one call. Imagine someone picking up his pen, writing a single letter, then putting it away, straightening his tie, picking up the pen again, doing an elaborate gesture, writing the next letter and putting the pen away again. Getting anything done will take forever like that. Tons of setup and overhead for doing next to nothing.

Make use of all the texture units, put as many detail textures into a single texture as possible, remove useless and redundant calls (setting exactly the same material properties a million times is somewhat pointless for example). Not to mention that a 64x64 terrain is so small that typically you'd draw it in a single call (it's the patch size I'm using for terrains of 4096x4096 and up).

Share this post


Link to post
Share on other sites
Quote:
Make use of all the texture units, put as many detail textures into a single texture as possible, remove useless and redundant calls (setting exactly the same material properties a million times is somewhat pointless for example). Not to mention that a 64x64 terrain is so small that typically you'd draw it in a single call (it's the patch size I'm using for terrains of 4096x4096 and up).

I agree in retrospect, but the picture was complicated somewhat by the fact I was (A) assigning different textures to individual terrain tiles (including 'fringe' overlays onto neighbouring tiles,) which might need to be modified dynamically, and (B) performing frustum culling of non-visible tiles. This application is more akin to a 2d-isometric RTS, than to outdoor scenes in a typical shooter.

I just didn't think that inefficiencies would crop up much when I'm only rendering a few thousand polys in the worst-case scenario. Silly me, I guess.
Quote:
You can still use Vertex Arrays, just instead of glDrawArrays(), use glDrawElements(), which allows you to send the vertex data once, meaning no repetition of vertices and then send an array of indices which specify the order in which the vertices are drawn. This is the basis of indexed primitives.

Given I'm assuming tile edges are contiguous, that could be very handy.

On a related note- a problem I've been wrestling with is how to introduce cliffs or other discontinuous terrain outcrops within a single tile. I'd like to be able to adapt the code for indoor areas with cliffs acting as passageway walls, and so forth.

Share this post


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

  • Advertisement