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

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?

Post's attachments

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

Tylko zalogowani mogą pobierać załączniki.

2

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 Ostatnio edytowany przez jury (2020-12-27 18:14:30)

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.