Exemplos de Vídeo

Iniciando o Display de Vídeo

    SDL_Surface *screen;

    /* Inicializa a biblioteca SDL */
    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "Não pode iniciar SDL: %s\n", SDL_GetError());
        exit(1);
    }

    /* Limpa e sai */
    atexit(SDL_Quit);

    /* Inicia o vídeo em um modo 640x480 usando uma paleta de 8-bits */
    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);

    if ( screen == NULL ) {
        fprintf(stderr, "Não foi possível estabelecer o modo 640x480x8: %s\n",                     SDL_GetError());
        exit(1);
    }

Iniciando o Melhor Modo de Vídeo

    /* Tem preferência por 8-bits, mas aceita qualquer outra profundidade */
    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);

    if ( screen == NULL ) {
        fprintf(stderr, "Não foi possível estabelecer o modo 640x480x8: %s\n",                       SDL_GetError());

        exit(1);
    }

    printf("Estabelecendo o modo 640x480 a %d bits-por-pixel \n", screen->format->BitsPerPixel);

Carregando e Mostrando um Arquivo BMP

    SDL_Surface *image;
    SDL_Rect dest;
    int ncolors, i;
    SDL_Color *colors;

    /* Carrega um arquivo BMP em uma surface */
    image = SDL_LoadBMP("sample.bmp");

    if ( image == NULL ) {
        fprintf(stderr, "Não pode carregar sample.bmp: %s\n", SDL_GetError());
        return;
    }

    /* Estabelece as cores do vídeo – SDL_SetColors() só funciona em 
       displays paletizados, mas ele não funciona em displays HiColor ou  
       TrueColor.
       Se as cores do vídeo já tiverem sido estabelecidas, este passo pode ser
       pulado, e a biblioteca irá mapear as imagens automaticamente para
       as cores atuais do vídeo.
    */

    if ( image->format->palette ) {
        ncolors = image->format->palette->ncolors;
        colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
        memcpy(colors, image->format->palette->colors, ncolors);
    } 
    else {
        int r, g, b;

        /* Aloca uma paleta de 256 cores */
        ncolors = 256;
        colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));

        /* Define um cubo colorido 3,3,2 */
        for ( r=0; r<8; ++r ) {
            for ( g=0; g<8; ++g ) {
                for ( b=0; b<4; ++b ) {
                    i = ((r<<5)|(g<<2)|b);
                    colors[i].r = r<<5;
                    colors[i].g = g<<5;
                    colors[i].b = b<<6;
                }
            }
        }

        /* Nota: A melhor maneira de alocar uma paleta pode ser 
           calcular a freqüência de cores na imagem e criar uma
           paleta baseada nessa informação.
        */
    }

    /* Define um mapa de cores, teste para todas as cores, mas não se preocupe com isso */
    SDL_SetColors(screen, colors, 0, ncolors);
    free(colors);

    /* Blita na surface de vídeo */
    dest.x = 0;
    dest.y = 0;
    dest.w = image->w;
    dest.h = image->h;

    SDL_BlitSurface(image, NULL, screen, &dest);
    SDL_UpdateRects(screen, 1, &dest);

    /* Libera o bitmap alocado */
    SDL_FreeSurface(image);
    return;

Desenhando Diretamente no Vídeo

    /* Código para colocar um pixel amarelo no centro da tela */
    Sint32   X, Y;
    Uint32   pixel;
    Uint8   *bits, bpp;

    /* Mapeie a cor amarela para o vídeo (R=0xFF, G=0xFF, B=0x00)
       Nota: Se o vídeo for paletizado, você deve estabelecer a paleta primeiro.
    */

    pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00);

    /* Calcula o framebuffer offset do centro do vídeo */
    if ( SDL_MUSTLOCK(screen) ) {
        if ( SDL_LockSurface(screen) < 0 )
            return;
    }
    bpp = screen->format->BytesPerPixel;
    X = screen->w/2;
    Y = screen->h/2;
    bits = ((Uint8 *)screen->pixels)+Y*screen->pitch+X*bpp;

    /* Define o pixel */
    switch(bpp) {
        case 1:
            *((Uint8 *)(bits)) = (Uint8)pixel;
            break;

        case 2:
            *((Uint16 *)(bits)) = (Uint16)pixel;
            break;

        case 3: { /* Independente do formato */
            Uint8 r, g, b;

            r = (pixel>>screen->format->Rshift)&0xFF;
            g = (pixel>>screen->format->Gshift)&0xFF;
            b = (pixel>>screen->format->Bshift)&0xFF;

            *((bits)+screen->format->Rshift/8) = r; 
            *((bits)+screen->format->Gshift/8) = g;
            *((bits)+screen->format->Bshift/8) = b;
            }
            break;

        case 4:
            *((Uint32 *)(bits)) = (Uint32)pixel;
            break;
    }

    /* Atualiza a tela */
    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }

    SDL_UpdateRect(screen, X, Y, 1, 1);
    return;

O Mais Rápido Blit de Surface Possível

Existem três maneiras diferentes em que você pode desenhar uma imagem no vídeo:

  1. Criar uma surface e blitar ela no vídeo com SDL_BlitSurface

  2. Criar a surface de vídeo na memória do sistema e chamar SDL_UpdateRect

  3. Criar a surface de vídeo na memória de vídeo e chamar SDL_LockSurface

A melhor maneira de fazer isso é combinar os métodos:

#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_timer.h"

void ComplainAndExit(void)
{
    fprintf(stderr, "Problema: %s\n", SDL_GetError());
    exit(1);
}

int main(int argc, char *argv[])
{
    SDL_PixelFormat fmt;
    SDL_Surface *screen, *locked;
    SDL_Surface *imagebmp, *image;
    SDL_Rect dstrect;
    int i;
    Uint8 *buffer;

    /* Inicializa a SDL */
    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        ComplainAndExit();
    }
    atexit(SDL_Quit);

    /* Carrega uma imagem BMP em uma surface */
    imagebmp = SDL_LoadBMP("image.bmp");

    if ( imagebmp == NULL ) {
        ComplainAndExit();
    }

    /* Estabelece o modo de vídeo (640x480 na profundidade(depth) nativa) */
    screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);

    if ( screen == NULL ) {
        ComplainAndExit();
    }

    /* Definindo o mapa de cores do vídeo */
    if ( imagebmp->format->palette != NULL ) {
        SDL_SetColors(screen,
                      imagebmp->format->palette->colors, 0,
                      imagebmp->format->palette->ncolors);
    }

    /* Converte a imagem para o formato do vídeo (mapa de cores) */
    image = SDL_DisplayFormat(imagebmp);
    SDL_FreeSurface(imagebmp);

    if ( image == NULL ) {
        ComplainAndExit();
    }

    /* Desenha faixas coloridas na surface */
    if ( SDL_MUSTLOCK(screen) ) {
        if ( SDL_LockSurface(screen) < 0 )
            ComplainAndExit();
    }

    buffer=(Uint8 *)screen->pixels;

    for ( i=0; i<screen->h; ++i ) {
        memset(buffer,(i*255)/screen->h, screen->w*screen->format->BytesPerPixel);
               buffer += screen->pitch;
    }

    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }

    /* Blita a imagem no centro da tela */
    dstrect.x = (screen->w-image->w)/2;
    dstrect.y = (screen->h-image->h)/2;
    dstrect.w = image->w;
    dstrect.h = image->h;

    if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) {
        SDL_FreeSurface(image);
        ComplainAndExit();
    }

    SDL_FreeSurface(image);

    /* Atualiza o vídeo */
    SDL_UpdateRects(screen, 1, &dstrect);

    SDL_Delay(5000);        /* Espera 5 segundos */
    exit(0);
}

SDLDoc-ptBR/Exemplos_Video (last edited 2008-04-17 08:18:54 by localhost)