1

Temat: Ustawienie palety przez SDL

Cały wieczór dzisiaj spędziłem próbując ustawić paletę przez SDL i *ponownie* nie udało mi się (jakiś kawałek czasu temu po raz pierwszy chciałem to osiągnąć i spędziłem wtedy chyba ze 3 dni, ale w końcu się poddałem)
Może ktoś się dopatrzy czegoś co robię źle.

Generalnie robię to jak poniżej, ładuję bmp SDLową funkcją (choć i czytałem już specyfikację BMP i mam też własną funkcję ładującą BMP) potem buduję sobie paletę i SDLową funkcją ją ustawiam, i wg mojego rozumowania to powinno działać.

    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return 1;
    }
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    for (x = 0; x <256; x++)    
    {
    strcpy(s1, "screen po setvideomode: ");
    sprintf(s2, "indeks = %i | r: %i g: %i b: %i", x, screen->format->palette->colors[x].r, screen->format->palette->colors[x].g, screen->format->palette->colors[x].b);
    strcat(s1, s2);
    loguj(s1);        
    }        
    
    if( screen == NULL )
        return 1;

    background = load_image( "data/images/title.bmp" );
    
    for (x = 0; x < 256; x++)
    {
        paleta[x].r = background->format->palette->colors[x].r;
        paleta[x].g = background->format->palette->colors[x].g;
        paleta[x].b = background->format->palette->colors[x].b;
    }    

    for (x = 0; x <256; x++)    
    {
    strcpy(s1, "background po zaladowa: ");
    sprintf(s2, "indeks = %i | r: %i g: %i b: %i", x, paleta[x].r, paleta[x].g, paleta[x].b);
    strcat(s1, s2);
    loguj(s1);        
    }        
    
    if (!SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, paleta, 0, 256))
    {
        loguj("problem z ustawieniem palety1");
    }
    
    SDL_BlitSurface(background, NULL, screen, NULL);
    
    SDL_Flip(screen);
    
    SDL_Delay(1000);

Niemniej kolory są zawsze nie takie jak w pliku. Jeśli z takiego wczytanego BMPka do struktury SDLowej "zbieram" sobie paletę i loguję ją do pliku, to te wartości r, g i b są jakieś zupełnie inne. Co prawda nie wygląda to jak kompletnie losowe wartości:

background po zaladowa: indeks = 0 | r: 0 g: 0 b: 0
background po zaladowa: indeks = 1 | r: 0 g: 0 b: 85
background po zaladowa: indeks = 2 | r: 0 g: 0 b: 170
background po zaladowa: indeks = 3 | r: 0 g: 0 b: 255
background po zaladowa: indeks = 4 | r: 0 g: 36 b: 0
background po zaladowa: indeks = 5 | r: 0 g: 36 b: 85
background po zaladowa: indeks = 6 | r: 0 g: 36 b: 170
background po zaladowa: indeks = 7 | r: 0 g: 36 b: 255
background po zaladowa: indeks = 8 | r: 0 g: 73 b: 0
background po zaladowa: indeks = 9 | r: 0 g: 73 b: 85
background po zaladowa: indeks = 10 | r: 0 g: 73 b: 170
background po zaladowa: indeks = 11 | r: 0 g: 73 b: 255
...
ciach
...
background po zaladowa: indeks = 245 | r: 255 g: 182 b: 85
background po zaladowa: indeks = 246 | r: 255 g: 182 b: 170
background po zaladowa: indeks = 247 | r: 255 g: 182 b: 255
background po zaladowa: indeks = 248 | r: 255 g: 219 b: 0
background po zaladowa: indeks = 249 | r: 255 g: 219 b: 85
background po zaladowa: indeks = 250 | r: 255 g: 219 b: 170
background po zaladowa: indeks = 251 | r: 255 g: 219 b: 255
background po zaladowa: indeks = 252 | r: 255 g: 255 b: 0
background po zaladowa: indeks = 253 | r: 255 g: 255 b: 85
background po zaladowa: indeks = 254 | r: 255 g: 255 b: 170
background po zaladowa: indeks = 255 | r: 255 g: 255 b: 255

tylko faktycznie jak jakaś paleta, ale zupełnie nie ta która była oryginalnie w BMP.

A tu jak co jest calutki kod który w trybie 640x480x8 próbuje wczytać plik BMP i po prostu go wyświetlić:

#include "SDL/SDL.h"

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 8;

SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *fafa = NULL;

char s1[100], s2[100];

void loguj (char str[])
{
    FILE *plik;
    plik = fopen("log.txt", "a");
    fprintf(plik, "%s\n", str);
    fclose(plik);
}

SDL_Surface *load_image( char filename[] )
{
    SDL_Surface* loadedImage = NULL;
    SDL_Surface* optimizedImage = NULL;

    loadedImage = SDL_LoadBMP( filename );
    if( loadedImage != NULL )
    {
        optimizedImage = SDL_DisplayFormat( loadedImage );
        SDL_FreeSurface( loadedImage );
    }
    return optimizedImage;
}

