PDA

View Full Version : texture mapping terrain with high resolution image



Diaren
11-18-2010, 07:17 AM
I'm using VBOs (OpenGL 2.1) and am basically rendering the terrain at any given point on earth. The terrain which can be GL_TRIANGLES or GL_TRIANGLESTRIP with normals and per vertex colors needs to be texture mapped with a high resolution image.

For these questions the terrain and image is 10000x10000, the terrain has a point every 10 and the image is split up into 100x100 tiles, at any given time the viewer can view a 1000x1000 section of the terrain. So that's a possible 10000 different textures with 100 viewable per frame.

Do I have to call glDrawXXX for every texture in view?
Is there some standard way of achieving this?

ZbuffeR
11-18-2010, 08:41 AM
Yes you have to do 100 calls.

Otherwise clever tricks such as megatexture can do that with a single draw call.
The idea is as you see only 1000x1000 texels, use a single 1000x1000 texture, and glTexSubImage it when the camera move. Works well when camera does not teleport but move smoothly from one place to another.
A similar idea here :
http://techpubs.sgi.com/library/tpl/cgi-..._html/ch15.html (http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650&db=bks&srch=&fname=/SGI_Developer/Perf_PG/sgi_html/ch15.html)

Diaren
11-18-2010, 10:51 AM
Hmm don't think performer is an option. So have to draw every texture seperately... Hmmm that doesn't sound very performance friendly.

Does the opengl handling the paging of the textures or do I have to create (glGenTexture) if I run out of memory?

e.g. I might have an array of 100 ints for each texture, and if one is 0 then I'd glGenTexture otherwise I'd glTexSubImage if the tile is different?

aqnuep
11-18-2010, 11:24 AM
No, you don't necessarily have to do 100 calls. First, you can use texture arrays to provide a large enough texture for all the blocks.
Besides that you can cull the terrain blocks against the view frustum to reduce the number of terrain blocks to draw and then simply use one MultiDrawElements to render the whole visible part.
Of course, this needs quite new hardware (OpenGL 3.x level).

ZbuffeR
11-18-2010, 01:10 PM
I linked to that page hoping it would help explaining the virtual texture idea. Not for the actual implementation. You realize this is 6 years old ?
In practice streaming the virtual texture is fairly simple with any GLSL hardware, the only trick is to send to the shader the valid texture region coordinates.

As for texture arrays, I am curious about the implementation details : agnuep, can you be more precise ?

Aleksandar
11-18-2010, 02:26 PM
... First, you can use texture arrays to provide a large enough texture for all the blocks....
On the first glance, texture arrays seem very useful, but they are not update-friendly. The problem is in the fact that the whole array is a single "3D" texture (a single resource). Updating just one level would prevent access to all other layers (or cause artifacts in a simultaneous access). My humble opinion is that in a clipmap-like organization, separate texture for each layer could prevent rendering stopping by preventing access to the layer being currently updated.

Alfonse Reinheart
11-18-2010, 02:54 PM
Updating just one level would prevent access to all other layers (or cause artifacts in a simultaneous access).

In what way? How do you know that you would be unable to upload data to one part of the texture while rendering from another?

The main issue with array textures is generally the binary nature of them. The whole thing either is in GPU memory or it isn't. If you're only using part of it, then you're using more GPU memory than you need. On the other hand, it will always be in GPU memory, so you won't have to wonder about it being evicted if you start thrashing.

Aleksandar
11-18-2010, 03:51 PM
How do you know that you would be unable to upload data to one part of the texture while rendering from another?
Well I got a strange flicker while doing that. And, after all, it is just my logical conclusion.


The main issue with array textures is generally the binary nature of them. The whole thing either is in GPU memory or it isn't. If you're only using part of it, then you're using more GPU memory than you need. On the other hand, it will always be in GPU memory, so you won't have to wonder about it being evicted if you start thrashing.
Isn't it the case for all objects (VBOs, PBOs, Textures, etc). They can be only in the GPU's memory or not. Or you thought about VBOs mapping when you can have a copy in the memory that can be flushed by unmapping? Nevertheless, I didn't get the point.

Apart from that, while rendering a part of the terrain (a single block) it is quite normal that I'm using just a part of the clipmap (my current implementation using a single layer for the whole block). In that case it will be useful to have an ability to update some layers while using others for the rendering. For example, if the finer-level is not ready, use coarser-level.

Alfonse Reinheart
11-18-2010, 04:11 PM
Isn't it the case for all objects (VBOs, PBOs, Textures, etc). They can be only in the GPU's memory or not.

Yes, but if you have 256 textures, then any one of them can be in GPU memory. So if you are using 100 of them, then only those 100 need to be there; the other 156 can be evicted for other things. If you have one array texture with 256 layers, then either all of them are in memory or none of them are.

Diaren
11-18-2010, 05:55 PM
Just so we're clear, it's just a gui program so I don't need a high fps. I don't necessarily need roaming support, although it would be nice to know that whatever I do can be carried over to roaming.

So vertex arrays is an option, but when I update it prevents the whole lot from being used until the update is complete. It'd most probably be quicker to draw every tile wouldn't it?.

I understand the cliptexture concept, but how much work do I need todo for the texture memory management or does the driver handle this and I just keep loading/unloading textures until the system runs out of memory which is not an issue.

Aleksandar
11-19-2010, 02:04 AM
Yes, but if you have 256 textures, then any one of them can be in GPU memory. So if you are using 100 of them, then only those 100 need to be there; the other 156 can be evicted for other things. If you have one array texture with 256 layers, then either all of them are in memory or none of them are.
Oh, you meant that. Sure, I agree. But usually the number of textures is not so great. Usually there are just a dozen or less layers (the number of LODs+1 or +2), and they have to be resident because almost all of them are accessed in a single frame (just additional +1 or +2 used for cache are not accessed in a static scenes).


I understand the cliptexture concept, but how much work do I need todo for the texture memory management or does the driver handle this and I just keep loading/unloading textures until the system runs out of memory which is not an issue.
Drivers do load/unload textures (and also you can prioritize some of them to postpone removal, or make them resident), but I don't suggest you to overload memory with the textures. Having just several textures updated with glTexSubImage2D() will be much cleverer solution. Also, vertex arrays have nothing in common with texture arrays. Keep using VBOs.