Bu bölümde DirectX ile ilk programımızı yapacağız. Ama öncelikle DirectX programlarının derlenebilmesi için DirectX 9.0 SDK paketini indirmelisiniz. Bu paket içerisinde DirectX programlama için gerekli olan kütüphane dosyaları ve çeşitli yardımcı araçlar bulunmaktadır.
Programlama yaparken yapılan ilk program olmazsa olmaz Hello World programıdır : ) fakat DirectX ile yazı yazmak o kadar kolay olmadığı için bu geleneği uygulayamıyoruz onun yerine arkaplanı mavi boş bir pencere oluşturmakla yetineceğiz.
ilk programı yaparken izleyeceğimiz adımları şöyle açıklayabiliriz :
1 – Global değişkenleri ve fonksiyonlar tanımlama
2 – Direct3D initialize eden fonksiyonu oluşturarak Direct3D objesi oluşturmak
3 – Çizim fonksiyonunu oluşturmak
4 – Kullanılan hafızaları bırakan fonksiyonu oluşturmak
1- Global değişkenleri ve fonksiyonlar tanımlama
Direct3D ile çalışmaya başlarkan ilk yapılması gereken Global değişken ve fonksiyonları tanımlamaktır.
// Pencere ve Direct3D için başlık dosyaları #include <windows.h> #include <windowsx.h> #include <d3d9.h> // Direct3D Kütüphane dosyası #pragma comment (lib, "d3d9.lib") // global değişkenler LPDIRECT3D9 d3d; // Direct3D için işaretçi LPDIRECT3DDEVICE9 d3ddev; // Direct3D device için işaretçi // fonksiyon tanımlamaları void initD3D(HWND hWnd); // Direct3D hazırlayan fonksiyon void render_frame(void); // çizim fonksiyonu void cleanD3D(void); //Direct3D yi kapatan ve hafızayı temizleyen fonksiyon // WindowProc fonksiyonu için tanımlama LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
2 – Direct3D initialize metodunu ve Direct3D device objesi oluşturmak
Bu bölümde Direct3D kullanımı için ilk adımlar atılmaktadır. Bunun için bazı device bilgilerini tutan struct kullanacağız. Bunlar Direct3D nin hangi pencere üzerinde çizim yapacağı, pencerenin tam ekran mı yoksa pencere halinde mi olacağı gibi birtakım önemli bilgiler.
// bu fonksiyon Direct3D yi kullanım için hazırlıyor
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // Direct3D arayüzünü oluşturur
D3DPRESENT_PARAMETERS d3dpp; // çeşitli device bilgilerini tutmak için bir struct değişken
ZeroMemory(&d3dpp, sizeof(d3dpp)); // struct 'ı kullanmak için temizliyoruz
d3dpp.Windowed = TRUE; // program tamekran değil, pencere şeklinde
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // eski çerceçeveleri etkisiz kılar
d3dpp.hDeviceWindow = hWnd; // Direct3D nin kullanacağı pencereyi belirtiyoruz
// d3dpp struct'ını kullanarak bir device sınıfı oluşturur
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
3 – Çizim fonksiyonunu oluşturmak
Bu fonksiyon her bir çerçeve için çalıştırılacak olup çizim işlemlerinin yapıldığı fonksiyondur. Bu yazımızda birşey çizdirmeyip sadece arkaplanı maviye boyayacağız. Tabi isterseniz siz rengi değiştirebilirsiniz.
// herbir çerçeve için tekrarlanarak kullanılacak çizim metodu
void render_frame(void)
{
// pencereyi arkaplan mavi olacak şekilde temizler
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene(); // 3D çizim'e başlanır
// çizilecek şeyleri bu arada çizdiriyoruz
d3ddev->EndScene(); // 3D SAHNE SONU
d3ddev->Present(NULL, NULL, NULL, NULL); // oluşturulan çerçeveleri Pencerede gösterir.
}
4 – Direct3D’ yi kapatan ve hafızayı temizleyen fonksiyonu oluşturmak
Oyun programlamada hafızayı kontrol etmek çok önemli bir olaydır. Çok ufak bile olsa kullanılıp işi biten her nesneyi silmek hafızadan çıkarmak gereklidir, aksi taktirde hafıza taşacak program kapanacaktır.
// bu metod Direct3D 'yi ve hafızayı temizler
void cleanD3D(void)
{
d3ddev->Release(); // 3D device'i kapatır ve hafızadan kaldırır
d3d->Release(); //Direct3D'yi kapatır ve hafızadan kaldırır
}
Sonuç
Bu yazımızda Directx ve C++ kullanarak ilk programımızı yaptık.Henuz bir çizgi dahi çizmemiş olsak ta Directx’in bacağını kırdığımızı düşünüyorum. Bir sonraki dersimizde çizim yapmaya başlayacağız.
Bu dersin tam kodunu aşağıdaki linke tıklayarak görebilirsiniz .
/* yazar : Muhammet Gümüş
kaynak : muhammedgumus.com
*/
// temel pencere ve Direct3D başlık dosyaları
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
// Direct3D kütüphane dosyası
#pragma comment (lib, "d3d9.lib")
// global tanımlamalar
LPDIRECT3D9 d3d; // Direct3D için işaretçi
LPDIRECT3DDEVICE9 d3ddev; // Direct3D device için işaretçi
// fonksiyon tanımlamaları
void initD3D(HWND hWnd); //Direct3D hazırlayan fonksiyon
void render_frame(void); // çizim fonksiyonu
void cleanD3D(void); //Direct3D yi kapatan ve hafızayı temizleyen fonksiyon
// WindowProc fonksiyonu için tanımlama
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// Windows programları için kullanılan Winapi fonksiyonu
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"ilk Direct3D Programim",
WS_OVERLAPPEDWINDOW,
300, 300,
800, 600,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
// Direct3D hazırlayıp çalıştıran metod
initD3D(hWnd);
// ana döngüye giriyor
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
render_frame();
}
// Directx'i ve hafızayı temizle
cleanD3D();
return msg.wParam;
}
// Programın ana mesaj handle'i
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// bu fonksiyon Direct3D yi kullanım için hazırlıyor ve çalıştırıyor
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // Direct3D arayüzünü oluşturur
D3DPRESENT_PARAMETERS d3dpp; // çeşitli device bilgilerini tutmak için bir struct değişken
ZeroMemory(&d3dpp, sizeof(d3dpp)); // struct 'ı kullanmak için temizliyoruz
d3dpp.Windowed = TRUE; // program tamekran değil, pencere şeklinde
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // eski çerceçeveleri etkisiz kılar
d3dpp.hDeviceWindow = hWnd; // Direct3D nin kullanacağı pencereyi belirtiyoruz
// d3dpp struct'ını kullanarak bir device sınıfı oluşturur
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
// herbir çerçeve için tekrarlanarak kullanılacak çizim metodu
void render_frame(void)
{
// pencereyi arkaplan mavi olacak şekilde temizler
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene(); // 3D çizim'e başlanır
// çizilecek şeyleri bu arada çizdiriyoruz
d3ddev->EndScene(); // 3D SAHNE SONU
d3ddev->Present(NULL, NULL, NULL, NULL); // oluşturulan çerçeveleri Pencerede gösterir.
}
// bu metod Direct3D 'yi ve hafızayı temizler
void cleanD3D(void)
{
d3ddev->Release(); // 3D device'i kapatır ve hafızadan kaldırır
d3d->Release(); //Direct3D'yi kapatır ve hafızadan kaldırır
}


