Dalam SDL, ada dua cara yang biasa digunakan untuk menampilkan
atau mencetak gambar ke dalam permukaan / surface. pertama adalah
SDL_BlitSurface, dan yang kedua adalah SDL_BlitScaled. Perbedaannya
adalah pada penggunaan parameter ke-4. Walaupun sama-sama menggunakan
SDL_Rect untuk menentukan bagian gambar yang ditampilkan dan posisinya,
tapi pada SDL_BlitSurface tidak akan ada perubahan ukuran gambar karena parameter keempatnya mengabaikan nilai w(width) dan
h(height).
Pada SDL_BlitScaled, gambar bisa diubah
ukurannya dengan nilai w dan h dari argumen pada parameter ke-4.
Kecepatan untuk menampilkan gambar dari SDL_BlitSurface tentu saja akan
lebih cepat daripada SDL_BlitScaled karena proses yang dibutuhkan lebih
sederhana. Mana yang akan kita gunakan? Kita akan menggunakannya sesuai
dengan kebutuhan.
Untuk mencoba penerapan function SDL_BlitScaled, kita akan menampilkan gambar dengan nama "Codelogi.bmp" dengan dua ukuran dalam kode program berikut ini.
#include <SDL2/SDL.h>
int main( int argc, char* args[] ){
SDL_Window* window = NULL;
SDL_Event evt;
SDL_Surface* screenSurface = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ){
printf( "Error: %s\n", SDL_GetError() );
}else{
window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
if( window == NULL ){
printf( "Error : %s", SDL_GetError() );
}else{
screenSurface = SDL_GetWindowSurface( window );
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF) );
SDL_Surface *tmp=SDL_LoadBMP("Codelogi.bmp");
if(tmp){
SDL_Surface *bmp=SDL_ConvertSurface(tmp, screenSurface->format, 0);
SDL_Rect rct, rcd;
SDL_FreeSurface(tmp);
rct.x=bmp->w/2;
rct.y=0;
rct.w=bmp->w;
rct.h=bmp->h;
rcd.x=0;
rcd.y=0;
rcd.w=bmp->w*2;
rcd.h=bmp->h*2;
if(bmp){
while(evt.type!=SDL_QUIT){
while(SDL_PollEvent(&evt)){
SDL_BlitScaled(bmp, &rct, screenSurface, &rcd);
SDL_BlitSurface(bmp, &rct, screenSurface, &rcd);
SDL_UpdateWindowSurface( window );
}
}
SDL_FreeSurface(bmp);
}
}
}
}
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
Dalam program akan terlihat dua gambar yang terpotong pada posisi yang sama walaupun ukurannya berbeda. Itu terjadi karena kita mengubah nilai x pada argumen parameter pertama sehingga gambar yang ditampilkan hanya ditampilkan dari bagian tengah gambar. Selain itu, gambar yang pertama ditampilkan menggunakan SDL_BlitScaled sehingga ukurannya 2 kali lebih besar karena nilai w dan h dari variabel rcd adalah 2 kali ukuran gambar. Sekalipun variabel-variabel yang digunakan pada function adalah variabel yang sama, tapi hasilnya berbeda karena ada anggota yang diabaikan dari variabel rcd, yaitu w dan h.
Mengoptimalkan permukaan gambar
Jika
pada program yang digunakan untuk mengedit foto ada layer, dalam SDL
ada surface atau variabel bertipe SDL_Surface yang bisa digunakan untuk
menyimpan gambar sementara sebelum ditampilkan. Tiap surface bisa punya
format gambar yang berbeda-beda.
Sebelum "disatukan" dalam surface pada
window atau surface lain, setiap surface akan disesuaikan formatnya
supaya sama dengan format dari surface tujuan. Misalnya, jika surface
tujuan adalah 32 bit dan surface asal adalah 24 bit maka surface asal
akan diubah dulu menjadi 32 bit sesuai surface tujuan. Walaupun diubah,
tapi perubahan tersebut tidak benar-benar disimpan secara permanen
sehingga tiap kali kita perlu menampilkan gambar akan ada proses
tambahan yang bisa memperlambat program.
Untuk
surface kosong yang akan kita buat, kita bisa menentukan formatnya,
tapi, saat kita memuat gambar dengan SDL_LoadBMP atau semacamnya,
formatnya akan menyesuaikan dengan gambar yang dimuat.
#include <SDL2/SDL.h>
int main( int argc, char* args[] ){
SDL_Window* window = NULL;
SDL_Event evt;
SDL_Surface* screenSurface = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ){
printf( "Error: %s\n", SDL_GetError() );
}else{
window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
if( window == NULL ){
printf( "Error : %s", SDL_GetError() );
}else{
screenSurface = SDL_GetWindowSurface( window );
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF) );
SDL_Surface *tmp=SDL_LoadBMP("Codelogi.bmp");
if(tmp){
SDL_Surface *bmp=SDL_ConvertSurface(tmp, screenSurface->format, 0);
SDL_FreeSurface(tmp);
if(bmp){
while(evt.type!=SDL_QUIT){
while(SDL_PollEvent(&evt)){
SDL_BlitSurface(bmp, 0, screenSurface, 0);
SDL_UpdateWindowSurface( window );
}
}
SDL_FreeSurface(bmp);
}
}
}
}
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
SDL_ConvertSurface
akan menghasilkan SDL_surface yang baru, jadi kita seharusnya menghapus
surface yang sudah kita convert dengan SDL_FreeSurface dengan tujuan
untuk mengosongkan memori yang sudah tidak digunakan lagi.
Kalau kalian malas mengetik, kalian bisa mendownload kode programnya di sini.