I would like to pan or scoll a very complex and static scene (and preferably without hardware acceleration requirement). Panning should be smooth and without flicker.
In case of a double buffer updates are too slow, because it takes some time to render the whole scene and then swap the buffers. The result is that scrolling is not smooth. Bad…
If case of a single buffer updates are much faster, however there is ugly flicker because you can see how all geometry is redrawn. Bad…
The third solution and in my opinion the one that should work is to ‘bitblt’ or copy portion of the screen image that was not hidden by translation and then render only new areas of the sceene (again with single buffer). I guess, theoretically this should make panning both smooth and fast.
BUT, when I implemented this using glCopyPixels(), the performance of this function was terrible. You can actually see very slow update on the screen. Also, I followed tips for improving pixel drawing rates from the RedBook 3rd ed. (pg. 324)(default pixel zoom, disabling all fragment ops., disabling lighting and texturing…)
My question: is it possible that even without hardawre acceleration image ‘bitblt’-ing/copying is so slow, or I am doing something wrong ?
No, I don’t think there’s any other solution. All that glPixel stuff is slow, and I think that wouldn’t change, even with a GeForce10. Single bufferring is obviously not acceptable. Double buffering should provide best results. Maybe you should try cosmo gl, I’ve heard it should be faster than MS generic. You should notice that software gl is slow, because GL is more optimized on image quality than on speed. But who cares, it’s software…
You say the scene is static, and by the sound of it you’re using an orthogonal projection so you don’t need to worry about changing perspective when you pan. So why not render the entire scene into a memory DC during initialization, then just blit the relevant rectangle to your window using GDI when the user scrolls/pans?
If your scene is really that static, there doesn’t seem to be any reason for your window-drawing code to call OpenGL at all, and AFAIK a memory DC can be as big as you like.
Originally posted by MikeC: Ivan - I’m a bit confused about your application. You say the scene is static, and by the sound of it you’re using an orthogonal projection so you don’t need to worry about changing perspective when you pan.
You are right! It is 2D drawing program.
Originally posted by MikeC:
[b]So why not render the entire scene into a memory DC during initialization, then just blit the relevant rectangle to your window using GDI when the user scrolls/pans?
If your scene is really that static, there doesn’t seem to be any reason for your window-drawing code to call OpenGL at all, and AFAIK a memory DC can be as big as you like.
Or is your scene really, REALLY huge?
[/b]
Sorry, I was not precise enough. The image can be either very small or really, REALLY huge depending on the zoom factor (e.g. 100,000 by 100,000 or more). Nevertheless, what you mentioned (with some wrinkles) might work even for these large images.
However, this means that I will have to use platform specific code (Win,Mac,Unix) for screen canvas/GUI. I was planing to use OpenGL user interface for all these systems, but if this implies terrible performance, I will rather write some platform specific code.
The only thing that suprises me is that OpenGL does not have a way to do faster ‘bitblt’-ing, one of fundamental graphics functions that should be lightingly fast?
ivan
i used glCopyTexImage2D() to test procedural texturing.
i found it to be a little faster than glCopyPixels() for a whole scene… but it’s really marginal.
but note that with that function you create/update a texture with pixels coming from the framebuffer.
textures are also limited to power-2 sizes, wich will lead to waste some space in the texture if
you wish a 1:1 mapping from texture to framebuffer.
with glCopyTexImage2D(), your application have to do something like:
-render geometry to the framebuffer
-copy the framebuffer to a texture
-render a quad with this texture applied ( MS generic opengl is slow on texturing, SGI generic is a bit faster )
however, you’re basically drawing things twice.
moreover, with texture or pixel operations, consider that opengl don’t do just a simple memory copy:
it process data flowing within it’s pipeline, so it converts formats, do scale-biasing…
it have to check if a particular operation is desired or not.
it also do memory moves twice, to system ram first ant then to the video card, either the framebuffer or the texture zone.
i think it’s better to let the system handle pageflipping/blitting process, and focus on some scheme
to reduce the set of primitives you send to opengl.