Visual C++ ile Görsel Programlama 4 (Win32)
Visual C++ ile Görsel Programlama 4, Resimler ve Komutları
Visual C++ ile Görsel Programlama 4 ( Resimler ve Komutları)
Öncelikle Projemize kaynak dosyaları eklemeyi öğrenelim (Resources). Bunlar ikon, resim, menü ve diyalog kutusu gibi dosyalardır. bunları isterseniz VisualC++ içindeki editör yardımı ile çizersiniz veya import diyerek önceden hazırlanmış bir dosyayı açabilirsiniz.
Kaynak Ekleme
Kaynak eklemek için insert >> Resource menüsüne giriyoruz
karşımıza çıkan pencerede Yeni bir dosya(New) yada önceden çizilmiş hazır dosya seçeneklerinden birini seçiyoruz. Burada öncelikle bitmap diyerek projemize bir resim ekleyelim.
Daha sonra kaydet düğmesine basıyoruz. Burada kaydedilen dosya script.rc isimli bir kaynak dosyası oluyor. Sadece resim ve ikonları değil bunları proje içinde çağırmak için kullanılan sayılar da bu dosya ile birlikte otomatik oluşturuluyor.
Kaydettiğimiz script.rc dosyası şu anda projeye dahil değil çünkü sol taraftaki dosyalar sekmesinde görünmüyor. Bu dosyayı prıjeye eklediğimizde resim dosyası da bununla birlikte eklenecektir. Resource Files dosyasına sağ tıklayıp Add Files to Folder diyerek az önce kaydettiğimiz script.rc dosyasını seçiyoruz.
Script.rc dosyasını ekledikten sonra Header Files kısmına bakıyoruz eğer resource.h dosyası burada görünmüyorsa; Header Files yazısına sağ tıklayıp Add Files to Folder diyerek resource.h dosyasını seçiyoruz.
Resource.h dosyası bir başlık dosyasıdır ve projeye eklenen tüm kaynaklar bu dosyada görünür.
Kaynak dosyalarını ekledikten sonra sol alt tarafta yeni bir sekme oluştuğunu göreceksiniz. Bu sekmeye geçerek buradan tüm kaynakları görme ve düzenleme imkanınız olacaktır ( resim ikon vb. kaynakları düzenledikten sonra kaydetmeyi unutmayın)
Yukardaki resme bakarsanız projenin bu resme otomatik olarak IDB_BITMAP1 adını verdiğini göreceksiniz. bu isimden faydalanarak resim dosyasını kod içersinden çağırabileceğiz. Bir Örnek ile resim yapıştırmayı görelim. ( bu işlem size uzun gelebilir ama 2 boyutlu ilk oyun denememizde bunu kullanacağız.)
|
#include <windows.h> #include "resource.h" const char Classismi[] = "pencere"; HBITMAP resim=NULL; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: DeleteObject(resim); PostQuitMessage(0); break; case WM_CREATE: resim = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1)); break; case WM_PAINT: //esas çizim kodu bu kısımda yazılı HDC hdc; HDC resimhdc; PAINTSTRUCT ps; RECT anakare; hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &anakare); FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); resimhdc = CreateCompatibleDC(hdc); SelectObject(resimhdc,resim); BitBlt(hdc, 0, 0, 150, 200, resimhdc, 0, 0, SRCCOPY); DeleteDC(resimhdc); EndPaint(hwnd, &ps); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = Classismi; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Pencere tanımlama hatası!", "Hata!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindow(Classismi,"Pencere başlığı",WS_OVERLAPPEDWINDOW, 200, 200, 300, 200,NULL, NULL, hInstance, NULL); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } |
Bu projeye eklediğimiz kod parçalarını yazıyorum. öncelikle resource.h dosyasını projey eekledik ama bu kod içinde kullanılacağını belirtmedik. çünkü projemizde birçok kod sayfası olabilir ve programa resource.h dosyasının hangisinde kullanılacağını belirtmeliyiz. bunun için en başa
#include "resource.h"
yazdık. ikinci önemli konu ise resim dosyasının ilk oluşturulması ve hafızadan silinmesi işlemleri için WM_CREATE ve WM_DESTROY sırasında da resim dosyasıyla ilgili kod yazıyoruz.
case WM_CREATE:
resim = LoadBitmap(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_BITMAP1));
break;
burada dikkat edeceğimiz nokta projenin en başında HBITMAP resim=NULL; diyerek belirlediğimiz resim değişkenine yüklenen (LoadBitmap) resmin adıdır.(IDB_BITMAP1). Daha önce menülerden projeye eklediğimiz resim dosyasını burada kod yardımı ile bir değişkene atıyoruz (resim). bundan sonra proje içinde resim isimli değişkeni kolayca kullanabiliriz.. eğer birçok resim dosyamız olsaydı bunları da bu şekilde farklı değişkenlere yüklememiz gerekecekti.
case WM_DESTROY:
DeleteObject(resim);
PostQuitMessage(0);
break;
Program kapatılırken resim isimli değişkeni de hafızadan silmeyi unutmuyoruz. şimdi gelelim kodun en önemli kısmına. Resmi hdc üzerine yapıştırma işlemi. hdc'nin ne olduğunu daha önceki dersimizde görmüştük. Bu kodu WM_PAINT mesajı içersine yazıyoruz. bu mesaj genelde şu durumlarda çağrılır: pencere yeniden çizildiğinde , pencere haraket ettiğinde, simge durumuna geçtiğinde, başka bir programın arkasına gidip geldiğinde... vb şekilde ekrana tazelenerek geldiği durumlarda.
case WM_PAINT: HDC hdc; // ana pencere çizim alanı HDC resimhdc; //resmi taşıyan çizim alanı PAINTSTRUCT ps; //çizime başlarken kullanılan yapı RECT anakare; //Ana pencere ölçülerini alacak dikdörtgen yapı hdc = BeginPaint(hwnd, &ps); //Bu komut ile çizime başlanıyor GetClientRect(hwnd, &anakare); //Ana pencerenin ölçüleri alınıyor FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); //Ana pencere Gri renge boyanıyor resimhdc = CreateCompatibleDC(hdc); // resimhdc yapısı tanımlanıyor SelectObject(resimhdc,resim); // resimhdc içersine resim aktarılıyor BitBlt(hdc, 0, 0, 150, 200, resimhdc, 0, 0, SRCCOPY); // bilgi kopyalama ( hdc <<< resimhdc ) DeleteDC(resimhdc); //resimhdc yok ediliyor EndPaint(hwnd, &ps); //çizim bitiriliyor break; |
Bu kod içersinde en önemlisi ise BitBlt isimli fonksiyondur. Bu fonksiyon iki farklı HDC arasında bilgi taşıma yada karşılaştırma gibi işlemler yapar.
BitBlt( hedefHDC, ilknoktaX,
ilknoktaY, ikincinoktaX, ikincinoktaY, kaynakHDC, ikiX,
ikiY, KOMUT);
ilknoktaX : hedefte sol üst köşe X konumu
ilknoktaY : hedefte
sol üst köşe Y konumu
ikincinoktaX :
hedefin eni
ikincinoktaY : hedefin
boyu
ikiX : kaynak alanın
sol üst köşesi X konumu
ikiY :kaynak alanın
sol üst köşesi Y konumu
KOMUT: işlem komutu
Buradaki resmin taşınması işlemini aşağıdaki resimden daha iyi anlayabilirsiniz.
Yukarda sadece kopyalama yapan komut kullanıldı. BitBlt birçok komut içermektedir. listesi aşağıda.
BLACKNESS | Hedef alanı 0 numaralı renk ile doldurur (normalde siyah renk) |
DSTINVERT | Hedef alanın renklerini ters çevirir |
MERGECOPY | Hedef Alanın renklerini belirtilen Desen ile VE (AND)komutunu kullanarak birleştirir. |
MERGEPAINT | Renkleri ters çevrilmiş kaynak ile hedef alanı VEYA(OR) komutu ile birleştirir. |
NOTSRCCOPY | Ters Çevrilmiş kaynak Alanı hedef Alan üzerine kopyalar. |
NOTSRCERASE | Kaynak ve Hedef renklerini VEYA(OR) komutu ile karıştırıp sonucu ters çevirir. |
PATCOPY | Kaynak Deseni Hedef Resme kopyalar |
PATINVERT | Kaynek Desen ile Hedef Alanı VEYADEĞİL(XOR) komutu ile birleştirir. |
PATPAINT | Desen ile Kaynağın ters çevrilmiş renklerini VEYA (OR) komutu ile birleştirir.Bu işlemin sonucu alınıp Hedef ile VEYA(OR) komutu kullanılarak birleştirilir. |
SRCAND | Hedef ve kaynak Alanlar VE(AND) komutu ile birleştirilir. |
SRCCOPY | Kaynak Alan direkt olarak hedefe kopyalanır. |
SRCERASE | Hedefin Renkleri ters çevrilerek Kaynak Alan ile VE(AND) komutu ile birleştirilir. |
SRCINVERT | Kaynak ve Hedef Alanların renkleri VEYADEĞİL(XOR)komutu ile birleştirilir. |
SRCPAINT | Hedef ve Kaynak Alanlar VEYA (OR) komutu ile birleştirilir |
WHITENESS | Hedef Alan 1 numaralı renk ile doldurulur (normalde bu renk beyazdır) |
Bu komutların nasıl çalıştığını örnekte inceleyelim. VE komutunun çalışması için kaynak ve hedef alanların ikisinde de aynı renk bulunmalıdır. VEYA komutunda ise iki alandan birinde renk bulunması yeterlidir.VEYADEĞİL komutu iki alanda de renk boş ise çıkış verir.
VE (AND) |
VEYA (OR) |
VEYADEĞİL(XOR) |
Kesişme noktası dolu ise çıkış verir | Resim olan noktalar birleşir | Resim olmayan noktalar birleşip sonuç olur |
Sahneye resim çağırayı da öğrendik şimdi de zaman aracını öğrenip ilk oyunumuzu yazmaya geçeceğiz.
Konuyu anladık mı ?
Uygulama sorusu: Ana pencereye farklı noktalarda iki resim yapıştırın, ikinci
resim birincinin tersi olsun.
Ekleyen: drekon
Kapalı
Eklediğim Dersler
Ders Kategorileri
Yeni Dersler (Tutorials)
- Armor Modelleme
Ekleyen: Dereli - Ücretsiz Zbrush Dersi.
Ekleyen: BurakB - Corona Render ile Salon Görselleştirme
Ekleyen: barcelona1988 - Tek Bir Resimle Nasıl Sinematik Görüntü Ala Biliriz?
Ekleyen: PixlandPictures - After Effects - Script kullanmadan karakter rigleme
Ekleyen: PixlandPictures - 3dsmax landscape_ Making of Part1
Ekleyen: altıneldiven - Oyun yapımı dersleri 5 - Unity3D Sahne Duzeni
Ekleyen: drekon