BasicC/Obrazy

Z Wikibooks, biblioteki wolnych podręczników.
 W SDL obrazy występują w postaci tzw. powierzchni (surface) lub tekstury (texture). W Basic C powierzchnie prawie nie są stosowane, gdyż nie mają wspomagania sprzętowego, wiec zwykle obraz (Img) to tekstura - przypisany do zmiennej typu wskaźnik na SDL_Texture (nazwa zmiennej poprzedzona * w deklaracji).
Obraz do wyświetlenia tworzy się na projektorze (renderer) rysując np. punkty, linie lub wstawiając (kopiując) obrazy. Wyświetlenie na ekranie (w oknie) następuje po komendzie ShowPage. Można zmienić miejsce docelowe tworzenia obrazów (target) komendą Target i rysować na wskazanym obrazie (teksturze) zmieniając jego zawartość. Można stworzyć nowy obraz o danych wymiarach, wyczyścić go i rysować na nim jak na wirtualnym ekranie. By wyświetlić zawartość obrazu należy przywrócić projektor jako target komendą Target(NULL), wstawić do niego obraz i wywołać ShowPage.
Tryby dostępu do tekstur:

SDL_TEXTUREACCESS_STATIC rzadka zmiana treści, nieblokowalna
SDL_TEXTUREACCESS_STREAMING częsta zmiana treści, blokowalna
SDL_TEXTUREACCESS_TARGET może być stosowana jako tekstura docelowa do tworzenia grafiki

 Jeśli to możliwe należy używać trybu STATIC, inne tryby mogą powodować niespodzianki, np. obrazy w trybie TARGET mogą być kasowane w wyniku zmiany wielkości okna.

ColorKey(surface,R,G,B)[edytuj]

Ustawia kolor o składowych RGB dla powierzchni surface jako całkowicie przeźroczysty. surface jest strukturą typu SDL_Surface. Wykonuje SDL_SetColorKey(surface,1,SDL_MapRGB(surface->format,R,G,B));

CopyImg(T1,X,Y,W,H,T2)[edytuj]

Kopiuje fragment obrazu T1, od pozycji X,Y i wymiarach W,H, tworząc z niego obraz T2 w trybie TARGET. Zmienna wskazująca na obraz (teksturę) T2 musi zostać wcześniej zadeklarowana (SDL_Texture*T2=NULL;). Dokładnie wykonywane są następujące czynności:

  • if(T2) SDL_DestroyTexture(T2); usunięcie T2, jeśli istnieje
  • T2=SDL_CreateTexture(SDLRenderer,SDL_PIXELFORMAT_RGBA32,SDL_TEXTUREACCESS_TARGET,W,H); utworzenie nowego obrazu T2
  • SDL_SetRenderTarget(SDLRenderer,T2); ustawienie "targetu" na T2
  • SDL_SetRenderDrawColor(SDLRenderer,0,0,0,0); wybranie czarnego koloru
  • SDL_RenderClear(SDLRenderer); wypełnienie T2 na czarno
  • SRC.x=X;SRC.y=Y;SRC.w=W;SRC.h=H;SDL_RenderCopy(SDLRenderer,T1,&SRC,NULL); skopiowanie fragmentu T1 do T2
  • SDL_SetRenderTarget(SDLRenderer,NULL); ustawienie targetu na projektor

CreateImg(T,w,h)[edytuj]

Utworzenie nowego obrazu w trybie TARGET o wymiarach w,h przypisanego do zmiennej T, która musi być zadeklarowana. Wykonuje T=SDL_CreateTexture(SDLRenderer,SDL_PIXELFORMAT_RGBA32,SDL_TEXTUREACCESS_TARGET,w,h);

CreateImgBitmap(T,P,w,h)[edytuj]

Utworzenie nowego obrazu o wymiarach w,h, przypisanego do zmiennej T, wypełnionego danymi z pamięci o adresie wskazanym przez P. Wykonuje {T=SDL_CreateTexture(SDLRenderer,SDL_PIXELFORMAT_RGBA32,SDL_TEXTUREACCESS_STATIC,w,h);SDL_UpdateTexture(T,NULL,P,w*4);}

DeleteImg(T)[edytuj]

Usuwa obraz T. Wykonuje {SDL_DestroyTexture(T);T=NULL;}

GetBitmap(X,Y,W,H,pixels)[edytuj]

Kopiuje fragment obrazu z targetu od pozycji X,Y i wymiarach W,H do pamięci od adresu wskazywanego przez pixels. Wykonuje {SRC.x=X;SRC.y=Y;SRC.w=W;SRC.h=H;SDL_RenderReadPixels(SDLRenderer,&SRC,SDL_PIXELFORMAT_RGBA32,pixels,W*4);}
W niektórych systemach, np. Android, może powodować krytyczny błąd.

GetImg(X,Y,W,H,T)[edytuj]

