Sol on Immediate Mode GUIs (IMGUI)

01 - Groundwork

This chapter goes through the basic SDL framework application we're going to use to build the IMGUI widgets on.

Those familiar with SDL may wish to skip to the next chapter; this one is here mostly for the benefit of those who either don't know SDL, don't need to know SDL, or have used SDL long ago and don't remember how things went again.

Grab the source code, and plug it into the SDL environment, compile and run.

This is what it's supposed to look like:

At the top of the source file, we have a couple of includes. (If you're not working on windows environment, you may wish to change the SDL include to "SDL/SDL.h").

After that, we have our first global variable:

// Screen surface
SDL_Surface *gScreen;

This is the pointer to the display (be it fullscreen or windowed surface), and all visible things are rendered using this pointer.

Next, we have a simple wrapper for the SDL's fillrect function so that we don't need to define SDL_Rects every time we need to fill a rectangle:

// Simplified interface to SDL's fillrect call
void drawrect(int x, int y, int w, int h, int color)
{
  SDL_Rect r;
  r.x = x;
  r.y = y;
  r.w = w;
  r.h = h;
  SDL_FillRect(gScreen, &r, color);
}

This is followed by a very simple (for now) rendering function:

// Rendering function
void render()
{   
  // clear screen
  drawrect(0,0,640,480,0);

  // test that the fillrect is working
  drawrect(64,48,64,48,0xff);

  // update the screen
  SDL_UpdateRect(gScreen, 0, 0, 640, 480);    

  // don't take all the cpu time
  SDL_Delay(10); 
}

The above is, I hope, relatively self-describing.

What remains is the main function, which consists of two parts; initialization, and the event loop.

// Entry point
int main(int argc, char *argv[])
{
  // Initialize SDL's subsystems - in this case, only video.
  if (SDL_Init(SDL_INIT_VIDEO) < 0) 
  {
    fprintf(stderr, &quot;Unable to init SDL: %s\n&quot;, SDL_GetError());
    exit(1);
  }

  // Register SDL_Quit to be called at exit; makes sure things are
  // cleaned up when we quit.
  atexit(SDL_Quit);
    
  // Attempt to create a 640x480 window with 32bit pixels.
  gScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
  
  // If we fail, return error.
  if (gScreen == NULL) 
  {
    fprintf(stderr, &quot;Unable to set up video: %s\n&quot;, SDL_GetError());
    exit(1);
  }

The initialization bit simply initializes SDL, creates a 640x480 window, and quits if something goes wrong. On systems where applications are launched through consoles, the user may actually receive some kind of error message. Which, we hope, will never happen.

// Main loop: loop forever.
  while (1)
  {
    // Render stuff
    render();

    // Poll for events, and handle the ones we care about.
    SDL_Event event;
    while (SDL_PollEvent(&event)) 
    {
      switch (event.type) 
      {
      case SDL_KEYUP:
                    
        switch (event.key.keysym.sym)
        {
        case SDLK_ESCAPE:
          // If escape is pressed, return (and thus, quit)
          return 0;
        }
        break;
      case SDL_QUIT:
        return(0);
      }
    }
  }
  return 0;
}

The rest of the source consists of the main loop, which simply calls render and checks if there's any messages. In this primitive state, we're simply checking for escape and quiting.

Next: 02 - UI State

Problems? Ideas? Try the forums.

Any comments etc. can be emailed to me.