LinuxDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


Animation in SDL: OpenGL

by Bob Pendleton
10/23/2003

OpenGL Surfaces

OpenGL is a powerful, portable, and elegant API for drawing 2D and 3D graphics. OpenGL is an open standard that is constantly being developed and reviewed through the public Architecture Review Board process. OpenGL continues to evolve to reflect changes in hardware and software technology. OpenGL reflects the distilled wisdom of thousands of programmers and researchers, all working to create a great graphics API.

There are a few "gotchas" with OpenGL. First off, OpenGL implementations come in two distinct flavors. There are hardware-accelerated implementations of OpenGL and pure software versions with no hardware acceleration. Hardware-based OpenGL is best for games and interactive programs. Software implementations provide a minimal level of graphics support for interactive use, but are useful for rendering images at sizes and color depths not supported by video cards. If an OpenGL program runs slowly on your computer, you should make sure your video card has hardware 3D support and install the latest drivers. Hardware-accelerated implementations of OpenGL are available for all widely used operating systems including Windows, MacOS, and all versions of Linux and UNIX. Due to the popularity of OpenGL with game developers, we can count on solid OpenGL support from video card vendors for the foreseeable future.

Another rough spot in using OpenGL is the interface between OpenGL and the operating system. You have to interact with the OS to create a window, or load a texture. Unfortunately, the functions needed to interact with OpenGL are different for each OS and windowing system. That is where Simple DirectMedia Layer (SDL) fits in. SDL provides a cross-platform API for working with OpenGL that is layered on top of the OS-specific APIs. You can write your code once and use it on every system that has both SDL and OpenGL.

Working with OpenGL Surfaces

An animation program written using an SDL OpenGL surface has the same structure as an SDL animation program written using hardware or software surfaces. The differences are in the details of using OpenGL for graphics instead of the SDL graphics APIs. Let's look at the differences between using the SDL APIs and the equivalent OpenGL APIs.

Initialize SDL

SDL supports three kinds of graphics surfaces: software surfaces, hardware surfaces, and OpenGL surfaces. Like software surfaces, OpenGL surfaces can be either windows on the desktop, or they can take over the entire screen for full-screen applications. The process of creating an OpenGL surface is different from creating any other type of SDL surface. The first step is the same for all SDL surfaces. We have to initialize SDL by calling SDL_Init().

if (-1 == SDL_Init(SDL_INIT_EVERYTHING))
{
  printf("Failed to initialize SDL error=%s\n", SDL_GetError());
  exit(1);
}

Initialize OpenGL

You have to tell OpenGL how to configure the graphics system before you create the surface. For software and hardware surfaces, the configuration is specified through SDL_SetVideoMode(). OpenGL surfaces support features that are not found in the other types of surfaces, so the configuration process is more complex and uses APIs that are specific to OpenGL. Before calling SDL_SetVideoMode() we must use SDL_GL_SetAttribute() to provide the extra information needed by OpenGL. The first parameter of the function is the name of the attribute to set. The second parameter is the value we are requesting. The following code is an example of using SDL_GL_SetAttribute() to configure the color format of an OpenGL surface.

SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  8);

Those three lines tell OpenGL that I want 8 bits for each color channel. In other words, I want millions of colors, and I won't settle for anything less. If the system doesn't support that depth, then the call to SDL_SetVideoMode() will fail.

OpenGL Attributes

The following describes the OpenGL attributes currently available in SDL 1.2.6. You do not have to set any attributes. You only need to set an attribute if you need to control the value of the attribute. If you do not specify any attributes, you will get a default display that may not meet your needs.

SDL_GL_RED_SIZE
SDL_GL_GREEN_SIZE
SDL_GL_BLUE_SIZE

The minimum number of bits of each color in a pixel. You only need to specify a value for these attributes if you need to force an RGB mode with specific color depth.

SDL_GL_ALPHA_SIZE

This is used to specify the minimum depth, in bits, of the alpha buffer.

SDL_GL_BUFFER_SIZE

This attribute is the depth of the frame buffer in bits. It is greater than or equal to the sum of the depths of the red, green, blue, and alpha values. If you want 24-bit color and an alpha channel in 32-bit pixels, you would give a color depth of 8 for each color and a buffer size of 32.

SDL_GL_DEPTH_SIZE

The number of bits in the Z buffers. Most hardware provides either 16-bit or 24-bit Z buffers. Asking for a larger Z buffer depth will fail.

SDL_GL_STENCIL_SIZE

The depth in bits of the stencil buffer.

SDL_GL_ACCUM_RED_SIZE
SDL_GL_ACCUM_GREEN_SIZE
SDL_GL_ACCUM_BLUE_SIZE
SDL_GL_ACCUM_ALPHA_SIZE

These attributes are like the other color and alpha values, but for the accumulation buffer. The accumulation buffer is an off-screen buffer used for special effects. The accumulation buffer is usually at least twice as deep as the frame buffer.

SDL_GL_DOUBLEBUFFER

This is set to either 0 for don't double buffer, or 1 for double buffering. This attribute must be used instead of the SDL_DOUBLEBUF video mode flag. It is only needed if you are using double buffering.

SDL_GL_STEREO

This attribute is used to turn stereo rendering on and off. When generating stereo images, the frame buffer is laid out to have left and right buffers as well as front and back buffers.

SDL_GL_MULTISAMPLEBUFFERS

These attributes control full screen anti-aliasing (FSAA) on hardware that supports the multisample extension to OpenGL. If a system does not support the extensions, these attributes will simply be ignored. For an example of how to use these, look at the source code for testgl.c that comes with the SDL 1.2.6 release.

New features and new attributes are always being added to SDL. Support for full screen anti-aliasing was added while I was writing this article. Support for the pixel buffer (AKA pbuffers) extension to OpenGL is under development.

Related Reading

Linux Web Server CD Bookshelf, Version 2.0
6 Bestselling Books on CD-ROM
By A publication of O'Reilly Media

A key point to remember about all of the attributes is that they do not specify the exact value that you will get. They specify the minimum acceptable value. For example, if you ask for 1 bit of green, you may get 8 bits. If you ask for a 16-bit Z buffer, you may get a 24-bit Z buffer. On the other hand, if you ask for a 32-bit Z buffer and your hardware doesn't support it, SDL_SetVideoMode() will fail. That means that you should ask for the minimum your program can live with, and hope for the best. Use SDL_GL_GetAttribute() to get the values of the attributes after the video mode has been set.

I've also included a program called modes.cpp. It iterates through a large number of different video modes, trying pretty much every combination of the attributes that I consider to be reasonable and a few that are clearly unreasonable. On my PC, all but the full screen anti-aliased modes work. But no matter what I ask for, I always get a 32-bit mode with 8 bits for each color component. When I ask for an alpha buffer, I get 8 bits of alpha. When I ask for a Z buffer, I get a 24-bit Z buffer. Why is that?

A basic principle of graphics programming is that you ask for what you want, but you have to be prepared to work with what you get. To start to get a handle on why you have to live with what you get, you have to understand the concept of an OpenGL visual. Go find a copy of glxinfo (if you are using the X Window system) or wglinfo (if you are using Microsoft Windows). If you are using UNIX or Linux, you probably have glxinfo installed already. If you are using Windows, you may have to download a copy of wglinfo. When you run one of these programs, it will list a lot of information about the version of OpenGL you have installed on you computer. There are several options you can use to select the kind of information that is printed out and the format of the information. Try them all and read the output. It can be very enlightening.

The last thing these program print out is a list of visuals that are currently available on your computer. A visual is a specific configuration of the graphics hardware of the video card. The visuals that are currently available are not necessarily all of the visuals that are possible on your video card. On my Linux system, I get different lists of visuals depending on the color depth of my desktop. When my desktop is set to use millions of colors (24 bits of color), the listed visuals are all 24 bits deep with a buffer size of 32 bits, and when I set it to thousands of colors (16 bits of color) the visuals are all 16 bits deep with a buffer size of 16 bits. You will get different results on Windows. Here are a few lines from the visual table for my computer generated by glxinfo:

Table Header


Vis  Vis   Visual Trans  buff lev render DB ste  r   g   b   a  aux dep ste  accum buffers  MS   MS
ID  Depth  Type   parent size el  type      reo sz  sz  sz  sz  buf th  ncl  r   g   b   a  num bufs

16-Bit Visuals

0x21 16 TrueColor    0   16  0  rgba   1   0   5   6   5   0   0   16  0  16  16  16  16   0   0
0x22 16 DirectColor  0   16  0  rgba   1   0   5   6   5   0   0   16  0  16  16  16  16   0   0
0x23 16 TrueColor    0   16  0  rgba   0   0   5   6   5   0   0   16  0  16  16  16  16   0   0

32-Bit Visuals

