Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SDL] Wycinanie fragmentów tekstury

Ostatnio zmodyfikowano 2011-11-26 16:01
Autor Wiadomość
Terminator3
Temat założony przez niniejszego użytkownika
[SDL] Wycinanie fragmentów tekstury
» 2011-11-26 14:10:39
Otóż mam problem, moja gierka będzie używała dość dużej ilości małych tekstur dlatego pomyślałem że fajnie byłoby zrobić to jako jedną teksturę (jeden plik) i program po prostu by sobie pociął odpowiednio tą teksturę, no i mam problem, robię to mniej więcej tak jak jest to napisane w kursie na tej stronie do SDL'a ale nie działa, wyskakuje mi błąd:
Unhandled exception at 0x00411aa5 in Plik.exe: 0xC0000005: Access violation reading location 0x00000004.
I przyciski: "Continue" "Break" oraz wyłączony "Ignore"

kod:
C/C++
SDL_Surface * obraz = NULL;
obraz = IMG_Load( filename );
if( !obraz )
{
    fprintf( stderr, "error: ImgToTexture could not load image \"%s\"\n", filename );
    SDL_FreeSurface( obraz );
    return ~0;
}
SDL_Surface * img = NULL;
SDL_Rect Pos;
Pos.h = 16;
Pos.w = 16;
Pos.x = x;
Pos.y = y;
SDL_BlitSurface( obraz, & Pos, img, NULL );
błąd jest najwyraźniej w kodzie wyżej ponieważ gdy spróbowałbym wczytać i bez przeróbki dać ten obrazek 'filename' to wszystko jest ok, jaszcze dalsza cześć kodu:
C/C++
unsigned int img_type = 0;

if( img->format->BitsPerPixel == 32 )
{
    img_type = GL_RGBA;
}
else if( img->format->BitsPerPixel == 24 )
{
    img_type = GL_RGB;
}
else
{
    // Convert to 32 bits.
    SDL_PixelFormat fmt = {
        NULL, 32, 4,
        0, 0, 0, 0,
        0, 8, 16, 24,
        0xff, 0xff00, 0xff0000, 0xff000000,
        0,
        0xff
    };
   
    SDL_Surface * nimg = SDL_ConvertSurface( img, & fmt, SDL_SWSURFACE );
    SDL_FreeSurface( img );
   
    if( !nimg )
    {
        fprintf( stderr, "error: ImgToTexture could not convert image to 32-bit\n" );
        return ~0;
    }
   
    // Done converting.
    img = nimg;
    img_type = GL_RGBA;
}

// Create texture.
unsigned int texture_id = ~0;
glGenTextures( 1, & texture_id );
glBindTexture( GL_TEXTURE_2D, texture_id );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

// You might want to play with these parameters.
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

// Gen texture.
glTexImage2D( GL_TEXTURE_2D, 0, img_type, img->w, img->h,
0, img_type, GL_UNSIGNED_BYTE, img->pixels );

printf( "info: ImgToTexture loaded texture %u\n", texture_id );

// Done
SDL_FreeSurface( img );
return texture_id;
P-44730
DejaVu
» 2011-11-26 14:14:06
Nie polecam stosować zbyt dużych obrazków. Ja musiałem dzielić jeden obraz na kilka mniejszych aby system XP go 'łyknął' podczas gdy na win 7 działało wszystko cacy :)
P-44732
Terminator3
Temat założony przez niniejszego użytkownika
» 2011-11-26 14:16:39
Ale problemem nie jest wielkość obrazka (palety) bo jeśli wyświetlę cały to jest ok, tak samo gdy testowałem jeszcze to dzielenie obrazka i używałem SDL_BlitSurface tyle że wtedy na główny ekran programu, to było wszystko ok
P-44734
npHard
» 2011-11-26 14:29:15
masz takie coś:
SDL_Surface * img = NULL;
a potem takie coś:
SDL_BlitSurface( obraz, & Pos, img, NULL );
W tym momencie img jest NULL'em i równie dobrze mógłbyś wywołać to tak:
SDL_BlitSurface( obraz, & Pos, NULL, NULL );
Innymi słowy karzesz SDLowi skopiować fragment powierzchni znajdującej się pod adresem obraz do powierzchni znajdującej się w pamięci pod adresem NULL. System operacyjny nie pozwala zapisać nic pod ten adres więc mamy naruszenie pamięci.

Co zrobić? Musisz znaleźć sposób by jakoś zaalokować pustą powierzchnię. Najprościej chyba wczytać jakąś bitmapę. Są do tego też jakieś funkcje, kiedyś się z tym męczyłem.
P-44736
Terminator3
Temat założony przez niniejszego użytkownika
» 2011-11-26 15:49:12
Funkcja/e były by dla mnie najlepszym rozwiązaniem bo możliwe że będę wczytywał fragmenty obrazu o różnej wielkości, chyba że np. jeśli wczytam do tego obraz wielkości np. 16x16 to sam się przeskaluje na większy podczas kopiowania (w co wątpię)

Jednak nie znam aż tak funkcji SDL'a

@down zanim napisałeś post już znalazłem tą właśnie funkcję, wielkie dzięki za pomoc ;)
P-44743
kamillo121
» 2011-11-26 16:01:51
Namieszałeś trochę, jeżeli chcesz w ten sposób to pierw stwórz sobie powierzchnie(np SDL_CreateRGBSurface) a potem na nią kopiuj itd.
P-44746
« 1 »
  Strona 1 z 1