Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) SDL example 4: moving a square in a 2D OpenGL environment

 

This SDL example shows a sprite moving a over a background, like this screenshot (png).

 

Operating system: Ubuntu

IDE: Qt Creator 2.0.0

Project type: Qt4 Console Application

Selected required modules: QtCore

Compiler: G++ 4.4.1

Additional libraries: SDL, OpenGL, Boost

 

 

 

 

 

Qt project file

 

#-------------------------------------------------
#
# Project created by QtCreator 2010-07-17T14:57:33
#
#-------------------------------------------------

QT += core

QT -= gui

TARGET = CppSdlExample4
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

LIBS += -L/usr/local/lib -lSDL
LIBS += -L/usr/local/lib -lGL
SOURCES += main.cpp

 

 

 

 

 

Source code

 

#include <cassert>
#include <cstdlib>
#include <vector>
#include <boost/timer.hpp>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

int main()
{
  const int screen_width = 320;
  const int screen_height = 200;

  //Initialization
  if( SDL_Init( SDL_INIT_VIDEO) < 0 )
  {
    assert(!"Assume SDL initialization does not fail");
  }

  //Perform SDL_Quit at program exit
  std::atexit(SDL_Quit);

  const int bits_per_pixel = 32;
  if( !SDL_SetVideoMode( screen_width, screen_height, bits_per_pixel, SDL_OPENGL ))
  {
    assert(!"Assume SDL video mode setting does not fail");
  }

  //Initialize OpenGL
  glClearColor( 0, 0, 0, 0 );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  glOrtho( 0, screen_width, screen_height, 0, -1, 1 );
  glMatrixMode( GL_MODELVIEW );
  glDisable(GL_DEPTH_TEST); //In 2D there is no need for a depth test
  glLoadIdentity();
  if( glGetError() != GL_NO_ERROR )
  {
    assert(!"Assume OpenGL initialization does not fail");
  }

  //Set up sprite
  const int sprite_width = 10;
  const int sprite_height = 10;
  int sprite_x = (screen_width / 2) - (sprite_width / 2);
  int sprite_y = (screen_height / 2) - (sprite_height / 2);
  int sprite_dx = 1;
  int sprite_dy = 1;
  const int frames_per_second = 60;
  const int ticks_per_second = 1000 / frames_per_second;

  while(1)
  {
    //Use timer to keep frame rate constant
    boost::timer timer;

    //Handle events
    SDL_Event event;
    SDL_PollEvent( &event );
    if( event.type == SDL_QUIT ) break;

    //Move the square
    sprite_x+=sprite_dx;
    sprite_y+=sprite_dy;
    //Make the square bounce
    if (sprite_x < 0 || sprite_x + sprite_width > screen_width ) sprite_dx = -sprite_dx;
    if (sprite_y < 0 || sprite_y + sprite_height > screen_height ) sprite_dy = -sprite_dy;

    //Clear the screen
    glClear( GL_COLOR_BUFFER_BIT );

    //Start showing the sprite
    glTranslatef( sprite_x, sprite_y, 0 );
    //Start drawing square
    glBegin( GL_QUADS );
    glColor4f( 1.0, 1.0, 1.0, 1.0 );
    glVertex3f( 0, 0, 0 );
    glVertex3f( sprite_width, 0, 0 );
    glVertex3f( sprite_width, sprite_height, 0 );
    glVertex3f( 0, sprite_height, 0 );
    glEnd();
    //Reset
    glLoadIdentity();

    //Update screen
    SDL_GL_SwapBuffers();

    //Keep frame rate constant
    const int ticks_elapsed = static_cast<int>(timer.elapsed() * 1000.0);
    if (timer.elapsed() < ticks_per_second)
    {
      SDL_Delay( ticks_per_second - ticks_elapsed );
    }
  }
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict