Re: Why use OpenGL (was Native Mode Handling)
Brian Paul <brian-CdwZJljFklH+2FeEXyspIVaTQe2KTcn/@public.gmane.org>
| Newsgroups | gmane.comp.freedesktop.xserver |
|---|---|
| Organization | Tungsten Graphics, Inc. |
| Message-ID | <[email protected]> |
Kendall Bennett wrote: > Brian Paul <brian-CdwZJljFklH+2FeEXyspIVaTQe2KTcn/@public.gmane.org> wrote: > > >>>Thinking about this some more it would seem to me that perhaps what you >>>need is to make sure there is always a good 2D API available that is >>>implemented in terms of 3D functionality. Make sure it is easy to use >>>(or backwards compatible at least), and make sure it can be done *fast*. >>>Like I mentioned before, bitmap support in OpenGL sucks - >> >>Can you elaborate? I've heard this said before, but I never see >>much in the way of concrete information. > > > Doing it fast via OpenGL is always painful, because glDrawPixels is > traditionally not well accelerated (even on Windows). Actually, it's not too bad with recent NVIDIA and ATI drivers (for example). The basic task is to quickly move image data from user space to VRAM. There's no reason why OpenGL should be slower than any other graphics library/API for comparable operations. > Part of it has to > do with the fact that at the back end doing *everything* this function > can do is complicated, so the hardware drivers have to know what common > fast cases should be accelertaed, and the call code needs to know what > state to set up in order to get on the fast path. This is doable. It's just a matter of using the "right" OpenGL image format/type. I'd expect the fast format/type combinations to be the same as those for GDI or DirectX or Xlib or whatever API people are using nowadays. >>>One way of thinking about this is that as a 2D programmer, if I want to >>>draw a blended 2D bitmap, I don't want to have to set up a geometry >>>pipeline, load a texture map, bind the texture map, set up the 3D >>>rendering engine state and then finally draw some 3D triangles to get my >>>blended bitmap on the screen. Rather I just want to call something like >>>BlendBitmap() that will take my bitmap and blend it onto the screen. >>>Whether the internal implementaiton does all of the above is irrelevant, >>>so long as the 2D programmer does not have to deal with all the 3D >>>cruft. >> >>What's wrong with this: >> >>glEnable(GL_BLEND); >>glWindowPos2i(x,y); >>glDrawPixels( my_image ); > > > What about all the rest of the state that has to be set up correctly to > ensure this works properly? The default state should be OK. If you're mucking with other state (like alpha test, z-test, etc) then as the programmer you're obligated to take care to set things correctly. That's true no matter what API you're using. > There are all kinds of raster modes and > scaling that can affect this call that needs to be accounted for, plus > you need to set up the blending pipeline correctly. Sure, you have to set the right blend mode. But you'd have to do that with any API you'd use. > On top of that all > this ends up going through the geometry pipeline (since the vertices > *can* be transformed in OpenGL for this function I believe). glWindowPos is extremely simple/fast. > Since most > developers using a 2D API could care less about sub pixel precision etc. OK, so the programmer uses glWindowPos and they don't have to care. > Also using glDrawPixels() the only option you have is to draw the bitmap > from a image buffer that you pass to the OpenGL API. There is no way to > create a bitmap and have the contents stored in offscreen video memory > somewhere, and then be able to draw directly from the offscreen buffer > somewhere else in video memory using the hardware. To do that, you need > to stuff your bitmap into a texture (with all the associated hazards of > texture dimensions), bind it to the pipeline and then draw some polygons. > Like I said before, whether intenally a DrawBitmap function does all of > that is irrelevant - the 2D programmer does not want to have to deal with > that level of complexity. The GL_ARB_vertex_buffer_object extension will probably soon have a layered extension that will effectively let you store an image in video memory and reference it with glDrawPixels. It would be analogous to X's Pixmaps. A smart display list implementation could do this too. You might say that this sounds complicated. But how would you do this with any other graphics library? With Xlib you'd use a Pixmaps. You'd create a pixmap with XCreatePixmap(), load its contents with XPutImage(), then draw it to the framebuffer with XCopyArea(). Anyone who's done this knows that it's not exactly simple. Incidently, using texture maps to store images on the server side and drawing them with a textured polygon might be substantially faster than a conventional blit. Does blit performance on modern cards approach the giga-pixel fill rate that can be realized with texture mapping? The other advantage of texture mapping over glDrawPixels (for images drawn more than just once) is the fact that OpenGL can reformat the image data if it's not in the ideal format. To summarize my position: - OpenGL's API is pretty simple for most things (far simpler than Xlib, for example). You can generally ignore the parts that you don't need. - There's no intrinsic reason why OpenGL should be slow when it comes to conventional 2D image operations. - We have the know-how to optimize some of these things in our GL drivers. It's just a matter of finding the time. I bet that if we implemented fast glDraw/Copy/ReadPixels in one of the DRI drivers, other people could adapt the implementation to other drivers pretty quickly. -Brian