int main( int argc, char* args[] )
{    
    SDL_Event event;
    SDLKey key;
    int x, y, indeks_pal;
    int koniec = 0;
    Uint8 *pixel_addr;
    SDL_Color paleta[256];
    
    for (x = 0; x < 256; x++)
    {
        paleta[x].r = x;
        paleta[x].g = x;
        paleta[x].b = x;
    }
    
for (x = 0; x <256; x++)    
{
strcpy(s1, "szara paleta: ");
sprintf(s2, "indeks = %i | r: %i g: %i b: %i", x, paleta[x].r, paleta[x].g, paleta[x].b);
strcat(s1, s2);
loguj(s1);        
}    

    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return 1;
    }
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    for (x = 0; x <256; x++)    
    {
    strcpy(s1, "screen po setvideomode: ");
    sprintf(s2, "indeks = %i | r: %i g: %i b: %i", x, screen->format->palette->colors[x].r, screen->format->palette->colors[x].g, screen->format->palette->colors[x].b);
    strcat(s1, s2);
    loguj(s1);        
    }        
    
    if( screen == NULL )
        return 1;

    background = load_image( "data/images/title.bmp" );
    
    for (x = 0; x < 256; x++)
    {
        paleta[x].r = background->format->palette->colors[x].r;
        paleta[x].g = background->format->palette->colors[x].g;
        paleta[x].b = background->format->palette->colors[x].b;
    }    

    for (x = 0; x <256; x++)    
    {
    strcpy(s1, "background po zaladowa: ");
    sprintf(s2, "indeks = %i | r: %i g: %i b: %i", x, paleta[x].r, paleta[x].g, paleta[x].b);
    strcat(s1, s2);
    loguj(s1);        
    }        
    
    if (!SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, paleta, 0, 256))
    {
        loguj("problem z ustawieniem palety1");
    }
    
    SDL_BlitSurface(background, NULL, screen, NULL);
    
    SDL_Flip(screen);
    
    SDL_Delay(1000);
    
    if (!SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, paleta, 0, 256))
    {
        loguj("problem z ustawieniem palety2");
    }    
    
    SDL_Delay(1000);
    
    indeks_pal = 0;

    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
    
    for (x = 0; x < 640; x = x + 5 )
    {
        for (y = 0; y < 200; y++)
        {
            pixel_addr = (Uint8 *)screen->pixels + (screen->pitch * y) + x;
            *pixel_addr = indeks_pal;
            pixel_addr++;
            *pixel_addr = indeks_pal;
            pixel_addr++;
            *pixel_addr = indeks_pal;
            pixel_addr++;
            *pixel_addr = indeks_pal;
            pixel_addr++;
            *pixel_addr = indeks_pal;            
            
        }
        for (y = 200; y < 400; y++)
        {
            pixel_addr = (Uint8 *)screen->pixels + (screen->pitch * y) + x;
            *pixel_addr = indeks_pal + 128;
            pixel_addr++;
            *pixel_addr = indeks_pal + 128;
            pixel_addr++;
            *pixel_addr = indeks_pal + 128;
            pixel_addr++;
            *pixel_addr = indeks_pal + 128;
            pixel_addr++;
            *pixel_addr = indeks_pal + 128;        
            
        }        
        indeks_pal++;
    }
    
    if( SDL_Flip( screen ) == -1 )
        return 1;
    
    while (!koniec)
    {
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_KEYDOWN)
            {
                key = event.key.keysym.sym;
                
                if (key == SDLK_ESCAPE)
                    koniec = 1;
            }
        }
    }

    SDL_FreeSurface( background );
    SDL_Quit();
    return 0;
}

A cały plik logujący dane z palet załączam do tematu.
O co tutaj chodzi?

Ostatnio edytowany przez jury (2020-12-26 23:08:25)

Post's attachments

log.txt 41.73 kb, liczba pobrań: 3 (od 2020-12-26) 

Tylko zalogowani mogą pobierać załączniki.

2

Odp: Ustawienie palety przez SDL

Nie znam się, ale pamiętasz o indianach? (mały indianin i duży indianin czyli intel vs motorola)? Bo tu może być problem, a bitmapy to według procka zapisywane były i chyba tak już zostało...

Sikor umarł...

3

Odp: Ustawienie palety przez SDL

Dzięki za sugestię, ale na razie robię tylko tryb kolorów 8bit, więc endian'y mnie nie dotyczą.
Coś mi przyszło do głowy jeszcze wczoraj, więc będę to dzisiaj jakoś sprawdzał.

Edit: OK, temat nieaktualny. Rozpierdzuchę palety robi funkcja SDL_DisplayFormat wywołana zbyt wcześnie. I to w sumie jest dość zrozumiałe, ale nie rozumiem dlaczego mimo wszystko jak później dostarczymy paletę, to z grafiki robi się mocno psychodeliczny twór. To znaczy, oczywiście odpowiedzialna za to jest zapewne również SDL_DisplayFormat, ale przynajmniej na razie już nie wnikam co i jak bo osiągnąłem to co mi obecnie potrzebne.

Ostatnio edytowany przez jury (2020-12-27 18:14:30)