Kopiuje fragment obrazu z targetu od pozycji X,Y i wymiarach W,H do tekstury T. Wywołuje GetBitmap do bufora tymczasowego, a nastepnie ImgBitmap. Jeśli T wskazuje na NULL tworzony jest nowy obraz przypisany do T.

ImgBitmap(T,P,W)[edytuj]

Wypełnia obraz T danymi z pamięci wskazywanymi przez P. W to ilość pikseli w wierszu (szerokość obrazu). Wykonuje SDL_UpdateTexture(T,NULL,P,w*4);

InvertImg(S,T)[edytuj]

Kopiuje obraz (teksturę) S do T z odwróconymi kolorami w trybie TARGET. Tekstura musi być zadeklarowana.
Uwaga! Dodatkowo powoduje:

  • zmianę trybu mieszania kolorów tekstury S
  • ustawienie targetu na projektor
  • zmianę koloru rysowania na biały

InvertImgBitmap(T,pixels,W,H)[edytuj]

Jak ImgBitmap, ale tworzony jest nowy obraz o wymiarach W,H, kolory zostają odwrócone (negatyw), a obraz jest w trybie STREAMING.

InvertImgSurface(S,T)[edytuj]

Kopiuje powierzchnię S w odwróconych kolorach do tekstury T w trybie STREAMING tworząc negatyw. Dokładnie wykonuje:

  • SDL_Surface* CS=SDL_ConvertSurfaceFormat(S,SDL_PIXELFORMAT_RGBA32,0); tworzy powierzchnie CS zawierającą kopie S o formacie kolorów RGBA32
  • SDL_DestroyTexture(*T); usuwa teksturę T
  • *T=SDL_CreateTexture(SDLRenderer,SDL_PIXELFORMAT_RGBA32,SDL_TEXTUREACCESS_STREAMING,CS->w,CS->h); tworzy teksturę T o wymiarach powierzchni S
  • SDL_LockTexture(*T,NULL,&Pixels,&Pitch); "blokuje" T, do zmiennej Pixels zapisuje adres danych T, do Pitch ilość bajtów w wierszu T (szerokość*4)
  • Uint32* pix=(Uint32*)Pixels; tworzy wskaźnik pix na 4-bajtowy obszar i przypisuje mu adres Pixels
  • Uint32* spix=(Uint32*)CS->pixels; spix wskazuje na CS
  • for(int i=0;i<CS->w*CS->h;++i) pix[i]=~spix[i]; kopiuje zanegowane (odwrócone) dane z CS do T
  • SDL_UnlockTexture(*T); odblokowuje T
  • SDL_FreeSurface(CS); usuwa CS

ImgAlphaMod(texture,alpha)[edytuj]

Ustawia modulator alfa obrazu texture dla kopiowania. Docelowa wartość alfa kopiowanego (rysowanego) obrazu będzie wynosiła: alfa obrazu*(alpha/255). Wynika z tego, że alpha=255 nie da żadnego efektu. Wykonuje SDL_SetTextureAlphaMod(texture,alpha);

ImgBlendMode(texture,blend)[edytuj]

Ustawia tryb mieszania obrazu texture. Wykonuje SDL_SetTextureBlendMode(texture,blend);

ImgColorMod(texture,r,g,b)[edytuj]

Ustawia modulator składowych kolorów dla obrazu texture przy kopiowaniu. Docelowa wartość składnika koloru będzie wynosić: składnik koloru*(color/255), gdzie color to wartość danego składnika modulatora koloru. Np. części obrazu w kolorze białym otrzymają kolor modulatora, części czarne pozostaną czarne, inne kolory otrzymają kolor pośredni. Wywołuje SDL_SetTextureColorMod(texture,r,g,b);

ImgSDLColorMod(texture,SDLColor)[edytuj]

J. w., ale kolor podajemy za pomocą zmiennej typu SDL_Color.

ImgSize(T)[edytuj]

Odczytuje rozmiar obrazu T. Wynik zapisuje do pól w i h zmiennych SRC i DST. Wykonuje {SDL_QueryTexture(T,NULL,NULL,&DST.w,&DST.h);SRC.w=DST.w;SRC.h=DST.h;}

InsertImg(T)[edytuj]

Kopiuje obraz T do miejsca docelowego (targetu, domyślnie projektora) wypełniając całą jego zawartość. Wywołuje SDL_RenderCopy(SDLRenderer,T,NULL,NULL);

LoadImg(T,N)[edytuj]

Ładuje obraz T z pliku o nazwie N. T musi być zadeklarowane. Jeśli obraz T istniał - należy go najpierw usunąć komendą DeleteImg. Wykonuje:

  • SDL_FreeSurface(SDLSurface); usuwa zawartość SDLSurface
  • ifdef SDL_IMAGE_H_

SDLSurface=IMG_Load(N); jeśli załączono SDL_image załaduj obraz do SDLSurface else SDLSurface=SDL_LoadBMP(N); jeśli nie - załaduj obraz komendą SDL_LoadBMP endif

  • if(!SDLSurface) SDL_Log(SDL_GetError()); jeśli SDLSurface=NULL wypisz komunikat
  • T=SDL_CreateTextureFromSurface(SDLRenderer,SDLSurface); tworzy teksturę T z SDLSurface

