Sdl

SDL é uma API para interagir com dispositivos do Sistema como por exemplo o CD-rom e Joysticks.
Ela foi desenvolvida pela Loki Games para facilitar o desenvolvimento de jogos livre de plataforma (Windows e Linux), sendo o líder de projeto original Sam Latinga

Características

  • Portável (livre de plataforma)
  • código-fonte aberto
  • Usada por diversos softwares

Exemplos

Criando um janela com SDL + OpenGL: http://www.pontov.com.br/site/index.php?option=com_content&view=article&id=142:criando-uma-janela-opengl&catid=56:opengl&Itemid=57

Uso de Joystick

xxx

APIs auxiliares

A API SDL possui diversas bibliotecas auxiliares que implementam diversas funcionalidades uteis. Uma delas e a SDL_Image que possibilita que imagens JPEG, PNG, e TIFF sejam carregadas.
O link para a biblioteca SDL_Image e http://www.libsdl.org/projects/SDL_image

SDL Image

A API SDL Image permite o carregamento de diversos formatos de imagem. Estes formatos incluem o próprio .bmp, o png, o jpeg e o gif.

Para se utilizar a biblioteca basta configurá-la da mesma forma que qualquer outra biblioteca C, ou seja, dizer ao compilador e ao linker os diretórios em que os .h e .lib estão. Depois no código basta chamar a função IMG_Load no lugar da função SDL_LoadBMP.

SDL ttf

A API SDL ttf serve para carregar fontes truetype e possibilitar seu uso em aplicações SDL

SDL Mixer

A API SDL Mixer permite a execução de arquivos de som em aplicações SDL

Ligações para outras linguagens

Java]: SDLJava
Python: Pygame

SDL2

A SDL2 é a versão mais nova da SDL. Dentre as novidades estão o suporte a Opengl 3+ e Android.

Caracteristicas

  • Suporte a texturas
  • Suporte a APIs graficas 3D (OGL, DX)
  • Suporte a haptico (vibracao nos controladores)
  • Suporte a Android

Instalação

Linux

A forma mais simples é instalar usando o gerenciador de pacotes da tua distribuição. No Ubuntu a linha de comando é a seguinte:

sudo apt install libsdl2-dev

Exemplo de codigo

Exemplo simples SDL2 + OpenGL 3.2

#include <iostream>
 
#include <GL/gl.h>
#include <SDL2/SDL.h>
 
using namespace std;
 
const char* PROGRAM_NAME = "OPENGL PROGRAM";
 
/* A simple function that prints a message, the error code returned by SDL,
 * and quits the application */
void sdldie(const char *msg)
{
    printf("%s: %s\n", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}
 
void checkSDLError(int line = -1)
{
#ifndef NDEBUG
    const char *error = SDL_GetError();
    if (*error != '\0')
    {
        printf("SDL Error: %s\n", error);
        if (line != -1)
            printf(" + line: %i\n", line);
        SDL_ClearError();
    }
#endif
}
 
int main(int argc, char *argv[])
{
    SDL_Window *mainwindow; /* Our window handle */
    SDL_GLContext maincontext; /* Our opengl context handle */
 
    if (SDL_Init(SDL_INIT_VIDEO) < 0) /* Initialize SDL's Video subsystem */
        sdldie("Unable to initialize SDL"); /* Or die on error */
 
    /* Request opengl 3.2 context.
     * SDL doesn't have the ability to choose which profile at this time of writing,
     * but it should default to the core profile */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
 
    /* Turn on double buffering with a 24bit Z buffer.
     * You may need to change this to 16 or 32 for your system */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
    /* Create our window centered at 512x512 resolution */
    mainwindow = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (!mainwindow) /* Die if creation failed */
        sdldie("Unable to create window");
 
    checkSDLError(__LINE__);
 
    /* Create our opengl context and attach it to our window */
    maincontext = SDL_GL_CreateContext(mainwindow);
    checkSDLError(__LINE__);
 
    /* This makes our buffer swap syncronized with the monitor's vertical refresh */
    SDL_GL_SetSwapInterval(1);
 
    /* Clear our buffer with a red background */
    glClearColor ( 1.0, 0.0, 0.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    /* Swap our back buffer to the front */
    SDL_GL_SwapWindow(mainwindow);
    /* Wait 2 seconds */
    SDL_Delay(2000);
 
    /* Same as above, but green */
    glClearColor ( 0.0, 1.0, 0.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    SDL_GL_SwapWindow(mainwindow);
    SDL_Delay(2000);
 
    /* Same as above, but blue */
    glClearColor ( 0.0, 0.0, 1.0, 1.0 );
    glClear ( GL_COLOR_BUFFER_BIT );
    SDL_GL_SwapWindow(mainwindow);
    SDL_Delay(2000);
 
    /* Delete our opengl context, destroy our window, and shutdown SDL */
    SDL_GL_DeleteContext(maincontext);
    SDL_DestroyWindow(mainwindow);
    SDL_Quit();
 
    return 0;
}

SDL2 + OpenGL 3.1

// Using SDL and standard IO
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <stdio.h>
#include <string>
 
// Starts up SDL and creates window
bool init();
 
// Initializes matrices and clear color
bool initGL();
 
// Renders quad to the screen
void render();
 
// Frees media and shuts down SDL
void close();
 
// Shader loading utility programs
void printProgramLog( GLuint program );
void printShaderLog( GLuint shader );
 
// The window we'll be rendering to
SDL_Window* gWindow = NULL;
 
// OpenGL context
SDL_GLContext gContext;
 
// Render flag
bool gRenderQuad = true;
 
// Graphics program
GLuint gProgramID = 0;
GLint gVertexPos2DLocation = -1;
GLuint gVBO = 0;
GLuint gIBO = 0;
 
bool init()
{
    // Initialization flag
    bool success = true;
 
    // Initialize SDL
    if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_AUDIO) < 0 )
    {
        printf("SDL COuld not be initialized: %s\n", SDL_GetError());
        success = false;
    }
    else
    {
        // Use OpenGL 2.1
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
 
        // Create window
        gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                   640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
        if( gWindow == NULL )
        {
            printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
            success = false;
        }
        else
        {
            // Create context
            gContext = SDL_GL_CreateContext( gWindow );
            if( gContext == NULL )
            {
                printf( "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError() );
            }
            else
            {
                // Initialize GLEW
                glewExperimental = GL_TRUE;
                GLenum glewError = glewInit();
                if( glewError != GLEW_OK )
                {
                    printf(  "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) );
                }
 
                // Use Vsync
                if( SDL_GL_SetSwapInterval( 1 ) < 0 )
                {
                    printf( "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() );
                }
 
                // Initialize OpenGL
                if( !initGL() )
                {
                    printf( "Unable to initialize OpenGL!\n" );
                    success = false;
                }
            }
        }
    }
 
    return success;
}
 
bool initGL()
{
    // Success flag
    bool success = true;
 
    // Generate Program
    gProgramID = glCreateProgram();
 
    // Create vertex shader
    GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
 
    // Get vertex source
    const GLchar* vertexShaderSource[] =
    {
        "#version 140\nin vec2 LVertexPos2D; void main() { gl_Position = vec4( LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); }"
    };
 
    // Set vertex source
    glShaderSource( vertexShader, 1, vertexShaderSource, NULL );
 
    // Compile vertex source
    glCompileShader( vertexShader );
 
    // Check vertex shader for errors
    GLint vShaderCompiled = GL_FALSE;
    glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &vShaderCompiled );
 
    if( vShaderCompiled != GL_TRUE )
    {
        printf( "Unable to compile vertex shader: %d!\n", vertexShader );
        printShaderLog( vertexShader );
        success = false;
    }
    else
    {
        // Attach vertex shader to program
        glAttachShader( gProgramID, vertexShader );
 
        // Create fragment shader
        GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
 
        // Get fragment source
        const GLchar* fragmentShaderSource[] =
        {
            "#version 140\nout vec4 LFragment; void main() { LFragment = vec4( 1.0, 1.0, 1.0, 1.0 ); }"
        };
 
        // Set fragment source
        glShaderSource( fragmentShader, 1, fragmentShaderSource, NULL );
 
        // Compile fragment source
        glCompileShader( fragmentShader );
 
        // Check fragment shader for errors
        GLint fShaderCompiled = GL_FALSE;
        glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &fShaderCompiled );
 
        if( fShaderCompiled != GL_TRUE )
        {
            printf( "Unable to compile fragment shader: %d!\n", fragmentShader );
            printShaderLog( fragmentShader );
            success = false;
        }
        else
        {
            // Attach fragment shader to program
            glAttachShader( gProgramID, fragmentShader );
 
            // Link program
            glLinkProgram( gProgramID );
 
            // Check for errors
            GLint programSuccess = GL_TRUE;
            glGetProgramiv( gProgramID, GL_LINK_STATUS, &programSuccess );
            if( programSuccess != GL_TRUE )
            {
                printf( "Error linking program %d!\n", gProgramID );
                printProgramLog( gProgramID );
                success = false;
            }
            else
            {
                // Get vertex attribute location
                gVertexPos2DLocation = glGetAttribLocation( gProgramID, "LVertexPos2D" );
                if( gVertexPos2DLocation == -1 )
                {
                    printf( "LVertexPos2D is not a valid glsl program variable!\n" );
                    success = false;
                }
                else
                {
                    // Initialize clear color
                    glClearColor( 0.f, 0.f, 0.f, 1.f );
 
                    // VBO data
                    GLfloat vertexData[] =
                    {
                        -0.5f, -0.5f,
                         0.5f, -0.5f,
                         0.5f,  0.5f,
                        -0.5f,  0.5f
                    };
 
                    // IBO data
                    GLuint indexData[] = { 0, 1, 2, 3 };
 
                    // Create VBO
                    glGenBuffers( 1, &gVBO );
                    glBindBuffer( GL_ARRAY_BUFFER, gVBO );
                    glBufferData( GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW );
 
                    // Create IBO
                    glGenBuffers( 1, &gIBO );
                    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
                    glBufferData( GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW );
                }
            }
        }
    }
 
    return success;
}
 
void render()
{
    // Clear color buffer
    glClear( GL_COLOR_BUFFER_BIT );
 
    // Render quad
    if( gRenderQuad )
    {
        // Bind program
        glUseProgram( gProgramID );
 
        // Enable vertex position
        glEnableVertexAttribArray( gVertexPos2DLocation );
 
        // Set vertex data
        glBindBuffer( GL_ARRAY_BUFFER, gVBO );
        glVertexAttribPointer( gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof( GLfloat ), NULL );
 
        // Set index data and render
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
        glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL );
 
        // Disable vertex position
        glDisableVertexAttribArray( gVertexPos2DLocation );
 
        // Unbind program
        glUseProgram( NULL );
    }
}
 
void close()
{
    // Deallocate program
    glDeleteProgram( gProgramID );
 
    SDL_DestroyWindow(gWindow);
    gWindow = NULL;
 
    // Quit SDL subsystems
    SDL_Quit();
}
 
void printProgramLog(GLuint program)
{
    // Make sure name is program
    if( glIsProgram( program ) )
    {
        // Program log length
        int infoLogLength = 0;
        int maxLength = infoLogLength;
 
        // Get info string length
        glGetProgramiv( program, GL_INFO_LOG_LENGTH, &maxLength );
 
        // Allocate string
        char* infoLog = new char[ maxLength ];
 
        // Get info log
        glGetProgramInfoLog( program, maxLength, &infoLogLength, infoLog );
        if( infoLogLength > 0 )
        {
            // Print log
            printf( "%s\n", infoLog );
        }
 
        // Deallocate string
        delete[] infoLog;
    }
    else
    {
        printf( "Name %d is not a program\n", program );
    }
}
 
void printShaderLog(GLuint shader)
{
    // Make sure name is shader
    if( glIsShader( shader ) )
    {
        // Shader log length
        int infoLogLength = 0;
        int maxLength = infoLogLength;
 
        // Get info string length
        glGetProgramiv( shader, GL_INFO_LOG_LENGTH, &maxLength );
 
        // Allocate string
        char* infoLog = new char[ maxLength ];
 
        // Get info log
        glGetShaderInfoLog( shader, maxLength, &infoLogLength, infoLog );
        if( infoLogLength > 0 )
        {
            // Print log
            printf( "%s\n", infoLog );
        }
 
        // Deallocate string
        delete[] infoLog;
    }
    else
    {
        printf( "Name %d is not a program\n", shader );
    }
}
 
int main( int argc, char *args[] )
{
    // Start up SDL and create window
    if( !init())
    {
        printf("Failed to initialize");
    }
    else
    {
        bool quit = false;
 
        // Event handler
        SDL_Event e;
 
        // Enable text input
        SDL_StartTextInput();
 
        // While application is running
        while( !quit )
        {
            // Handle events on queue
            while( SDL_PollEvent( &e ) != 0 )
            {
                // User requests quit
                if( e.type == SDL_QUIT )
                {
                    quit = true;
                }
                else if( e.type == SDL_KEYDOWN )
                {
                    if( e.key.keysym.sym == SDLK_ESCAPE ){
                        quit = true;
                    }
                }
            }
 
            // Render quad
            render();
 
            // Update Screen
            SDL_GL_SwapWindow( gWindow );
        }
 
        // Disable text input
        SDL_StopTextInput();
    }
 
    // Free resources and close SDL
    close( );
 
    return 0;
}

Links

http://www.libsdl.org/ Página oficial da SDL
http://sdljava.sourceforge.net/ SDLJava
http://www.pygame.org/news.html PyGame

Tutoriais

http://lazyfoo.net/tutorials/SDL/index.php SIte muito bom com uma seção dedicada de artigos referente a tutoriais SDL2
https://wiki.libsdl.org/Tutorials Listagem de páginas com tutoriais sobre SDL

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.