Jump to content
  • Advertisement
Sign in to follow this  
spek

OpenGL Loading textures in the background

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

Hi, Question about loading/creating OpenGL objects such as textures and compiling Cg Shaders. Normally I would create them inside the rendering loop, no problemo. But now I have another thread that loads the world/textures in the background. Loading an image into an array of colors is simple. But when I'll try to create a GL texture and send the data, it fails. when trying to compile shaders, I get errors as well. I guess this is because I call these functions from another thread, outside the normal rendering loop. Anyhow, how to deal with this? I'd like to prevent loading times, that's why I created a background thread for reading files and eventually creating the textures, if possible. Greetings, Rick

Share this post


Link to post
Share on other sites
Advertisement
Well, I don't know if the OpenGL context can be accessed by a thread other than the one that created it (AFAIK this was something OpenGL 3.0 was meant to address).

But you could share the data loaded from disk between your threads. Why not load the data in one thread and upload it to OpenGL in your render thread?

Share this post


Link to post
Share on other sites
Ok. That clarifies the problem. Loading the image from disk is still possible. The shaders can all be loaded at the start of the program maybe.

Then we still have the texture uploading part. How slow/fast is this? While walking around, it regulary happens a couple of textures need to be loaded/unloaded. And ussually each texture also has variants such as normalMaps. How to upload, for example, 8 MB texture data 'quietly'?

Thanks for the info!
Rick

Share this post


Link to post
Share on other sites
I've experimented with that before actually. I created a blank OpenGL texture object with the same dimensions as the texture I wanted to load.

I'd load the image in a separate thread. Then, every frame, I'd copy just a small chunk of the image data to the OpenGL texture with the GL image operation functions. It usually wasn't enough to noticeably effect performance, but it did take quite a while to load the texture, so that might not be your best bet if you need them on the fly.

Share this post


Link to post
Share on other sites
I have some loading time available since most of the new loaded parts are not directly visible yet. But aren't there other ways? I mean GTA already managed it on old hardware, and streaming gets more and more used nowadays...

Share this post


Link to post
Share on other sites
Have you actually tried just glTex(Sub)Image'ing the data and profiling that? Uploading a few MB of texture data occasionally should work fine.

If that isn't fast enough for you, it is conceivable that writing the data into a mapped PBO from the loading thread and then unmapping/uploading from the main thread is faster. Finally, as long as you have multiple smaller textures and not one huge texture, try balancing the uploads over several frames.

But again, before you do any of this, just try the simple and stupid method. From your post it seems you haven't done that yet, and it might just be fast enough for you.

Share this post


Link to post
Share on other sites
Didn't try indeed :) Well, the main question was howto upload textures in the background. But as far as I understand, only the main rendering loop can do the uploading. I want to prevent framerate drops/'hanging' as much as possible, so I thought maybe there were some other tricks.

Textures sizes can vary quit alot in my case. 512x512 or 1024x1024 is possible as well. I could start with loading 1 texture per frame, or after each x frames maybe. Ussually each texture also has 1 or 2 other variants (normalMap/specularMap/somethingelseMap), and some of them might need mipmaps as well. Is it smarter to create those mip-maps manually maybe? Well, I guess I should just try and look how slow or fast it goes. I was afraid uploading a bigger chunk of data would cause a noticeable drop.

Greetings

Share this post


Link to post
Share on other sites
Hi again,

First I'll try the traditional way of uploading textures like Prefect suggested. But while coding I read some more about PBO's. I'm not sure if they can actually help me though. So far the streaming is made of the following steps:
1.- texture gets requested, load file into RAM
2.- In OpenGL context, transfer RAM to texture
3.- Free RAM

As far as I understand, the PBO can be used to send pixeldata quickly (without stalling the CPU) to the video mem. However, this PBO needs to be build in the first place as well. According to the model above, I would need to create a PBO each time a texture is loaded:
>> file -> RAM -> PBO -> Video Mem.

When I read some threads about this, this seems to work actually slower, because that PBO needs to be build as well, right? I could create a PBO for each and every texture. But where is the PBO actually stored, in the RAM or video Mem? I might end up with hundreds MB of image data... When does a PBO benefit? I have 2 other lightMaps that must be changed by the CPU several times a second, maybe its of good use here.

Greetings,
Rick

Share this post


Link to post
Share on other sites
you can use wglShareLists £¬make two context created from different context share same list£¬such as text make£¬buffer object id£¬display list...

see msdn...

wglShareLists
The wglShareLists function enables multiple OpenGL rendering contexts to share a single display-list space.

BOOL wglShareLists(
HGLRC hglrc1, // OpenGL rendering context with which to share
// display lists
HGLRC hglrc2 // OpenGL rendering context to share display lists
);

Remarks
When you create an OpenGL rendering context, it has its own display-list space. The wglShareLists function enables a rendering context to share the display-list space of another rendering context; any number of rendering contexts can share a single display-list space. Once a rendering context shares a display-list space, the rendering context always uses the display-list space until the rendering context is deleted. When the last rendering context of a shared display-list space is deleted, the shared display-list space is deleted. All the indexes and definitions of display lists in a shared display-list space are shared.

You can only share display lists with rendering contexts within the same process. However, not all rendering contexts in a process can share display lists. Rendering contexts can share display lists only if they use the same implementation of OpenGL functions. All client rendering contexts of a given pixel format can always share display lists.

All rendering contexts of a shared display list must use an identical pixel format. Otherwise the results depend on the implementation of OpenGL used.

Note The wglShareLists function is only available with OpenGL version 1.01 or later. To determine the version number of the implementation of OpenGL, call glGetString.

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!