LoadImgKey(T,N,K)[edytuj]

Jak LoadImg, ale dodatkowo ustala kolor K przeźroczystym komendą {Color.BAS=K;SDL_SetColorKey(SDLSurface,1,SDL_MapRGB(SDLSurface->format,Color.SDL.r,Color.SDL.g,Color.SDL.b));}

LoadPNG(T,N)[edytuj]

Ładuje obraz T z pliku o nazwie N w formacie .PNG. T musi być zadeklarowane. Jeśli obraz T istniał - należy go najpierw usunąć komendą DeleteImg. W BasicSDL musi być załączany plik lodepng.h. Wywołuje LodePNG(&T,N,-1);

LoadPNGKey(T,N,K)[edytuj]

Jak wyżej, ale dodatkowo ustawia pełną przeźroczystość koloru K w obrazie. Wywołuje LodePNG(&T,N,K);

PutImg(T,X,Y)[edytuj]

Wstawia obraz T do targetu w pozycji X,Y. Wykonuje {SDL_QueryTexture(T,NULL,NULL,&DST.w,&DST.h);DST.x=X;DST.y=Y;SDL_RenderCopy(SDLRenderer,T,NULL,&DST);}

PutImgScale(T,X,Y,SW,SH)[edytuj]

Wstawia obraz T do targetu w pozycji X,Y mnożąc szerokość i wysokość przez SW i SH. Wykonuje {SDL_QueryTexture(T,NULL,NULL,&DST.w,&DST.h);DST.x=X;DST.y=Y;DST.w*=SW;DST.h*=SH;SDL_RenderCopy(SDLRenderer,T,NULL,&DST);}

PutImgSize(T,X,Y,W,H)[edytuj]

Wstawia obraz T do targetu w pozycji X,Y zmieniając jego wymiary na W,H. Wykonuje {DST.x=X;DST.y=Y;DST.w=W;DST.h=H;SDL_RenderCopy(SDLRenderer,T,NULL,&DST);}

PutImgRect(T,S,D)[edytuj]

Wstawia część obrazu T wskazaną w S do targetu w pozycji i wymiarach wskazywanych przez D. S i D to zmienne typu SDL_Rect, można zadeklarowac własne lub wykorzystać zadeklarowane przez BasicSDL o nazwach SRC i DST. Wywołuje SDL_RenderCopy(SDLRenderer,T,&S,&D);

PutImgRotoFlip(T,X,Y,R,F)[edytuj]

Wstawia obraz T do targetu w pozycji X,Y obrócony o R stopni względem środka i odbity zgodnie z F przyjmujące: SDL_FLIP_NONE - brak odbicia, SDL_FLIP_HORIZONTAL - odbicie w poziomie, SDL_FLIP_VERTICAL - odbicie w pionie, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL - w pionie i poziomie. Wykonuje {SDL_QueryTexture(T,NULL,NULL,&DST.w,&DST.h);DST.x=X;DST.y=Y;SDL_RenderCopyEx(SDLRenderer,T,NULL,&DST,R,NULL,F);}

PutImgREF(T,S,D,R,F)[edytuj]

Jak PutImgRect ale obrócony o R stopni względem środka i odbity zgodnie z F. Wywołuje SDL_RenderCopyEx(SDLRenderer,T,&S,&D,R,NULL,F);

PutImgREX(T,S,D,R,C,F)[edytuj]

Jak PutImgRect ale obrócony o R stopni względem punktu C i odbity zgodnie z F, gdzie C jest zmienną typu SDL_Point. Wywołuje SDL_RenderCopyEx(SDLRenderer,T,&S,&D,R,&C,F);

SaveBMP(X,Y,W,H,N)[edytuj]

Zapisuję fragment obrazu z targetu od pozycji X,Y i wymiarach W,H do pliku o nazwie N w formacie .bmp.

Target(texture)[edytuj]

Ustala obraz texture miejscem docelowym operacji graficznych zamiast domyślnego projektora, dzięki czemu można rysować na danym obrazie zmieniając jego zawartość. Wpisanie NULL w miejsce texture powoduje ustawienie targetu na projektor. Wywołuje SDL_SetRenderTarget(SDLRenderer,texture);

Przykład:

#include "BasicSDL.h"
Uint8 dane[200*200*4];
SDL_Texture *obraz;
SDL_Point c={100,100};
MAIN
  SDLOpen(0)
  Color(-255)
  Circle(100,100,100)
  Box(50,50,100,150)
  GetBitmap(0,0,200,200,dane)
  ImgBitmap(obraz,dane,200)
  SRC(0,0,200,200) DST(300,100,300,200)
  PutImgREX(obraz,SRC,DST,39,c,0)
  InvertImgBitmap(obraz,dane,200,200)
  PutImg(obraz,200,0)
  ShowPage
  WaitInKey
  SDLQuit
ENDMAIN