| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
Where's the Beef? Running either of these two examples, you may doubt that you are actually getting any hardware acceleration at all. One of the original OpenGL designers once admitted to me that he thought the omission of texture objects was one of the major (but few) blunders of OpenGL 1.0. (This blunder was fixed with 1.1, which is why you’'re reading this.) At the time, OpenGL's engineers thought that display lists would do an adequate job of encapsulating the texture loads. The purpose of a display list is to encapsulate a group of OpenGL commands into a preprocessed batch that can be sent to hardware quickly or even invoked remotely via a client/server interface. While display lists are great for precompiling a set of OpenGL commands into hardware commands, they can be very difficult for hardware vendors to optimize when they contain important state changes, such as loading a new texture. If you think about it, display lists are inherently inefficient for texture loads. A display list must be stored in memory. When a display list contains a texture load, it also contains the original bit image of that texture. When the display list is invoked, it uploads the texture image to OpenGL (via glTexImage2D()). Now two copies of the texture exist. One represents the original texture bits stored as part of the display list, and the other has been preprocessed into a native format that the OpenGL driver and it’'s particular hardware can use. Loading a texture can be quite time consuming, especially if the native format is different from what you’'re specifying (such as using a 24-bit texture image when the driver converts it to a 16-bit image internally). Thus, even though using a display list can save a great deal of intermediary calculations (or disk accesses), some time is always lost due to the actual texture upload. What we need is a way of keeping this internal texture data around for individual textures. We can then reference these textures individually instead of performing multiple texture loads. This is exactly what texture objects do. (Some exceptions to the stated efficacy of texture objects exist. 3D Labs, for example, has done a tremendous amount of work to optimize display list generation for its drivers. Even the original Permedia drivers have has this optimization. 3D Labs' drivers correctly store the internal results of the glTexImage2D() call, rather than simply replay this sequence to the driver when the display list is invoked. One problem that this approach has created for developers targeting consumer hardware is that code that runs great on 3D Labs' hardware can suddenly appear unaccelerated on other graphics boards. However, this optimization is uncommon on most commodity boards. Most vendors won’'t spend the time making this optimization when texture objects are so readily available to developers). |
|
|