(On behalf of Patrice and myself: sorry for somewhat hijacking the thread, guys...)Our o2 Opengl framework uses GDI+ both for loading textures and producing image files.
Currently, the opengl buffer bits are transferred pixel by pixel into a gdi+ bitmap.
Hi Charles,
GDI+ API can be (and is) safely used to load and save many common 24- and 32-bit image formats as OpenGL textures in low-end image viewers and simpler engines. But GDI+ is noticeably slow even if compared to GDI routines.
One way to speed up the loading of really large discrete textures and their atlases (multiple textures as single image), say 4Kx4K or 8Kx8K pxs large, is to carefully select a palette of simpler image formats of relatively low level of compression and simpler compression algos (like RLE TGAs and BMPs, 100% JP(E)Gs or full-color GIFs) to support, and maintain one's own library of simplified routines to (de)compress them efficiently in memory as needed. There
are pieces of code available on the net that are compatible with common libraries/algos like e.g. zlib (for jpegs and pngs) while working significantly faster than those.
Another way is to work with Microsoft's DDS (
direct
draw
surface) texture formats that
both OpenGL and Direct3D can load and display
without prior explicit decoding/decompression.
(actually, (de)coding is done automatically by the renderer hardware on the fly when the texture gets bound to the render target)Currently, the opengl buffer bits are transferred pixel by pixel into a gdi+ bitmap. Though I wonder if there is a more efficient way of making the transfer, bearing in mind that the red and blue colors of each pixel have to be swapped.
No, you cannot speed up
glReadPixels() which seems to be by far the slowest OpenGL API that's even slower than GDI+ routines. The only way to boost the frame-to-image rendering speed to real on-screen 3D motion capture is use frame- and renderbuffer objects (FBOs/RBOs) in the GLSL hardware-accelerated programmable pipeline. It allows, for instance,
ObjReader to successfully render and capture simple animation (currently rotation/translation/scaling) of arbitrary meshes (pieces/submodel chunks) in a full-screen scene at a speed not less than 30FPS (typically 60+FPS) for scenes as complicated as
10 million polygons (ca. 30 million vertices) and more. FBO hardware-assisted blitting occurs perhaps 100 times faster than regular glReadPixels(), especially for non-antialiased framebuffers.
But the good news is yes,
you can eliminate the need to swap pixels while loading or saving images from or to GDI+. The two major OpenGL APIs you use for creating/saving the textures (or the OpenGL screen pictures) , glTexImage2D() and glReadPixels(), as well as some others, use a parameter called
format (not to be confused with
internalFormat!) that can be typically either
GL_RGBA or
GL_BGRA. Use GL_RGBA with common image formats like BMP or JPG for "straight" color bits order, or GL_BGRA, for "linuxoid" textures like PPM/PGM/PNM or GDI+ PNG image formats. In this case, OpenGL will do R and B byte swapping for you automatically at texture creation/on-disk dumping, leaving the G and A bytes in place.
