Lack of simple 2D blt

I’m annoyed by what seems to be a lack of support for
simple 2D blt’s in OpenGL; i.e. the lack of a version of
glDrawPixels which bypasses the various per-pixel
operations apparently taking place, causing it to be
slower than SetDIBitsToDevice (Windows GDI) or the
Blt method for DirectDraw surfaces (DirectX 7).
Perhaps there are some further glDisable’s that I need
to use. I am using

glDisable(GL_DEPTH_TEST);
glDepthMask(FALSE);

As best I can tell, most of the other optional processing,
like GL_BLEND, is turned off by default.

I’m aware of the workaround of drawing a textured quad,
but that’s rather clumsy and inefficient as well; e.g. if I
have a 130 x 130 pixel image in application memory,
then I need to allocate a 256 x 256 buffer and copy my
data into it, before calling glTexImage2D. (Surely no
one is going to suggest decomposing my image size
into a sum of powers of 2, and creating multiple
textures.)

Am I missing something here? Is the situation going to
improve in GL 2.0?

OpenGL is primarily a 3D API, and it is designed to deal best with information that it stores and handles itself. You cannot simply give OpenGL a texture pointer and render a triangle with it; you have to allocate a texture object, upload the texture, and then use it. Because of this, any functions where OpenGL does not have complete control of data are typically much slower than functions where OpenGL does not have control of data. The speed difference between NV_vertex_array_range and regular vertex arrays shows this, as most drivers are forced to copy data out of vertex arrays into their own memory each time they are used.

If OpenGL were to allow blitting, I would assume that it would have to draw from texture objects or a similar API in order to get reasonable speed.

In any case, as annoying for 2D as it is, the best way to blit is exactly what you said: upload the image as a texture and draw a quad. I wouldn’t expect OpenGL 2.0 to address this issue, as it is likely a low priority. 3D issues and programmability come first.

[This message has been edited by Korval (edited 04-02-2002).]

I may be horribly wrong, but I was always under the impression that OpenGL was primarily a 3d API.

Of course handling 3d means it can do 2d stuff aswell, but it doesnt seem to something that it is focused toward.

Ummmm.

As people stated before OpenGL is designed for 3D.

Sure you can use it to do 2D but it is like using complex numbers to do simple math (which is as well possible).

Look into the spec and see that the result of glDrawPixels is also dependent of:

glPixelStore, glPixelTransfer, glPixelMap, and glPixelZoom.

So glDrawPixels does a lot more then SetDIBitstoDevice (besides SetDIBitstoDevice is very slow under Win-NT4 as well).

DirectDraw is an 2D only API, if you dont need plattform independence, use that and be happy (but you have to deal with byte order or even worse bit order settings for different graphics cards and bit depth on your own).

Have fun!

[This message has been edited by lgrosshennig (edited 04-02-2002).]

It’s not because opengl is a 3d api that glDrawPixels is slow. Turning off some of the processes a fragment has to go through might help as well, but the main problem is that glDrawPixels as well as glReadPixels are considered low priority on cheap PCs. Todays cards (Geforce, Radeon) are super fast compared to cards 2 or 3 years old. If you made use of those, “BOOM software mode hell” and your frame rate went below 1. Now, you can get over 30 FPS on ‘large’ windows.

V-man

Thanks for your replies. In response to the “OpenGL is 3D” comments – yes, of course, there is some 3D in the mix of what we are doing. The point is there are lots of situations where the overall application needs to do some simple blt’s in addition to 3D; e.g. to display symbology or controls on top of or alongside the scene. Our situation is a bit more complicated than that – our 3D objects are rendered to offscreen buffers, pulled back from video to application memory, combined in software with other stuff, and then sent to the screen. We currently use Direct3D, but I am looking at the possibility of moving to OpenGL. There is some info about our current system at
http://www.math.uah.edu/dow/Simulation.htm

lgrosshennig writes
glDrawPixels does a lot more then SetDIBitstoDevice

That’s the problem; it does not write the pixels directly; my impresssion is that it turns each pixel into a “fragment” which then undergoes various processing steps.

V-man writes
Turning off some of the processes a fragment has to go through
might help as well, but the main problem is that glDrawPixels as
well as glReadPixels are considered low priority on cheap PCs.

I disagree; the problem is the lack of a function whose spec allows it to punch through the pipeline. It may be that some of the new functions in GL 2.0 relating to “image objects” address this, but I can’t tell from a brief look at the proposed specs.

One thing I am surprised no one mentioned (sorry if someone did and I missed it), make sure the dest and source types are the same. By that I mean if you are using RGB or RGBA for the frame buffer make sure the texture is a 24 bit or a 32 bit image. Regardless of what Pixel operations you disable opengl will always have to convert mismatched images formats. That is simply a must. Making the images the same type should help a lot. Making images a multiple of 2 is fastest for the memtransfer and packing operations. As for actual drawing its mostly unimportant. If you need to draw multiple images on top of each other you can always try doing it yourself. Really slick MMX type stuff and then just displaying the final image but I really don’t see that as ever being any faster than opengl, regardless of how slow opengl is.

Hope this helps.

Accelerated OpenGL is damned fast at drawing textured triangles - use them.


I disagree; the problem is the lack of a function whose spec allows it to punch through the pipeline. It may be that some of the new functions in GL 2.0 relating to “image objects” address this, but I can’t tell from a brief look at the proposed specs.

Like I said, its not really a pipeline complexity issue. These same functions are super fast on SGI workstations. No one uses these in their games (like so many other gl functions) so they dont give a damn about them.

Do some benchmarking if you wish.
Also, I recommend that you use DWORD aligned bitmaps if you havent done so. Probably RGBA8888 is a good idea with unsigned byte.

V-man

>>(Surely noone is going to suggest decomposing my image size
into a sum of powers of 2, and creating multiple textures.)<<

this is a nobrainer to do, ive done it before,
personally a fast drawpixels is the last thing i want from opengl, what would i use it for? i can think of many things for a fast readpixels though,
btw fwiw my gf2mx can do 640x480 at 60hz with glDrawPixels fast enuf