Halo semuanya! Ini adalah pelajaran keempat di SDL 2. Saya memutuskan untuk menggabungkan dua pelajaran menjadi satu, karena dalam aslinya mereka kecil. Tetapi mereka dapat ditemukan di
sini dan di
sini . Baiklah, mari kita mulai pelajaran.
Pertama, kita akan memutuskan apa yang akan kita lakukan. Hari ini kita akan belajar cara mengunggah gambar dari ekstensi lain (bukan BMP), yaitu: PNG. Ulangi gambar dalam format berbeda untuk mempercepat pekerjaan dan mengubah ukuran gambar. Kami akan bekerja dengan gambar ini:
Instalasi
Jadi, pertama-tama kita belajar cara mengunduh PNG. Dalam rangkaian fitur SDL 2 standar, tidak ada unggahan gambar format non BMP. Untuk mengunduh format yang berbeda, Anda perlu menginstal ekstensi.
Berikut instruksinya:
WindowsAnda pergi ke
halaman ini dan unduh arsip ZIP atau TAR.GZ dari bagian
Perpustakaan Pengembangan . Buka kemasan dan buang ke folder dengan kompiler.
LinuxJika sistem Anda menggunakan Debian, maka Anda harus memasukkan perintah ini:
apt-cache search libsdl2-image apt-get install libsdl2-image-dev
Jika Yellowdog Updater, Dimodifikasi digunakan, maka Anda memasukkan perintah ini:
yum search SDL2_image-devel yum SDL2_image-devel
OS MacUnduh file DMG dan baca Readme.
Menulis kode
Setelah mengatur
SDL_image, kami mulai menulis kode. Pertama, seperti biasa, kita akan menghubungkan pustaka, mengatur ukuran jendela dan membuat 3 variabel global.
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL;
Perhatikan bahwa saya menghubungkan
SDL_image.h secara terpisah, karena ini adalah perpustakaan yang terpisah.
Selanjutnya, kita menulis 3 fungsi, yang kita kenal, di mana kita akan menambah dan mengubah sesuatu, seperti biasa.
Init () bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; }
Di sini kami menambahkan inisialisasi modul SDL_image. Untuk menginisialisasi, pertama kita membuat variabel
int , kita memiliki
flag , dan menyimpan semua flag yang ingin Anda gunakan untuk inisialisasi.
Daftar semua benderaSDL_INIT_PNG - menginisialisasi pengunduh gambar PNG;
SDL_INIT_JPG - menginisialisasi pengunduh gambar JPG;
SDL_INIT_TIF - menginisialisasi pengunduh gambar TIF;
Selanjutnya, kami menulis kondisi ini:
if ( !( IMG_Init( flags ) & flags ) )
Fungsi
IMG_Init () mengembalikan flag yang dapat diinisialisasi. Jika dia mengembalikan bendera, tetapi yang kami inginkan tidak ada, kami mengembalikan kesalahan. Sangat sederhana. Juga, perhatikan bahwa saya menggunakan
IMG_GetError sebagai ganti
SDL_GetError , karena kami mencari kesalahan dalam fungsi modul
SDL_image , dan bukan
SDL .
Saya juga ingin mencatat bahwa saya memutuskan untuk menggunakan tipe
bool untuk
mengembalikan a - ini adalah cara yang lebih rasional.
Mari kita lanjutkan menulis program kita, menulis fungsi
Load () , di mana kita memuat gambar PNG dan mengubahnya.
Muat bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; }
Di sini kami mengunggah gambar dengan fungsi
IMG_Load baru.
Fungsinya sama dengan
SDL_LoadBMP dan hasilnya sama - ia mengembalikan instance dari kelas
SDL_Surface . Untuk menemukan kesalahan saat memuat, kami juga menggunakan
IMG_GetError .
Sudah waktunya untuk mengkonversi. Pertama, sedikit teori. Hanya sedikit orang yang tahu, tetapi ketika mengunduh gambar, itu diunduh dalam format 24bit, dan sebagian besar tampilan modern dalam format 32bit. Dan setiap kali kami menampilkan gambar di layar, itu pertama kali dilakukan ulang dalam format 32bit. Untuk program sederhana, ini tidak masalah, tetapi ketika membuat semacam proyek besar, itu akan sangat mempengaruhi kinerja, jadi kami akan mengambil dan pada tahap memuat gambar kami akan membuat ulang mereka dalam format tampilan. Fungsi
SDL_ConvertSurface akan membantu. Dibutuhkan 3 nilai: Permukaan yang ingin kita format, format yang ingin kita format, dan bendera. kami ingin memformat gambar
bunga , berikan parameter pertama. Parameter kedua adalah format permukaan jendela, kami tidak akan menggunakan bendera. Fungsi ini mengembalikan salinan permukaan, yang segera kami tetapkan untuk
bunga . Untuk mencari kesalahan, kami mengambil fungsi
SDL_GetError () ,
karena kami sudah bekerja dengan permukaan, dan mereka dari
SDL , dan bukan dari
SDL_image .
Selanjutnya kita menulis fungsi Berhenti, tambahkan hanya satu fungsi untuk itu.
Berhenti void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); }
Kami menambahkan
IMG_Quit untuk membatalkan inisialisasi modul SDL_image.
Main
Sekarang hal yang paling sederhana tetap - fungsi
utama .
int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; }
Untuk memulai, inisialisasi dan buat semua yang Anda butuhkan dan unggah file yang diperlukan. Kami tidak akan berhenti di sini.
SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0;
Setelah itu, buat objek kelas
SDL_Rect . Kami akan membutuhkannya untuk meregangkan gambar. Jika Anda perhatikan, gambar bunga 4 kali lebih kecil dari ukuran jendela (2 kali lebih tipis dan 2 kali lebih rendah), dan kita perlu merentangkannya ke ukuran jendela. Jadi dalam lebar
bg_flower persegi panjang tulis nilai lebar jendela, dan tinggi - tinggi jendela. atur koordinat ke 0, sehingga gambar ditampilkan di sudut kiri atas.
Untuk menampilkan gambar dengan ukurannya, ada fungsi khusus. Ini terlihat seperti ini:
SDL_BlitScaled(flower, NULL, scr, &bg_flower);
Dibutuhkan 4 arti. Yang pertama adalah gambar yang ingin kita tampilkan, yang kedua adalah Rectangle yang ingin kita potong dari gambar ini (jika kita ingin mengambil seluruh gambar, kita menulis NULL), yang ketiga adalah permukaan tempat kita ingin menampilkan gambar, dan yang keempat adalah persegi panjang yang sama, dimensi dan koordinat yang kami ambil untuk meregangkan atau memampatkan dan menampilkan gambar.
Selanjutnya, cukup perbarui permukaan layar, atur penundaan, keluar dan kembali 0.
SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
Di sinilah program kami berakhir. Untuk mengkompilasi keajaiban ini, Anda perlu menambahkan -lSDL2_image, sebagai opsi kompilasi lainnya.
Dan untuk ini kita akan mengakhiri hari ini. Ini kode yang kami dapat:
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; } bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; SDL_BlitScaled(flower, NULL, scr, &bg_flower); SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
Selamat tinggal semuanya!
<< Pelajaran sebelumnya || Pelajaran selanjutnya
>>