   texture prefetch / preloading? [solved]
  Is there any way to prefetch textures in OpenGL so that I can force it to load textures from RAM into video memory before rendering anything?  Note that I have already created all texture objects and specified the texture data with glTexImage2D.I'm working with an application that uses a large (+200Mb) amount of textures all at once, although not necessarily all visible at once -- but they can be.  As I move about in the world, textures get transferred from OpenGL memory into video memory at runtime, causing painful slowdowns.  Once all of the objects in the world have been rendered in the view at least once, there are no more speed drops and everything goes really fast.I have to go through a loading phase anyway, so it would be nice if I could get the textures uploaded at that point, rather than having to deal with slowdowns at runtime.  I've considered drawing all of the texture maps in the world onto the screen in a 1x1 pixel, but this just sounds hacky and silly.  Any thoughts?[Edited by - bpoint on January 18, 2006 9:58:28 PM]
  Hi,I am not sure if this will help but you could prioritize the textures that you use most of the time. I think this happens only once you call bind texture at least once.   ;  Thanks for the suggestion, but prioritizing only really comes into effect when there is insufficient video memory available for all textures.My application can fit all textures in the world within video memory, it's just that OpenGL only actually uploads them to video memory just before they are rendered, not when they are bound... although I guess that is more specific to NVidia's implementation, not OpenGL.Any other ideas, anyone?;  Disable rendering to the color buffer and for each texture, bind it and draw a single pixel with it ?Y.;  Heh, I considered culling both faces, but figured that might not trigger the upload since the primitive would be discarded.  Disabling writes to the color buffer is a much better idea.It's still hacky (if it works) though... I don't suppose there is any good way of doing this at all?  :);  I tried disabling color buffer writes and rendering a tiny polygon with the texture(s) I want to prefetch, but it didn't seem to make much of a difference.  I wouldn't say it didn't help at all, though... sort of like only some of the textures I requested were fetched, but not all of them.So... no ideas, anyone?  :)Aside from what I want to do, isn't there anyone that uses texture prefetching?  A few frames before rendering a newly loaded object, normally one would want to ensure it's going to be available in video memory by prefetching it... I guess this is one of those things that OpenGL doesn't let you have control over.  *sigh*   ;  ive got no idea how it works behind the scenescant u draw them whilst youre loading them, after all the cards not gonna be doing anything else. (pehaps call flush after each call);  I'm not talking about drawing while loading, that would be silly.  :)Maybe I should be a bit more clearer in what it is I'm trying to do and where the bottleneck is.  Here's the flow on how a texture in OpenGL goes from being loaded to being rendered:allocate memory -> load from disk -> generate texture (glGenTextures) -> bind texture (glBindTexture) -> copy texture to OpenGL memory (glTexImage2D) -> render onto polygonIt is at the point where the polygon is first rendered with a texture that it gets uploaded from OpenGL memory into video memory.  Because my texture data is so large, at runtime I am taking a fairly large impact (I'm talking +10secs here, not just a few frames!) from the upload.  This is very annoying because it happens as soon as an object in the world comes into view and is rendered for the first time.  However, _all_ textures fit perfectly into video memory, so once all of the objects have been rendered at least once, everything zooms along just fine.I go through a loading phase to get the textures into memory anyway, so I'd like to ensure they're all uploaded at that time as well to avoid any pauses at runtime.  Like I said earlier, drawing all textures (albet with color buffer writes disabled) onto tiny polygons on the first frame didn't seem to help too much.There has got to be someone out there who has done something like this out there!  :)  I know I can't be the only one with this problem... ;  If I understand you right, you are looking to load all the textures into the video card ram before you start rendering polygons and that the amount of textures should all fit in ram?In which case, as has been suggested you need to draw all textures onto polygons before starting you main rendering loop to force the card to load them into ram. If you ever played Quake 3 you'd see its solution was to draw a grid of all the textures just before it starts the level. I thought Ysaneya's idea was good, although you suggest it doesn't work. I'm sure the principle is right though, so instead why not try rendering all textures to a screen aligned grid of quads, but place a black (or more appropriate colour, or even a loading screen) textured quad in front of the grid of quads to obscure them from view. I'd imagine you'd need to disable depth buffer read/writes, to force all polygons to be drawn and ensure the black quad is drawn last.This should ensure all your textures are loaded into ram (if they fit) before you start your main rendering loop, whilst also being hidden from view. If as you state the loading time for the textures is very large, then perhaps designing a loading screen would be best. You may find it prudent to load and display that first for a frame before drawing the grid of quads behind it.Hope this helps   ;  I've actually never played Quake 3 (*gasp*), but it sounds like that's the right way of doing it.After reading your post, I realized my previous code was actually flawed -- I had Z buffer writes and compare enabled, so only the first texture was getting cached.  All of the other textures were most likely discarded by the Z test, and were never requested by the hardware, so they never got uploaded.  At least, that's my guess.So, I tried again with Z compare off and it still didn't work.  Maybe texturing doesn't even get looked at if the color buffer writes are disabled.With Z compare off and the color buffer writes enabled, it worked!  I already have a loading screen, so just throwing them in at the beginning of the frame before anything is drawn is trivial.I was just looking for something "less hacky", I guess.  :)Thanks for the help everyone!