0x21 24 TrueColor    0   32  0  rgba   1   0   8   8   8   0   0   24  8  16  16  16  16   0   0
0x22 24 DirectColor  0   32  0  rgba   1   0   8   8   8   0   0   24  8  16  16  16  16   0   0
0x23 24 TrueColor    0   32  0  rgba   1   0   8   8   8   8   0   24  8  16  16  16  16   0   0
0x24 24 TrueColor    0   32  0  rgba   0   0   8   8   8   0   0   24  8  16  16  16  16   0   0
0x25 24 TrueColor    0   32  0  rgba   0   0   8   8   8   8   0   24  8  16  16  16  16   0   0
0x26 24 TrueColor    0   32  0  rgba   1   0   8   8   8   0   0   16  0  16  16  16  16   0   0
0x27 24 TrueColor    0   32  0  rgba   1   0   8   8   8   8   0   16  0  16  16  16  16   0   0
0x28 24 TrueColor    0   32  0  rgba   0   0   8   8   8   0   0   16  0  16  16  16  16   0   0
0x29 24 TrueColor    0   32  0  rgba   0   0   8   8   8   8   0   16  0  16  16  16  16   0   0

If you decode the rather condensed table headers, you see that there is a column in the table for every attribute that you can set with SDL_GL_SetAttribute() and a few that you can't. The following describes the relationship between table columns and attributes.

  • Vis ID (Visual ID). The name of the visual. SDL hides this detail from you.

  • Vis Depth (Visual depth). The total number of bits of color information. It doesn't say anything about the actual size of a pixel.

  • Visual Type. There are many different ways to represent a pixel and they all have names. DirectColor gives the best possible color, followed by TrueColor. SDL tries to get a DirectColor visual, but will settle for what it can get.

  • Transparent. Does this buffer support transparency? Transparency is required when the display has more than one layer. OpenGL layers are not supported in SDL.

  • Buff Size (SDL_GL_BUFFER_SIZE). The actual size, in bits, of the memory used to store color information.

  • Level. The level of the OpenGL buffer. The main buffer is level 0 (zero). Underlay buffers have negative level numbers and overlay buffers have positive level numbers. OpenGL layers are not supported by SDL.

  • Render Type. There are two basically different kinds of pixels. There are pixels that are made up of separate red, green, blue, and sometimes alpha color components. And there are pixels that are indexes into a table that contains the color information. Most 8-bit displays store indexes. This column in the table just tells you if the pixels contain color information or if they are indexes into a color table.

  • DB (SDL_GL_DOUBLEBUFFER). This column tells whether or not the visual is double-buffered.

  • Stereo (SDL_GL_STEREO). This column tells you whether or not the visual supports stereo viewing.

  • RGBA Sz (SDL_GL_RED_SIZE, SDL_GL_GREEN_SIZE, SDL_GL_BLUE_SIZE, SDL_GL_ALPHA_SIZE). The actual number of bits used to store each color value. Notice that in the 16-bit formats green is given an extra bit. That is done for two reasons. The obvious one is to use all 16 bits. The other is that the human eye is more sensitive to green than to the other colors, so giving an extra bit to green makes the picture look better. There are many other pixel formats supported by hardware.

  • Aux Buf (Auxiliary Buffers). Some implementations of OpenGL support buffers that you can draw into, but not see. These are called auxiliary buffers.

  • Depth (SDL_GL_DEPTH_SIZE). The number of bits of Z, or depth, information. This is usually either 0, 16, or 24.

  • Stencil (SDL_GL_STENCIL_SIZE). The number of bits of stencil buffer data.

  • Accum Buffers RGBA (SDL_GL_ACCUM_RED_SIZE, SDL_GL_ACCUM_GREEN_SIZE, SDL_GL_ACCUM_BLUE_SIZE, SDL_GL_ACCUM_ALPHA_SIZE). The number of bits of color information stored in the accumulation buffers.

  • MS Num (SDL_GL_MULTISAMPLESAMPLES). A multisample buffer has some number of "samples" for each pixel in the color buffer. This value is the number of samples per pixel.

  • MS Bufs (SDL_GL_MULTISAMPLEBUFFERS). The number of multisample buffers available.

SDL selects which visual to use by comparing the values of the attributes you specified to the rows in the visual table. Any attributes you did not set are treated as having a value of zero. SDL looks down the list until it finds a row in which all of the attributes of the visual are greater than or equal to the attribute values you specified. Because it uses a less-than-or-equal test, the smaller the value of the attribute, the greater the chance that the computer supports a compatible visual.

Pages: 1, 2

Next Pagearrow




Linux Online Certification

Linux/Unix System Administration Certificate Series
Linux/Unix System Administration Certificate Series — This course series targets both beginning and intermediate Linux/Unix users who want to acquire advanced system administration skills, and to back those skills up with a Certificate from the University of Illinois Office of Continuing Education.

Enroll today!


Linux Resources
  • Linux Online
  • The Linux FAQ
  • linux.java.net
  • Linux Kernel Archives
  • Kernel Traffic
  • DistroWatch.com


  • Sponsored by: