Surfaces SDL a partir de dados na memória

Hoje falaremos sobre surfaces SDL, e como criá-las a partir de dados binarios em memória.

Como sempre, estarei usando as seguintes definições de tipos de dados:


typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;

A criação de surfaces SDL a partir de arquivos de imagem é muito simples. Basta usar a função SDL_LoadBMP ou então a função IMG_Load da biblioteca SDL_Image (para poder ler imagens com outros formatos alem do BMP), como está exemplificado no codigo a seguir:


SDLSurface *surf;

// usando funçao padrao de load da biblioteca SDL 
surf = SDL_LoadBMP("imagem.bmp"); 

// usando funçao de load da biblioteca SDL_Image
surf = IMG_Load("imagem.png");

Porém, se voce usa no teu jogo um formato de arquivo binário que aglomera todos seus arquivos num só (um .dat, por exemplo), não dá para fazer load de uma surface desse jeito. Geralmente, voce extrai os dados binários dessa imagem a partir do arquivo e os coloca em uma posição de memoria. Como criar uma surface a partir desses dados?  A biblioteca SDL inclui estruturas e funções para exatamente este tipo de situação.

Primeiramente, temos a estrutura SDL_RWops. Esta estrutura vai guardar informações para que a SDL possa criar a surface. A SDL tem várias funções para criar uma SDL_RWops a partir de várias fontes, incluindo arquivos, ponteiros para estrutura FILE e, no nosso caso o que iremos usar, de dados da memória. Para tal, usamos a função SDL_RWFromMem(void*,int). Essa função recebe 2 parametros – um ponteiro para a posição de memória do vetor, e o tamanho desse vetor:


SDL_RWops *rw;
rw = SDL_RWFromMem ( (void*)dados, tamanho );

Agora que temos os dados processados, podemos criar a surface usando a função SDL_LoadBMP_RW(SDL_RWops*,int), ou entao a IMG_Load_RW(SDL_RWops*,int). Estas funções recebem 2 parametros também – o ponteiro para a estrutura SDL_RWops, e um inteiro que define se a função vai liberar automaticamente a estrutura passada (valor = 1) ou voce vai fazer isso manualmente (valor = 0).


SDL_Surface *surf;
surf = IMG_Load_RW ( rw, 1 );

Caso se passe 0 como valor, ou seja, a função não irá liberar a memoria da estrutura, usa-se a função SDL_FreeRW(SDL_RWops*) para liberar a memória.

Pronto, agora temos uma surface SDL criada com dados a partir da memória. Agora quero apenas mostrar um código extra que otimiza essa surface, melhorando a performance. Fazemos isso usando a função SDL_DisplayFormat, que transforma a surface que acabamos de criar em uma nova com o mesmo formato da tela:


SDL_Surface *surfOtimizada;
// criando surface otimizada
surfOtimizada = SDL_DisplayFormat ( surf );
// liberando memoria da surface pre-otimizada
SDL_FreeSurface ( surf );

E pronto – temos um código simples. Aqui está o código completo, dentro de uma função de uso fácil:


SDL_Surface* criaSurface ( const byte *dados, const int tamanho )
{
    SDL_RWops *rw;
    SDL_Surface *surf = 0, *surfOtimizada;

    // cria estrutura de controle
    rw = SDL_RWFromMem ( (void*)dados, tamanho );
    // cria surface pre-otimizada
    surf = IMG_Load_RW ( rw, 1 );
    // otimiza surface
    if ( surf )
    {
        surfOtimizada = SDL_DisplayFormat(surf);
        // libera memória de surface pre-otimizada
        SDL_FreeSurface(surf);
    }

    // retorna surface
    return surfOtimizada;
}

Anúncios

6 comments so far

  1. vinigodoy on

    Outro excelente artigo! Quando eu for explicar texturas no meu blog, e explicar a carga de SDL_Images, certamente vou colocar um link para cá.

    😀

  2. […] Plugin é uma pequena adição ao programa que voce pode plugar no teu software para extender as funcionalidades dele sem necessidade de recompilação. Existem diversas técnicas avançadas para criaçao de sistema de plugins, mas aqui vou exemplificar uma bem simples, que tem um pouco de relação com o assunto anterior que foi discutido. (o de carregar imagens SDL a partir de dados em memória – que voce pode acessar aqui). […]

  3. […] De novo extremamente simples. Este sistema integra muito bem com o meu antigo post sobre leitura de surfaces SDL a partir de dados na memória. […]

  4. […] zip, por exemplo, mas não nos aprofundaremos nesse tema aqui. Caso queira ler a respeito, confira esse artigo no Vertex […]

  5. Bruno on

    Depois é so usar SDL_BlitSurface e pronto?, porque aqui não ta fucionando, abri o arquivo, mas não to consiguindo mostra a imagem na tela.

  6. More Help on

    Pretty! This was a really wonderful article. Thank you for supplying these details.


Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: