Will PBO fix glDrawPixels?

One killer obstacle we have always faced with OpenGL is the total inability to simply draw 2D graphics on the display at a reasonable speed. Everyone ends up using textured quads because glDrawPixels is so painfully slow on almost all hardware. This is fine for sprites that don’t change but this is particularly painful, for example, when you are trying to render a 2D GUI interface on top of your 3D display. The 2D image of the GUI must be updated every frame. Therefore, because we are forced into this ugly kludge of using textured quads, we must actually update the GUI’s texture every frame by calling glTexSubImage2D. Making this call on a large texture (e.g. 512x512) every cycle often cuts the application’s framerate IN HALF!

All of this pain is because we can’t simply draw 2D graphics on the display at a reasonable speed.

Will the PBO extension fix this problem? Will we finally be able to draw pixels on the display at a reasonable speed?

It is so hard to conceive of how the incredibly basic ability to blit 2D graphics to the screen quickly has gone unaddressed in OpenGL for so long. Rendering textured quads is a hack not a solution. I wonder how many people have been forced to use Direct3D because of this gross oversight in OpenGL? I hope that it is addressed somehow.

The 2D image of the GUI must be updated every frame.

Unless you’re speaking of showing a video, why would you need to update your textures every frame ? And if you got small res or short anims, you can pack them all into a big texture and upload it once.

I disagree that it’s a trick. Using a quad automatically gives you the ability to use zooms, rotations, transparency, or even weird pixel shaders stuff. It’s just a different way of thinking. I’ve programmed a full UI in 2D OpenGL and got no problem with it. OpenGL is fine as it is now (well, except on the video side - uploading a video of 1024x768x32 @ 30 fps is… slow).

Y.

Originally posted by Ysaneya:
uploading a video of 1024x768x32 @ 30 fps is… slow).
if it’s at 30fps, nope, thats fast enough for me :smiley: (i know you mean you don’t get it to 30 fps as you would need to:D)

to the OP:

opengl does not have any concept of pixels (screenpixels, that is), and direct3d is moving quickly away from it, having a gui in the next windows wich does not have screen-pixels at all anymore (but “1” will be one pixel wide on the ‘standard screens’).

there’s not much wrong in this, it makes a lot of sence. as resolutions of your draw target can change (the screen res, or even a printer, or what ever), you have to do it with proper scaling, and some virtual coordinate system.

so no, there will never be another way to quickly plot pixels, other than texsubimage, drawquad.

i don’t have that much problems with this, using opengl as my pixel-plotter for my raytracer just this very way (onto a texture rectangle). advantages are different ones. main advantage: i can fully use hdr-textures, and do the final on-screen-mapping with glow and all… now thats nice:D

Of course OpenGL has a concept of screen pixels; if it doesn’t then what is the function glDrawPixels for?

Anyway, thanks to both of you for taking the time to respond. I can see that the textured quad has established firm dominance in the OpenGL community, so I give up trying to fight against it. However, there is simply no way to deny that uploading a texture using glTexSubImage2D, and then turning right around and rendering a quad with that texture on it, is overkill when all you’re trying to do is paint a simple 2D image on the screen (and you don’t need zooms, transparency, rotation, or pixel shader stuff.) Oh, well.

It seems like a cruel trick to even have glDrawPixels at all since it so slow that it is basically a venus fly trap that sucks unsuspecting programmers in and spits them out bitter and confused.

Originally posted by Claytonious:

It seems like a cruel trick to even have glDrawPixels at all since it so slow that it is basically a venus fly trap that sucks unsuspecting programmers in and spits them out bitter and confused.

For what it’s worth, Claytonious, I agree with you. It’s silly to have a TexSubImage2D()/draw_textured_quad() be faster than DrawPixels().

Send me email and I’ll get you in touch with the people at NVIDIA to talk to.

Thanks -
Cass

I haven’t used drawpixels in a real world scenario but from my benchmark (and others) drawpixels is capable of 500Mb/sec on a GF5900. SubImage2D manages ~300Mb/sec. On ATI hardware it seems quite different, drawpixels is about 100-200Mb/sec and subimage2d ~1000Mb/sec. What hardware are you using?

PBO is likely to give similar performance gains to PDR which means in terms of raw performance you will see little difference if any. The big advantage of PBO is that it will allow you to use both drawpixels and subimage2d asynchronously.

@cass: wouldn’t it be a minor homework for a driver writer to internally map a glDrawPixels() call to a sequence of texture upload of the image data, setup of texture parameters, drawing a viewplane align textured quad, and undo all changes to the texture stage again? :wink:

Is there a quality issue here as well as a performance issue? I was recently drawing a 256x256 quad mapped with a 256x256 texture into a 256x256 ortho view in a 256x256 window, and noticed several cases of what looked like off-by-one sampling errors - the interpolated texcoords weren’t picking the right texel for the corresponding pixel. With GL_LINEAR sampling, and for some types of content (texfont glyphs in this case) even 1-texel errors are very, very obvious.

(This was on a GF4200 Go, btw. I didn’t spend all that long on it so it’s also quite possible that I screwed up my setup.)

Leaving aside the question of blitting directly from sysmem, is there currently a way to blit from a texture to the color buffer without going through texture filtering? Like a glCopyTexSubImage2D in reverse.

OpenGL texture sampling rules are very well defined. Are you sure you used correct tex coords? The texel centers are at non integer coordinates.

Originally posted by harsman:
OpenGL texture sampling rules are very well defined.
So I’d assumed, but where, exactly? I couldn’t find anything on the subject in the Blue Book. There are a few comments in the Red Book about predictable rasterization of primitives, but nothing about texcoords.

Are you sure you used correct tex coords?
Not in the least. As I said, I didn’t spend a huge amount of time on it, and I’ve been out of the loop re OpenGL for a very long while.

The texel centers are at non integer coordinates.
Yes… that was my first thought and the first thing I tried, but fractionally-offsetting the texcoords only seemed to make matters worse. By the same rationale, wouldn’t the fragment centres be at non-integer coordinates as well? Don’t the two offsets cancel out?

Originally posted by MikeC:
[quote]Originally posted by harsman:
OpenGL texture sampling rules are very well defined.
So I’d assumed, but where, exactly? I couldn’t find anything on the subject in the Blue Book. There are a few comments in the Red Book about predictable rasterization of primitives, but nothing about texcoords.
[/QUOTE]It’s explained in the Rasterization chapter of the OpenGL spec (chapter 3 of the OpenGL 1.5 pdf pg 85, also see figure 3.10, on page 134).

It’s not so much that texel centers are in half texcoords, but that fragment centers are in half screen coords, which causes textures to be sampled at half texel coords (when you sample in the middle of a texel, you get the full texel value even with linear filtering).

In this sense, OpenGL is orthogonal and you don’t need to fiddle with texcoords to have a 1 to 1 mapping texture to screen - i.e. by rendering a 256x256 texture on a (0,0,256,256) quad with (0,0,1,1) texture coordinates, you have a 1 to 1 mapping.

Originally posted by evanGLizr:
by rendering a 256x256 texture on a (0,0,256,256) quad with (0,0,1,1) texture coordinates, you have a 1 to 1 mapping.
Ahhh… I have a nasty suspicion that I was rendering a (0,0,255,255) quad. That could account for the single-pixel errors. Foiled by the fencepost…

Many thanks for the rasterization references, I’ll read up on that.