IDirect3DDevice9 Arabirimi

IDirect3DDevice9 Arabirimi

IDirect3DDevice9 Direct3D'nin temel arabirimlerinden biridir. Bu yazıda arabirimin ihtiva ettiği fonksiyonları elimden geldiği kadar açıklamaya çalıştım.Bu yazıyı gelecek derslerimizde sık sık kullancağımız fonksiyonların daha ayrıntılı açıklamasının bulunması açısından bir nevi referans niteliğinde olması için hazırladım. Gerekli gördüğüm yerlerde fonksiyonları ufak örneklerle açıklamaya çalıştım. Zamanla bu yazıda ufak tefek düzenlemeler olabilir. Şimdilik bu hali ile birçok kişinin işine yarayacağını düşünüyorum.

IDirect3DDevice9::BeginScene: Çizim işlemlerini başlatır. Direc3D'de bütün çizim işlemleri BeginScene ve EndScene fonksiyonları arasında icra edilmelidir.

Fonksiyonun örnek kullanımı:

C/C++ kodu:
...
...
lpd3dDevice->BeginScene();//Çizim işlemlerini başlat
...
lpd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);// 1 adet polygon çiz
lpd3dDevice->EndScene();//Çizim işlemlerini sonlandır.
...

IDirect3DDevice9::BeginStateBlock: Çizim işlemleri gerçekleşirken icra edilen (SetRenderState, SetSamplerState, SetTextureStageState vb.) durum belirteçlerinin kaydının tutulması işlemini başlatır. Kaydedilecek durum belirteçleri BeginStateBlock ve EndStateBlock fonksiyonları arasında icra edilmelidir. Durum belirteci (States) kavramını şu şekilde izah etmeye çalışayım. Çizim işlemleri icra edilirken ilgili konuya ait belirteç icra edildiğinde ondan sonra gelen tüm çizim işlemlerine doğrudan etki eden bir durum oluşur. Örneğin SetSamplerState durum belirtecini ele alalım. Bu belirteç dokuların adresleme ve filtreleme gibi durumlarını değiştirir. Bir kere icra edildiğinde sonrasında yapılan bütün primitif çizimleri sırasındaki doku atamalarında belirtilen doku adresleme ve/veya filtreler kullanılacaktır. Bu durum başka bir belirteç icra edilene kadar etkisini koruyacaktır. Konumuza geri dönersek. Bu icra edilen birçok durum belirteçlerinin kaydını bu yolla tutup başka bir çizim anında sürücüye tekrar atayabiliriz.

Fonksiyonun örnek kullanımı:

Örnek 1 :

C/C++ kodu:

IDirect3DStateBlock9* pStateBlock = NULL;
lpd3dDevice->BeginStateBlock();
 
...
//Durum belirteçleri
//SetRenderState, SetSamplerState, SetTextureStageState gibi fonksiyonlar ile sürücüye atanan belirteçler...
pd3dDevice->SetRenderState ( D3DRS_ZENABLE, true ); //D3DRS_ZENABLE durum belirteci pixeller üzerinde etkilidir.
pd3dDevice->SetRenderState ( D3DRS_CULLMODE, D3DCULL_CW);//D3DRS_CULLMODE durum belirteci vertexler üzerinde etkilidir.
 
...
lpd3dDevice->EndStateBlock( &pStateBlock ); //Kayıt işlemini sonlandır ve 
kaydı yapılan durum belirteçlerini pStateBlock değişkenine aktarır.
 
...
 
pStateBlock->Apply(); //Kaydını aldığımız durum belirteçlerini istediğimiz bir anda sürücüye atar.
pStateBlock->Capture();//Daha önceden kayda aldığımız durum belirteçlerinin değerlerini günceller.
 

Örnek 2 :

C/C++ kodu:
 
IDirect3DStateBlock9* pStateBlock = NULL;
lpd3dDevice->BeginStateBlock();
//modele doku atanması ile ilgili durum belirteçleri.
lpDevice->SetTextureStageState( 0, D3DTSS_COLOROP,D3DTOP_SELECTARG1 );
lpDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
lpDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
lpDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
lpDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
lpDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
lpd3dDevice->EndStateBlock( &pStateBlock );
 
//model çiz
 
lpDevice->SetFVF(POLYGON_VERTEX::FVF);
lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX));
lpDevice->SetIndices(lpIndexBuffer); 
lpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,dwNumVertex,0,dwNumPolygonIndex);
....
...
..
.
pStateBlock->Apply(); Kaydını tuttuğumuz durum belirteçlerini tekrar sürücü atıyoruz.
//model çiz
lpDevice->SetFVF(POLYGON_VERTEX::FVF);
lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX));
lpDevice->SetIndices(lpIndexBuffer); 
lpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,dwNumVertex,0,dwNumPolygonIndex);
 

IDirect3DDevice9::Clear: Çizim ekranının (yüzeyinin) belirli bölgelerini yada tamamını, depth bufferi, stencil bufferi temizlemek için kullanılır. Fonksiyon icra edildiğinde RenderTarget yüzey belirtilen renkte boyanır. DepthBuffer 0-1 arasında olmak şartı ile belirtilen yeni değerle temizlenir. StencilBuffer 0-2n-1 (n bit derinliğini ifade etmektedir) arasında olmak şartı ile belirtilen yeni değerle temizlenir. Bu fonksiyonun düzgün çalışabilmesi için temizlenmek istenen unsurların var olmasına dikkat etmek gerekir. Örneğin sürücüyü depth-stencil desteği olmadan yaratırsanız olmayan birşeyi temizlemeye çalışacağınızdan fonksiyon düzgün çalışmayacaktır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:

lpd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100,100,100), 1.0f, 0 );


IDirect3DDevice9::ColorFill: Belirtilen yüzeyin istenilen dörtgen bir alanını belirtilen renkle doldurur/boyar.

Fonksiyonun örnek kullanımı:
C/C++ kodu:

IDirect3DSurface9* lpSurface;
RECT rc={0,0,50,50};
...
lpd3dDevice->ColorFill(lpSurface,&rc,0xff0000ff); //belirtilen yüzeyin belirtilen alanını mavi renkle boyadık.
 

IDirect3DDevice9::CreateAdditionalSwapChain: Yeni bir ek swap chain (takas zinciri) oluşturmak için kullanılır. Modelleme programlarından da hatırlayacağınız gibi aynı sahneye ait çoklu görüş alanları oluşturmak için kullanılır. Bu görüş alanları aynı kaynakları kullanarak sahneye çizim yapabilirler. Takas zinciri konusunu biraz açarsak. Direct3D de çizim işlemleri gözümüzün görebileceği şekle gelmeden önce back buffer denilen bir hafıza bölgesine çizilir. Back buffera çizilen görüntü daha sonra front buffera aktarılır. Gözümüzün göreceği şekle yani pencereye çizilir. Bu olaya swap chain (takas zinciri) denilmektedir. Direct3D de bir sürücü oluşturulduğunda otomatikman bir takas zinciri oluşur. CreateAdditionalSwapChain fonksiyonu yeni bir görüş penceresi oluşturmak istediğimizde bu görüş penceresi için gerçekleştireceğimiz çizim işlemlerinin gerçekleşeceği ek bir swap chain oluşturulmasını sağlar.

Aşağıdaki örnekte 2 görüş alanı oluşturmak için izlenmesi gereken adımlar gösterilmektedir. Örneği dikkatlice inceleyin. Yine aynı adımları takip ederek daha fazla görüş alanı oluşturabilirsiniz.

Aşağıdaki resimde aynı kaynakları (modeller,dokular) kullanan ancak farklı kamera görüşlerine sahip görüş alanları görülmektedir.


Fonksiyonun örnek kullanımı:

C/C++ kodu:

//Tanımlamalar.
HWND windowHwnd = NULL; //1 inci pencerenin id si
HWND windowHwnd1 = NULL;//2 nci pencerenin id si
LPDIRECT3DSWAPCHAIN9 swapChain0 = NULL; // 1 inci swap chain
LPDIRECT3DSWAPCHAIN9 swapChain1 = NULL; // 2 nci swap chain
 
//INIT
//Çoklu görüş alanları için
lpDevice->GetSwapChain( 0, &swapChain0 ); //Sürücü oluştururken bir swap chain zaten oluştuğu için onu alıyoruz.
lpDevice->CreateAdditionalSwapChain( &d3dpp, &swapChain1 ); //Ek bir swap chain daha oluştur.
 
//RENDER
//-----1. görüş alanı için-----//
LPDIRECT3DSURFACE9 pBackBuffer = NULL;//Sahnelerin çizileceği yüzey
swapChain0->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );//1. sahneye ait backbufferi döndür.
lpDevice->SetRenderTarget( 0, pBackBuffer );//Çizimin yapılacağı hedef yüzeyi belirt.
 
 
//1. görüş alanı için projeksiyon ve görüş matrixlerini ayarla.
//Modelleri çiz
 
swapChain0->Present( NULL, NULL, windowHwnd , NULL, 0 );//1. sahneyi belirtilen pencerede çizdir.
pBackBuffer->Release();
 
 
//-----2. görüş alanı için-----//
swapChain1->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );//2. sahneye ait backbufferi döndür.
lpDevice->SetRenderTarget( 0, pBackBuffer );//Çizimin yapılacağı hedef yüzeyi belirt.
 
//2. görüş alanı için projeksiyon ve görüş matrixlerini ayarla.
//Modelleri çiz
 
swapChain1->Present( NULL, NULL, windowHwnd1, NULL, 0 );//2. sahneyi belirtilen pencerede çizdir.
pBackBuffer->Release();


IDirect3DDevice9::CreateCubeTexture: 3 boyutlu kübik doku kaynağı oluşturmak için kullanılır. Dokunun en,boy ve derinliği aynı boyuttadır. 3 boyutlu dokuları bir küp gibi düşünebiliriz. Küpü oluşturan her yüzeye ayrı ayrı dokular kaplanabilir. Kübik dokular genelde ortamların 360 derecelik görünüşlerini tutmak amacı ile kullanılırlar. Daha sonra bu dokular uygulama içerisinde gökyüzü oluşturmak için (sky box), yansıtma özelliğine sahip objelerin ortamı yansıtmasının simülasyonunda (Environment Mapping) vs. kullanılabilirler. Sözgelimi bir arabanın kaportası, su, çaydanlık gibi pürüzsüz yüzeylere sahip varlıkların ortamı yansıtması örnek olarak gösterilebilir. Aşağıdaki resimlerden ilkinde küp dokunun temsili bir resmi görünmektedir. Ikinci resimde dokuya ait yüzeylerin doku koordinatları ile ilişkisi gösterilmektedir. Üçüncü resimde de örnek bir küp dokusu gösterilmektedir. Yalnız aşağıdaki resim sizi yanıltmasın. Kübik dokular fiziksel olarak dosya içerisinde aşağıdaki gibi bir görünümde saklanmazlar. Her yüzey birbirinden bağımsızdır. Dördüncü resimde de kübik dokuların ortamı nesneler üzerinde yansıtması amacı ile kullanılışını görüyoruz.




Fonksiyonun örnek kullanımı:

C/C++ kodu:

IDirect3DCubeTexture9 *cubeTexture;
lpd3dDevice->CreateCubeTexture( 1024, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &cubeTexture, 0 );

IDirect3DDevice9::CreateDepthStencilSurface: Depth stencil yüzeyi oluşturur. Depth buffer sahnenin derinlik bilgisini tutar. Aşağıdaki resimde görüldüğü gibi kameraya yakın modeller açık renkli, uzağa doğru gidildikçe ise modellerin koyulaştığını görüyoruz. Rasterize esnasında modellerin hangisinin önde hangisinin arkada çizileceği bu buffera bakılarak belirlenir. Ayrıca gölge, sis, ayna gibi efektlerin oluşturulmasında yine depth bufferdan yararlanılmaktadır.

Dipnot: Rasterize grafik programlamada sık kullanılan bir deyim olduğu için yeri gelmişken onu da açıklayayım. Rasterize elimizdeki verilerin(vertex,polygon,dokular,shaderler vs) belirli bir işlem sürecinden geçerek karşımıza pixellerden oluşan bir görüntü olarak gelmesi olayına denir.



IDirect3DDevice9::CreateIndexBuffer: Index buffer oluştumakta kullanılır. Index bufferlar primitif çizerken vertex bufferdeki vertexlerin hangi sıra ile alınıp kullanılacağını belirleyen vertex numaralarını (indexlerini) tutan bellek bölgeleridir. Index bufferleri kullanmak aynı vertexlerin birden çok kere kullanılmalarını önleyerek hafıza tasarrufu ve ekran kartına çizim için gönderilecek vertex miktarını azaltarak performans artışı sağlamaktadır.

Örneğin bir quad(kare primitif) çizmek istersek bunu aşağıdaki resimdeki gibi iki polygonu kullanarak gerçekleştirebiliriz. Eğer quad çizimini index bufferları kullanamadan yani indexsiz çizdirmek istersek vertex bufferin içini polygonları oluşturan vertexlerin koordinatları ile aşağıdaki gibi doldurmalıyız. Vertex bufferi, her polygon 3 vertexten meydana geldiğinden 2polygon*3vertex=6vertexle doldururuz. Sadece vertex bufferler kullanıldığında primitifler çizilirken vertex bufferlardan veri doğrusal olarak alınır. Yani vertex bufferda belirtilen indexten başlanıp vertexler sıra ile alınıp polygon çizimi için kullanılır. Vertex bufferdeki 0,1,2 noktaları 1. polygonu, 3,4,5 noktaları 2.polygonu, 6,7,8 3. polygonu... oluşturur ve bu böyle sıra ile gider.


Index bufferleri kullanırsak durum aşağıda görüldüğü gibi gerçekleşir. Dikkat ederseniz vertex bufferde ortak noktaları kullanan polygonların vertexleri sadece bir kere kullanıldı. Bu yöntem örneğimizde bizim fazladan 2 vertex kullanmamızı önledi. Index bufferlar kullanıldığı zaman ekran kartı polygonları çizerken vertexleri index bufferda gösterilen sıra ile alıp kullanır.



Fonksiyonun örnek kullanımı:

C/C++ kodu:

LPDIRECT3DINDEXBUFFER9 lpIndexBuffer;
...
//Hafızada indexler için alan ayırma işlemi yapılıyor.
lpDevice->CreateIndexBuffer(dwNumPolygonIndex*3*sizeof(int),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&lpIndexBuffer,NULL);
 
WORD *pIndices;
lpIndexBuffer->Lock(0,0,(void **)&pIndices,0);
for (DWORD n=0;n<dwNumPolygonIndex;n++) { 
    pIndices[n*3]  =pPolygonIndex[n].nVertexIndex[0];
    pIndices[n*3+1]=pPolygonIndex[n].nVertexIndex[1];
    pIndices[n*3+2]=pPolygonIndex[n].nVertexIndex[2];
}
lpIndexBuffer->Unlock();


IDirect3DDevice9::CreateOffscreenPlainSurface: Belirtilen boyutlarda bir yüzey oluşturmak için kullanılır. 

Fonksiyonun örnek kullanımı:

C/C++ kodu:

IDirect3DSurface9* lpSurface; 
lpd3dDevice->CreateOffscreenPlainSurface( 512, 512, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &lpSurface, NULL);


IDirect3DDevice9::CreatePixelShader: Pixel Shader oluşturmak için kullanılır.

IDirect3DDevice9::CreateQuery: Gerçek zamanlı olarak ekran kartı üzerinde bazı sorgulamalar yapmak için kullanılır. Vcache, occlusion , işlenen d3d çağrıları (komutları), işlenen polygon sayısı, işlenen verilerin yüzde olarak işlenme miktarları gibi bilgileri elde etmek mümkündür.

Aşağıdaki örnekte bir çok alanda kullanabileceğiniz occlusion sorgulama ile ilgili ufak bir örnek göstereceğim. Occlusion sorgusu örnekte göreceğiniz gibi BEGIN END blokları arasında çizilen modelin kaç pixel olarak çizildiğini sorgular. Eğer dönen değer sıfır pixel ise model sahnede görünmüyor demektir. Occlusion sorgulamanın bu özelliğini ne şekilde değerlendirebiliriz? Örneğin güneşten yayılan lens flare efektinin güneşin ekrana çizilip çizilmemesi durumuna göre çizilmesini yada çizilmemesini sağlayabiliriz. Güneş modeline bir duvarın arkasından baktığımızda occlusion sorgulamadan bize dönecek değer 0 pixel olur. Çünkü güneş görünmüyordur. Bu durumda lens flare efektini çizdirmeyiz.

Occlusion sorgulama eleme sistemlerinde de sıklıkla kullanılmaktadır. Şimdi düşünün bir ormandasınız. Önünüzde binlerce ağaç var. Siz önünüzdeki bu binlerce ağaçtan kaç tanesini görebiliyorsunuz. Önünüzdeki ağaçlar arkalarda olan bir çok ağacı görmenizi engelliyor. Işte bu durumda görünmeyen ağaçları çizdirmemek size inanılmaz performans kazandıracaktır. Yalnız bu işlemin ufak bir püf noktası var. Sahneye önce çizilecek ağaçların çok çok düşük polygonlu halleri çizilir. Sahneye az sayıda polygon çizdirmek ekran kartını yormaz.Occlusion sorguyu her düşük polygonlu ağaç modeli üzerinde ayrı ayrı gerçekleştireceğiz. Eğer dönen değer 0 pixel ise ağaç sahnede görünmüyor demektir. Bu durumda sorguyu gerçekleştirdiğimiz düşük polygonlu ağaca ait yüksek polygonlu ağaç modelini çizdirmeyiz.

D3DQUERYTYPE_OCCLUSION yerine başka sorgular seçebilirisiniz.

Fonksiyonun örnek kullanımı:

C/C++ kodu:
 
LPDIRECT3DQUERY9 d3dQuery;
DWORD pixelsVisible;
//init
lpDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, &d3dQuery );//Occlusion sorgusu yarat. 
..
//render
d3dQuery->Issue( D3DISSUE_BEGIN ); 
//modeli çiz
d3dQuery->Issue( D3DISSUE_END );
while(d3dQuery->GetData((void *) &pixelsVisible, sizeof(DWORD), D3DGETDATA_FLUSH) == S_FALSE);
 

IDirect3DDevice9::CreateRenderTarget: Sahnenin bir yüzeye çizilmesi için gerekli yüzey kaynağını oluşturmakta kullanılır. Daha sonra bu yüzey sahnedeki herhangi bir primitifi kaplamakta yada shaderlerde bazı post process efektlerin oluşturulmasında kullanılabilir.

IDirect3DDevice9::CreateStateBlock: Yeni bir StateBlock oluşturur ve belirtilen tipteki tüm belirteçlerin kaydı alınır. StateBlocklar durum belirteçlerine (States) ait bilgileri tutarlar.  Fonksiyonun ilk parametresi aşağıdaki değerleri alabilir. Bu değerler tipi belirtilen tüm durum belirteçlerinin kaydının tutulması gerektiğini belirtir.

Fonksiyonun örnek kullanımı:

C/C++ kodu:
D3DSBT_ALL  //Tüm durum belirteçlerinin kaydını tut.
D3DSBT_PIXELSTATE //Sadece pixeller üzerinde etkili olan durum belirteçlerinin kaydını tut.
D3DSBT_VERTEXSTATE //Sadece vertexler üzerinde etkili olan durum belirteçlerinin kaydını tut. 
 
//Örneğin;
pd3dDevice->SetRenderState ( D3DRS_ZENABLE, true ); //D3DRS_ZENABLE durum belirteci pixeller üzerinde etkilidir.
pd3dDevice->SetRenderState ( D3DRS_CULLMODE, D3DCULL_CW); //D3DRS_CULLMODE durum belirteci vertexler üzerinde etkilidir.
 
HRESULT hr;
IDirect3DStateBlock9* pStateBlock = NULL;
pd3dDevice->CreateStateBlock( D3DSBT_ALL , &pStateBlock);//Tüm belirteçlerin kaydını ve durumlarını al.

IDirect3DDevice9::CreateTexture: Doku kaynağı oluşturmak için kullanılır. Doku kaynakları modellerin kaplanmasında yada shaderlere parametre olarak verilebilir.

Fonksiyonun örnek kullanımı:

C/C++ kodu:
LPDIRECT3DTEXTURE9 lpTexture;
lpDevice->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET,mode.Format, D3DPOOL_DEFAULT, &lpTexture,NULL);

IDirect3DDevice9::CreateVertexBuffer: Vertex buffer oluşturmakta kullanılır. Vertex bufferlar primitiflere ait vertex dizilerini tutan bellek bölgeleridir. CreateIndexBuffer fonksiyonunun anlatımında vertex bufferlar hakkında daha ayrıntılı bilgi verilmiştir.

Fonksiyonun örnek kullanımı:
C/C++ kodu:

LPDIRECT3DVERTEXBUFFER9 lpVertexBuffer;
 
//Vertex yapısı
struct POLYGON_VERTEX{
    D3DXVECTOR3 vPosition;//Vertexin pozisyonu
    D3DXVECTOR3 vNormal;//Vertexin normali (ışıklandırma için gerekli)
    D3DXVECTOR2 vTex0;//Doku koordinatları (u,v)
    static const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //Vertexe ait özellikleri sürücüye tanıtmak için gerekli tanımlama
};
...
//Vertexler için hafızada alan ayırma işlemi yapılıyor.
lpd3dDevice->CreateVertexBuffer( dwNumPolygon*3*sizeof(POLYGON_VERTEX), NULL, POLYGON_VERTEX::FVF, D3DPOOL_DEFAULT, &lpVertexBuffer, NULL );
 
//vertex buffer dolduruluyor.
HRESULT hr;
hr=lpVertexBuffer->Lock(0,0,(void**)&pVertices, 0);
for (DWORD n=0;n<dwNumVertex;n++) { 
    pVertices[n].vPosition=Vertex[n].vPosition;//Polygon vertexleri
    pVertices[n].vNormal  =Vertex[n].vNormal;//Vertex normalleri
    pVertices[n].vTex0    =Vertex[n].vTex0;//Doku koordinatları
} 
lpVertexBuffer->Unlock();
IDirect3DDevice9::CreateVertexDeclaration: Shader çizimi esnasında kullanılan primitife ait vertexlerin yapısını sürücüye tanıtmakta kullanılan yapıları oluşturmakta kullanılır. Kısaca Flexible Vertex Formata (FVF) benzer bir tanımlamanın vertex shaderler için kullanılan halidir diyebiliriz. FVF primitif çizerken, Vertex deklarasyon ise shader çizerken primitife ait vertexin yapısını sürücüye tanıtmakta kullanılır.
Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
IDirect3DVertexDeclaration9 *g_VertDecl= NULL;
 
D3DVERTEXELEMENT9 vertexElement[] =
{
    { 0, sizeof( float ) * 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
    { 0, sizeof( float ) * 3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
    { 0, sizeof( float ) * 6, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
    { 0, sizeof( float ) * 8, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
    { 0, sizeof( float ) * 11, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
    D3DDECL_END()
};
 
lpDevice->CreateVertexDeclaration( vertexElement, &g_VertDecl ); 

IDirect3DDevice9::CreateVertexShader: Vertex Shader oluşturmak için kullanılır.

IDirect3DDevice9::CreateVolumeTexture: 3 boyutlu eni boyu ve derinliği birbirinden farklı dokular oluşturmak için kullanılır.

IDirect3DDevice9::DeletePatch: Id numarsı (handle) verilen patch kaynağını hafızadan siler.

IDirect3DDevice9::DrawIndexedPrimitive: Indexli primitif çizmek için kullanılır. CreateIndexBuffer fonksiyonunda index bufferlarla ilgili kısa açıklama yapılmıştır.

Fonksiyonun örnek kullanımı:
 C/C++ kodu:
 
...
lpDevice->SetFVF(POLYGON_VERTEX::FVF);
lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX) );
lpDevice->SetIndices(lpIndexBuffer); 
lpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,dwNumVertex,0,dwNumPolygonIndex);
...

IDirect3DDevice9::DrawIndexedPrimitiveUP: Direct3D ye ait vertex ve index bufferları kullanmadan direk kullanıcı tanımlı dizileri kullanarak primitif çizmekte kullanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
struct POLYGON_VERTEX{
    D3DXVECTOR3 vPosition;
    D3DXVECTOR3 vNormal;
    D3DXVECTOR2 vTex0;//Doku koordinatları (u,v)
    static const DWORD FVF =(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);
}
 
//UP
POLYGON_VERTEX *lpVertexBufferUP;
WORD *lpIndexBufferUP;
 
//init
//UP vertex buffer
lpVertexBufferUP=new POLYGON_VERTEX[dwNumVertex]; //vertexler için bir dizi oluştur.
for (DWORD n=0;n<dwNumVertex;n++) {
    //Vertex dizisini daha önceden model dosyasından okuduğumuz vertex bilgileri ile doldur.
    lpVertexBufferUP[n].vPosition= Vertex[n].vPosition;
    //Vertex normalleri
    lpVertexBufferUP[n].vNormal= Vertex[n].vNormal;
    //Polygon doku koordinatları
    lpVertexBufferUP[n].vTex0=  Vertex[n].vTex0;
 
}
 
//UP index buffer
lpIndexBufferUP=new WORD[dwNumPolygonIndex*3];//vertex indexleri için dizi oluştur
for (DWORD n=0;n<dwNumPolygonIndex;n++) {//Index dizisini daha önceden model dosyasından okuduğumuz index verisi ile doldur.
    lpIndexBufferUP[n*3]  =pPolygonIndex[n].nVertexIndex[0];
    lpIndexBufferUP[n*3+1]=pPolygonIndex[n].nVertexIndex[1];
    lpIndexBufferUP[n*3+2]=pPolygonIndex[n].nVertexIndex[2];
}
 
//Render
...
//DrawIndexedPrimitiveUP fonksiyonu ile primitif çizilirken aşağıda belirtilen fonksiyonlar kullanılmaz. Çünkü bu fonksiyonlar ile yapılacak işlemler DrawIndexedPrimitiveUP fonksiyonu tarafından zaten gerçekleştiriliyor.
//lpDevice->SetFVF(..); //Çağırmaya gerek yok. Çünkü DIPUP fonksiyonunda 8 inci parametre ile vertex bilgisini belirttik.
//lpDevice->SetStreamSource(..);Çağırmaya gerek yok. Çünkü DIPUP fonksiyonunda 7 nci parametre ile vertex bufferi belirttik.
//lpDevice->SetIndices(...);// Çağırmaya gerek yok. Çünkü DIPUP fonksiyonunda 5 inci parametre ile index  bufferi belirttik.
lpDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,dwNumVertex,dwNumPolygonIndex,lpIndexBufferUP,D3DFMT_INDEX16,lpVertexBufferUP,sizeof(POLYGON_VERTEX));
...
 
IDirect3DDevice9::DrawPrimitive: Indexli olmayan vertex dizili primitifleri çizer. Primitif çizilirken sadece vertex buffer kullanılır. CreateIndexBuffer fonksiyonunda bu konuya deyinilmiştir.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
..
lpd3dDevice->BeginScene();//Çizim işlemlerini başlat
...
lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX) );//çizim sırasında kullanılacak vertex buffer belirtiliyor.
lpDevice->SetFVF(POLYGON_VERTEX::FVF); //sürücüye vertex buffera ait vertexlerin yapısı bildiriliyor. 
lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );//vertex bufferin 0. indexinden başlayarak 1 adet polygon çiz
lpd3dDevice->EndScene();//Çizim işlemlerini sonlandır.
...

IDirect3DDevice9::DrawPrimitiveUP: Direct3D ye ait vertex bufferı kullanmadan direk kullanıcı tanımlı dizileri kullanarak primitif çizmekte kullanılır.

Fonksiyonun örnek kullanımı:
 C/C++ kodu:
 
struct POLYGON_VERTEX{
    D3DXVECTOR3 vPosition;
    D3DXVECTOR3 vNormal;
    D3DXVECTOR2 vTex0;//Doku koordinatları (u,v)
    static const DWORD FVF =(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);
}
 
//UP
POLYGON_VERTEX *lpVertexBufferUP;
 
//init
//UP vertex buffer
lpVertexBufferUP=new POLYGON_VERTEX[dwNumPolygonIndex*3]; //vertexler için bir dizi oluştur. polygon sayısı * 3
 
//Eğer kullandığımız model dosyası içinde vertex ve index bilgileri ayrı ayrı olarak tutuluyorsa DrawPrimitiveUP fonksiyonunda primitif çizimi için sadece vertexleri kullanılacağımızdan dosyadan okuduğumuz vertexleri indexlere göre yeniden yapılandırmamız gerekiyor. Bu durumda her polygon için 3 vertex bilgisi elde etmiş olacağız. Aşağıdaki döngü bu işlemi gerçekleştiriyor.
for (DWORD n=0;n<dwNumPolygonIndex;n++) { 
    //Polygon vertexleri
    lpVertexBufferUP[n].vPosition= Vertex[n].vPosition;
    //Vertex normalleri
    lpVertexBufferUP[n].vNormal= Vertex[n].vNormal;
    //doku koordinatları
    lpVertexBufferUP[n].vTex0 = Vertex[n].vTex0 ;
}
 
 
//Render
//DrawIndexedPrimitiveUP fonksiyonunda olduğu gibi yine kullanım dışı kalan fonksiyonlar var.
//lpDevice->SetFVF(..); //Çağırmaya gerek yok. Çünkü DPU fonksiyonunda 4 üncü parametre ile vertex bilgisini belirttik.
//lpDevice->SetStreamSource(..);Çağırmaya gerek yok. Çünkü DPU fonksiyonunda 3 üncü parametre ile vertex bufferi belirttik.
 
lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,dwNumPolygonIndex, lpVertexBufferUP,sizeof(POLYGON_VERTEX));
 
IDirect3DDevice9::DrawRectPatch: Sürücüye atanmış olan vertex bufferi kullanarak dörtgen patch çizmeye yarar.

IDirect3DDevice9::DrawTriPatch: Sürücüye atanmış olan vertex bufferi kullanarak üçgen patch çizmeye yarar.

IDirect3DDevice9::EndScene: BeginScene ile başlatılan çizim blokunu sonlandırır. BeginScene fonksiyonunda fonksiyonla ilgili örnek bulunmaktadır.

IDirect3DDevice9::EndStateBlock: BeginStateBlock fonksiyonu ile başlatılan durum belirteçlerinin kayıt işlemini sonlandırır ve elde edilen bilgileri döndürür. BeginStateBlock fonksiyonunda fonksiyon ile ilgili örnek bulunmaktadır.

IDirect3DDevice9::EvictManagedResources: POOL_MANAGED parametresi ile oluşturulan kaynakları (doku, vertex buffer, index buffer) ekran kartı hafızasından sistem hafızasına gönderir. Not: POOL_MANAGED parametresi ile oluşturulan kaynaklar sistem hafızasına yüklenirler gerekli olduğu durumlarda ekran kartı hafızasına yüklenirler.

IDirect3DDevice9::GetAvailableTextureMem: Kullanılabilir doku hafızası miktarını döndürür.

IDirect3DDevice9::GetBackBuffer: Sürücüye ait back bufferı (arka tamponu) döndürür. Olayı biraz açarsak. Direct3D çizim işlemlerini gerçekleştirirken oluşan görüntüyü gözümüzün önüne getirmeden önce BackBuffer(Arka tampon) denilen bir bellek bölgesinde oluşturur. CreateAdditionalSwapChain fonksiyonunda konu ile ilgili daha fazla açıklama ve fonksiyonun örnek kullanımını bulabilirsiniz. Aşağıdaki örnekte GetBackBuffer fonksiyonunun bir başka kullanım alanını daha göstermek istedim. Fonksiyon back bufferı diske kaydediyor. Kısacası sahnenin ekran görüntüsünü çekiyor.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
void ScreenShot(char* file_name,int Width, int Height){
    IDirect3DSurface9* backbuff;
    //belirtilen boyutta bir yüzey kaynağı oluştur 
    g_pd3dDevice->CreateOffscreenPlainSurface(Width, Height, D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &backbuff,NULL); 
    //Back bufferi yüzey kaynağına aktar
    HRESULT hr =g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backbuff);   
    if(hr != D3D_OK){
        MessageBox(NULL,"Ekran görüntüsü alınamadı","Hata",NULL);
        backbuff->Release();
        return;
    }
    //Yüzey kaynağını diske belirtilen formatta kaydet.
    D3DXSaveSurfaceToFile(file_name, D3DXIFF_JPG , backbuff, NULL, NULL);
    backbuff->Release();
}

IDirect3DDevice9::GetClipPlane: Index numarası verilen kullanıcı tanımlı kırpma zeminine ait bilgileri almak için kullanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DXPLANE plane;
lpDevice->GetClipPlane(0,plane);

IDirect3DDevice9::GetClipStatus: Primitif çizimi sırasında kırpılma durumu ile ilgili bilgileri almak için kullanılır. Kırpma durumu ile ilgili bilgilere sadece sürücü "software vertex processing" (yazılım tabanlı vertex işleme) parametresi ile oluşturuldu ise erişilebilir.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DCLIPSTATUS9 clipstatus;
lpDevice->GetClipStatus(&clipstatus);

IDirect3DDevice9::GetCreationParameters: Sürücünün oluşturulurken hangi özelliklerde oluşturulduğu ile ilgili bazı bilgilerin alınması için kullanılır. Bu bilgileri D3DDEVICE_CREATION_PARAMETERS yapısı üzerinde açıklayalım.

C/C++ kodu:
 
typedef struct _D3DDEVICE_CREATION_PARAMETERS
{
    UINT            AdapterOrdinal; //Sürücünün oluşturulduğu ekran kartının id sini belirtir.
    D3DDEVTYPE      DeviceType;     //Sürücü tipini belirtir. HAL(donanım tabanlı rasterizer),REF(yazılım tabanlı rasterizer),SW(kullanıcı tanımlı rasterizer)
    HWND            hFocusWindow;   //Sürücünün çizim yaptığı pencerenin id sini döndürür.
    DWORD           BehaviorFlags;  //Sürücünün genel işleyişini belirleyen parametreleri döndürür. Ayrıntılı bilgi için SDK dokümanlarını inceleyiniz.
} D3DDEVICE_CREATION_PARAMETERS;

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
D3DDEVICE_CREATION_PARAMETERS lpCrParameters;
lpDevice->GetCreationParameters(&lpCrParameters);

IDirect3DDevice9::GetCurrentTexturePalette: Sürücüde o an aktif olan renk paletinin indexini döndürür.

IDirect3DDevice9::GetDepthStencilSurface: Sürücünün derinlik yüzeyini (Depth Buffer) almak için kullanılır.

IDirect3DDevice9::GetDeviceCaps: Ekran kartının desteklediği özellikleri, kabiliyetlerini öğrenmek için kullanılır. Bilgileri D3DCAPS9 yapısı olarak döndürür.

IDirect3DDevice9::GetDirect3D: Direct3D arabirimini döndürür.

IDirect3DDevice9::GetDisplayMode:  Sürücünün ekran çözünürlüğü (320x240,800x600...), renk çözünürlüğü (16bit,32bit...), ekran tazeleme frekansı, görüntü formatı gibi özellikleri almak için kullanılır.

IDirect3DDevice9::GetFrontBufferData: Belirtilen takas zincirine (swap chain) ait ön tamponun (front buffer) bir kopyasını alır ve sistem hafızasında belirtilen yüzeye aktarır. Performans yönünden oldukça yavaştır.

IDirect3DDevice9::GetFVF: Sürücüde o an aktif olan FVF yapısını döndürür.

IDirect3DDevice9::GetGammaRamp: Sürücüye atanmış gamma dizisini döndürür.

IDirect3DDevice9::GetIndices: Sürücüye atanmış olan index bufferi geri döndürür.

IDirect3DDevice9::GetLight: Index numarası verilen ışığın özelliklerini döndürür.

IDirect3DDevice9::GetLightEnable: Index numarası verilen ışığın aktif yada pasif olup olmadığını döndürür.

IDirect3DDevice9::GetMaterial: Sürücüye atanmış olan aktif materialin özelliklerini döndürür.

IDirect3DDevice9::GetNPatchMode: Çizilmekte olan patchin segment sayısını döndürür.

IDirect3DDevice9::GetNumberOfSwapChains: Aynı sürücü üzerinde yaratılmış sahnelerin (swap chain) sayısını döndürür. Modelleme programlarından da hatırlayacağınız çoklu görüş alanlarının sayısını döndürür.

IDirect3DDevice9::GetPaletteEntries: Index numarası verilen renk paletlerini geri döndürür.
 
IDirect3DDevice9::GetPixelShader: O an aktif olan pixel shaderi döndürür.

IDirect3DDevice9::GetPixelShaderConstantB: Pixel shaderda belirtilen bool tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetPixelShaderConstantF: Pixel shaderda belirtilen float tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetPixelShaderConstantI: Pixel shaderda belirtilen integer tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetRasterStatus: Index numarası verilen takas zincirinin (swap chain) rasterize durumu ile ilgili bilgi verir.

IDirect3DDevice9::GetRenderState: Belirtilen durum belirtecinin değerini döndürür.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
DWORD dwDeger;
lpDevice->GetRenderState(D3DRS_FILLMODE,&dwDeger);
if(dwDeger==D3DFILL_SOLID)//Polygonlar katı model (içi pixellerle doldurulmuş ) olarak mı çiziliyor.
    lpDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); //Polygonları telkafes (polygonların sadece kenar çizgilerini çiz, içini doldurma) şeklinde çiz.
 

IDirect3DDevice9::GetRenderTarget: Index numarası verilen render-target ( üzerine çizim yapılabilme özelliği olan / üzerine çizim yapılmakta olan) tipli yüzeyi döndürür.

IDirect3DDevice9::GetRenderTargetData: Ekran kartı hafızasındaki render-target (üzerine çizim yapılabilme özelliği olan / üzerine çizim yapılmakta olan ) tipli yüzeyi sistem hafızasında konumlu başka bir yüzeye kopyalar. Bu işlem için her iki yüzeyinde aynı boyutta ve formatlarda olması gerekmektedir.

IDirect3DDevice9::GetSamplerState: Sürücüye atanmış olan dokunun adresleme ve filtreleme ile ilgili özelliklerine ait değerleri almak için kullanılır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
DWORD dwMin;
lpDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, &dwMin );

IDirect3DDevice9::GetScissorRect: Sürücüye atanmış olan kırpma alanını döndürür. SetScissorRect fonksiyonunda açıklama yapılmıştır.

IDirect3DDevice9::GetSoftwareVertexProcessing: Vertexlerin yazılımsal olarak mı yoksa donanımsal olarak mı işlendiğini döndürür.

IDirect3DDevice9::GetStreamSource: Sürücüye atanmış olan vertex bufferi döndürür.

IDirect3DDevice9::GetStreamSourceFreq: O an sürücüye atanmış örnekleme tekniği ile çizilmekte olan primitiflerden kaç tane çizildiğinin sayısını döndürür.

IDirect3DDevice9::GetSwapChain: Id numarası verilen takas zincirini (swap chain) döndürür.

IDirect3DDevice9::GetTexture: Sürücüye atanmış olan belirtilen katmandaki dokuyu geri döndürür.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
LPDIRECT3DBASETEXTURE9 lpTexture;
lpDevice->GetTexture(0,&lpTexture); //Sıfırıncı katmandaki sürücüye en son atanmış dokuyu döndürür.
//lpDevice->SetTexture(0,lpTexture);//Sıfırıncı katmana belirtilen dokuyu atar

IDirect3DDevice9::GetTextureStageState: Sürücüye atanmış olan x katmanındaki dokunun özelliklerini döndürür.

IDirect3DDevice9::GetTransform: Sürücüye atanmış olan belirtilen tipteki matrixleri almak için kullanılır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
D3DXMATRIX matWorld, matView, matProjection, matWVP;
lpDevice->GetTransform(D3DTS_WORLD,&matWorld);
lpDevice->GetTransform(D3DTS_VIEW,&matView);
lpDevice->GetTransform(D3DTS_PROJECTION,&matProjection);
//matWVP = matWorld * matView * matProjection;

IDirect3DDevice9::GetVertexDeclaration: Sürücüye atanmış olan vertex deklesaryonunu  geri döndürür.

IDirect3DDevice9::GetVertexShader: Sürücüye atanmış olan vertex shaderi geri döndürür.

IDirect3DDevice9::GetVertexShaderConstantB: Vertex shaderda belirtilen bool tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetVertexShaderConstantF: Vertex shaderda belirtilen float tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetVertexShaderConstantI: Vertex shaderda belirtilen integer tipli değişkenin değerini almak için kullanılır.

IDirect3DDevice9::GetViewport: O anki Direct3D sürücüsüne ait görüş alanı bilgisini elde etmekte kullanılır. Bilgiler belirtilen D3DVIEWPORT9 tipindeki yapımıza aktarılır.

IDirect3DDevice9::LightEnable: Index numarası verilen ışığı aktif yada pasif (açar/kapatır) yapar.

IDirect3DDevice9::MultiplyTransform: Model, görüş yada projeksiyon matrixlerini belirtilen matrixle çarpmak için kullanılır.

IDirect3DDevice9:: Present: Sürücüyü bir sonraki çizim işlemi için hazırlar.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
 //sahneyi temizle
lpDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(100,100,100), 1.0f, 0 );
//Çizim işlemine başla
lpDevice->BeginScene();
//Çizim işlemleri
//Çizim işlemini sonlandır
lpDevice->BeginScene();
//Şimdiye kadar icra edilen çizim işlemlerinin sonucunu ekrana göster ve sürücüyü bir sonraki çizim işlemi için hazırla
lpDevice->Present( NULL, NULL, NULL, NULL );

IDirect3DDevice9::ProcessVertices: Belirtilen vertex bufferdeki vertexleri belirli bir işlem sürecinden geçirerek elde edilen yeni vertexleri belirtilen vertex buffera atar. Vertexler aşağıdaki işlem sürecinden geçer.
-Vertexler önce "world + view + projection" matrixleri tarafından dönüşüme uğrar.
-Görüş alanı özelliklerine göre (viewport) vertexlerin ekran koordinatları hesaplanır.
-Eğer kırpma açıksa kırpma kodu oluşturularak hedef vertex buffer ile ilişkilendirilerek saklanır. Eğer vertexlerden biri görüş alanı içerisindeyse (view frustum) vertexlerin ekran koordinatları hesaplanarak belirtilen vertex buffera aktarılır değilse vertexlerin projeksiyon sistemindeki konumları vertex buffera aktarılır.

IDirect3DDevice9::Reset: Çalışma zamanı sürücünün yeninden yapılandırılması istenildiğinde kullanılır. Örneğin uygulama çalışırken uygulamanın tam ekran-pencere moduna geçişini, çözünürlük değiştirme, sürücünün arızaya geçtiği durumlarda onarılması konularında bu fonksiyondan yararlanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
//Sürücümüzü tam ekran modunda çalışacak şekilde oluşturduk.
HRESULT InitD3D( HWND hWnd ) 
{
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = FALSE;
    d3dpp.BackBufferWidth=640;
    d3dpp.BackBufferHeight=480; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat =D3DFMT_X8R8G8B8;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    ...
 
 
 
void Render()
{
    HRESULT hr;
    hr = g_pd3dDevice->TestCooperativeLevel();
    if( hr==D3DERR_DEVICELOST ){//sürücü arıza durumunda mı?
        Sleep(100);//Her kontrolden sonra biraz bekle
        return;//Çizim rutinlerine geçmeden başa dön
    }
    else if( hr==D3DERR_DEVICENOTRESET ){//sürücü resetlenmeye hazır mı?
        ReleaseResources();//kaynakları serbest bırak
        g_pd3dDevice->Reset(&d3dpp);//sürücüyü resetle
        InitResources();//kaynakları yeniden yükle
        return;//Çizim rutinlerine geçmeden başa dön
    }
    
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
    ...

IDirect3DDevice9::SetClipPlane: Kullanıcı tanımlı kırpma zeminleri oluşturmak için kullanılır. Zeminin arkasında kalan objeler kırpma işlemine tabi tutulur ve ekrana çizilmezler. Aynı anda birden çok kırpmaz zemini kullanmak mümkündür. Objelerin kesitlerini göstermek, ayna gibi efektlerin yapımında kullanılmaktadır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DXPLANE plane;
D3DXPlaneFromPointNormal(&plane,&D3DXVECTOR3(100,0,0),&D3DXVECTOR3(1,0,0)); //(100,0,0) pozisyonunda yönü +X'e (1,0,0) bakan bir kırpma zemini(plane) oluşturduk.
lpDevice->SetClipPlane(0,plane);
lpDevice->SetRenderState(D3DRS_CLIPPLANEENABLE ,D3DCLIPPLANE0);

Aşağıdaki resimde örneğimizin etkileri görülmektedir. Objelerin tanımladığımız kırpma zemininin arkasında kalan kısımları çizilmemektedir.

IDirect3DDevice9::SetClipStatus: Sürücünün kırpma durumunu ayarlamakta kullanılır.

IDirect3DDevice9::SetCurrentTexturePalette: Sürücüye atanmış olan dokunun kullanacağı renk paletini belirtmek için kullanılır.

IDirect3DDevice9::SetCursorPosition: Fare imlecinin pozisyonunu değiştirmek için kullanılır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
lpDevice->SetCursorPosition(100,100,D3DCURSOR_IMMEDIATE_UPDATE );

IDirect3DDevice9::SetCursorProperties: Direct3D tarafından desteklenen fare imlecinin özelliklerini belirtmek için kullanılır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
IDirect3DSurface9* lpSurface;
lpDevice->SetCursorProperties(1,1,lpSurface); //ilk iki parametre doku üzerinde konum belirtmek için kullanılır. Bu konum imlecimizin uç noktası olacak. Üçüncü parametrede de imleç olarak kullanılacak dokuyu belirtiyoruz.

IDirect3DDevice9::SetDepthStencilSurface: Sürücüye belirtilen yüzeyin derinlik yüzeyi olarak kullanılacağını söyler.

IDirect3DDevice9::SetDialogBoxMode: Uygulamanız tam ekran modunda çalışırken de dialog kutularının görüntülenmesine izin verir.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
lpDevice->SetDialogBoxMode(true);//false

IDirect3DDevice9::SetFVF: O an çizdirilecek olan primitifin vertex yapısını sürücüye belirtmek için kullanılır. Kullanacağımız vertex yapısına göre FVF tanımlaması için kullanılacak öğeler de değişecektir. Aşağıda örnek bir tanımlama gösterilmektedir. Ayrıntılı açıklama ve diğer örnek tanımlamalar için SDK dokümanlarını inceleyiniz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
//vertex yapımız
struct POLYGON_VERTEX{
    D3DXVECTOR3 vPosition; //D3DFVF_XYZ
    D3DXVECTOR3 vNormal;  //D3DFVF_NORMAL 
    float tu,tv;                   //D3DFVF_TEX1 
    static const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //vertex yapımızın özellikleri. 
};

Aşağıdaki satır ile çizdireceğimiz primitifdeki vertexlerin hangi özelliklere sahip olacaklarını tanımlıyoruz. Aşağıdaki tanımlamayı yukarıdaki gibi vertex yapımızın içinde de statik olarak tanımlayabiliriz. Yukarıdaki tanımlama bana daha pratik geldiğinden ben öyle kullanmayı tercih ediyorum. FVF değişken statik olarak tanımlandığı için sadece yapı içerinden erişilebilir. Dizi tanımlamalarında bellekte fazladan yer kaplamaz.
const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
//render
lpDevice->SetFVF(POLYGON_VERTEX::FVF); //sürücüye vertex buffera ait vertexlerin yapısı bildiriliyor. 
lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
...

IDirect3DDevice9::SetGammaRamp: Sürücünün parlaklık, karşıtlık ayarını değiştirmek için kullanılır. Genellikle pencere modunda iken bu fonksiyonun etkisi yoktur. Sdk dokümanlarında konu ile ilgili ayrıntılı açıklamayı bulabilirsiniz. Aşağıda D3DGAMMARAMP yapısının içeriğini görüyoruz. Görüldüğü gibi RGB yani kırmızı, yeşil ve mavi renkler 256 lık diziler şeklinde tanımlanmıştır. Bu dizilerin içeriğine göre ışığın parlaklık, karşıtlık etkileri değişecektir. Aşağıdaki örnekte her rengin dizisi aynı değerler ile ve doğrusal olarak doldurulmaktadır. Aşağıdaki grafiklerden ilkinde fonksiyonumuza 0.1f değerini verdiğimizde oluşan sayı dizisinin oluşturduğu rampayı görüyoruz. Yani ışığın en az olduğu ortamın en karanlık göründüğü an. Ikinci grafikte ise fonksiyonumuza 2.2f değerini verdiğimizde ortam ışığı gereğinden fazla aydınlıktır. Yani fonksiyonumuza 0.1 ile 2.2f arasında değerler verdiğimizde ortam parlaklığı karanlıktan aydınlığı doğru gidecektir. Değişik fonksiyonlar kullanarak değişik ışık etkileri elde etmek mümkündür. Bu size kalmış.

C/C++ kodu:
 
typedef struct D3DGAMMARAMP {
    WORD red[256];
    WORD green[256];
    WORD blue[256];
} D3DGAMMARAMP, *LPD3DGAMMARAMP;


Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
void SetGamma(float Gamma){
    D3DGAMMARAMP gamma;
    signed nValue;
    fGamma+=Gamma;
    for (int w=0;w<=255;w++)
    {
        nValue = (int)(w * fGamma * 255);
        if(nValue > 65535) nValue = 65535;
        gamma.red[w]=nValue; 
        gamma.blue[w]=nValue;
        gamma.green[w]=nValue;
    }
    lpDevice->SetGammaRamp(0,D3DSGR_CALIBRATE ,γ);
    if (fGamma<0.1){fGamma=0.1f;}
    if (fGamma>2.2){fGamma=2.2f;}
}

IDirect3DDevice9::SetIndices: Eğer indexli primitif çizilecekse, o anki aktif vertex bufferden vertexlerin ne sıra ile alınacağını gösteren indexlerin tutulduğu index bufferi sürücüye tanıtmak için kullanılır.

Fonksiyonun örnek kullanımı:
C/C++ kodu:
 
LPDIRECT3DINDEXBUFFER9 lpIndexBuffer;
..
.
//Render
lpDevice->SetIndices(lpIndexBuffer); 
lpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,dwNumVertex,0,dwNumPolygonIndex);

IDirect3DDevice9::SetLight: Belirtilen ışık kaynağını sürücüye atar. Direc3D sürücüsü tarafından oluşturulan ışık kaynakları primitiflerin vertex normallerinden yararlanarak ışık etkisini simüle ederler (Per-vertex lightining). Bu sistemde ışık vertexler baz alınarak hesaplandığından polygon üzerindeki pixellere etki edecek ışık interpolasyon (başlangıç ve bitiş değerlerine göre ara değerlerin hesaplanması) edilerek hesaplanır. Yüksek polygonlu objelerde iyi sonuçlar elde edilmesine karşın çok düşük polygonlu objelerde yada sahnelerde kötü sonuçlar elde edilmektedir. Konuyu daha iyi anlamanız açısından aşağıdaki resmi inceleyiniz.
Aşağıdaki örnekte primitife spot ışık kaynağı doğrultulmuştur. Yüksek ve düşük polygonlu modellerde ışığın nasıl simüle edildiği görülmektedir. Görüldüğü gibi düşük polygonlu modellerde sonuç pekte iç açıcı olmamaktadır.

Peki bu durumda ne yapılmalı? Kaliteyi arttırmak için primitiflerin polygon sayısını mı arttıracağız? Tabiki hayır. Bildiğiniz üzere ekran kartlarının en büyük düşmanlarından biri yüksek polygon sayısıdır. Çünkü her ekran kartının kabiliyetleri ve hızı doğrultusunda işleyeceği belirli bir polygon sayısı bulunmaktadır. Ekrana ekran kartı kabiliyetlerini aşan sayıda polygon basarsak ekran kartı bu sayıdaki polygonu işlemekte zorlanacağından oyunumuz teklemeye başlayacaktır. Günümüzdeki ekran kartlarının eskiye oranla kabiliyetlerinin ve hızlarının çok çok artmasına ramen yine de belirli bir sınırları vardır. Gelişen teknolojiyle birlikte ekran kartları daha fazla polygon basabilmekte buna paralel olarakta oyundaki detaylar ve kalite artmaktadır. Ancak polygon sayısı herzaman bir handikap olarak kalmaktadır. Konumumuza dönersek per vertex ışıklandırma sistemindeki bu olumsuz durumu aşmanın iki yolu bulunmaktadır. Ilki eski oyunlarda ve günümüz oyunlarının da bir çoğunda kullanılan light-mapping yöntemidir. Light mapping yönteminde düşük polygonlu ve üzeri bir doku ile kaplı olan primitifin üzeri bir başka doku ile maskelenmektedir. Bu yöntemde çok iyi sonuç alınmasına karşın lightmap verisi (dokusu) önceden hesaplandığı için ışıklandırma statiktir ve oyun boyunca değişmez. Per-vertex ışıklandırma ise dinamik olarak hesaplandığından ışık kaynağı yer değiştirdiğinde ışığın polygonlar üzerindeki etkisi de dinamik olarak değişir. Aşağıdaki resimde lightmapping tekniğinin polygon üzerine uygulanışı gösterilmektedir. Light mapping temelde ekran kartlarının multitexturing (çoklu doku katmanı) yeteneği yardımı ile alt ve üst katman dokuların blend (karıştırılması) edilmesi ile gerçekleştirilir.

Per-vertex ışıklandırma sistemindeki bu olumsuz durumu aşmanın ikinci yolu ise ışıklandırma sistemini shaderler yardımı ile simüle etmektir. Bu sistemde ışıklandırma hesabı polygon üzerindeki her bir pixel için ayrı ayrı hesaplandığından (per-pixel lightining) çok gerçekçi ve dinamik ışık etkileri elde edilmektedir. Per-vertex ve lightmap ışıklandırma sistemleri artık yavaş yavaş yerini per-pixel ışıklandırmaya bırakmaktadırlar. Ayrıca per-pixel ışık sisteminde per-vertex ışık sistemindeki maksimum 8 dinamik ışık kullabilme gibi bir kısıtlama bulunmamaktadır.
Direct3D 3 tip ışık kaynağı desteklemektedir.
Directional Light (Doğrusal ışık kaynağı): Bu ışık kaynağı da spot ışık gibi davranır. Ancak ışık etkisini uzaklığa bağlı olarak yitirmez.
Point Light (Noktasal ışık kaynağı): Noktasal ışık kaynakları ampul gibi davranırlar. Her yöne ışık saçarlar. Işık etkisini uzaklığa göre yitirir.
Spot Light (Spot ışık kaynağı): Spot ışık kaynakları iç içe iki koniden oluşur ve belirtilen yöne doğru ışık saçarlar. Işık etkisini hem bakılan doğrultu boyunca hem de içteki koniden dıştaki koni doğrultusunda uzaklığa göre yitirir.
Ambient Light: Bu ışık kaynaklarına alternatif olarak birde ambient ışık sistemi bulunmaktadır. Bu ışık tipi nesnelerin kendinden yansıyan ışığı ifade etmektedir. SetLight fonksiyonundan ayrı olarak SetRenderState fonksiyonu ile sürücüye atanmaktadır. Ambient ışık sahnedeki bütün nesnelerin vertexlerine aynı oranda etki eder. Sahnedeki genel ışıklandırmanın yoğunluğunu ayarlamakta kullanılmaktadır. Bu işlemde vertex normallerinin, etraftaki ışıkların pozisyonlarının yada etki edecekleri mesafeler göz önünde bulundurulmaz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DLIGHT9 d3dLight;
ZeroMemory( &d3dLight, sizeof(D3DLIGHT9) );
 
d3dLight.Type = D3DLIGHT_POINT; 
//D3DLIGHT_SPOT;  
//D3DLIGHT_DIRECTIONAL; 
//ışığın material üzerinde etki edeceği bölgelerin renkleri belirtiliyor.
d3dLight.Diffuse.r = 1.0f;
d3dLight.Diffuse.g = 1.0f;
d3dLight.Diffuse.b = 1.0f;
d3dLight.Ambient.r = 1.0f;
d3dLight.Ambient.g = 1.0f;
d3dLight.Ambient.b = 1.0f;
d3dLight.Specular.r = 1.0f;
d3dLight.Specular.g = 1.0f;
d3dLight.Specular.b = 1.0f;
d3dLight.Position =D3DXVECTOR3(0.0f,1000.0f,0.0f); //ışığın pozisyonu
//bu parametre spot ve directional ışıklar için ışığın doğrultusunu belirtmek amacıyla kullanılır.
//d3dLight.Direction=D3DXVECTOR3(0.0f,-1.0f,0.0f);
//Işığın uzaklığa göre etkisinin azalması ile ilgili parametreler. Directional ışık kaynaklarında kullanılmazlar.
d3dLight.Attenuation0 = 0.0f; 
d3dLight.Attenuation1 = 1.0f;
d3dLight.Attenuation2 = 0.0f;
//d3dLight.Theta=D3DXToRadian(10.0f);
//d3dLight.Phi=D3DXToRadian(20.0f);
 
d3dLight.Range = 10000.0f;//Işığın etki edeceği uzaklık miktarı. Directional ışık kaynaklarında kullanılmaz.
g_pd3dDevice->SetLight(0, &d3dLight);//Oluşturduğumuz bu yapıyı 0 indexli ışık olarak ata. D3DLIGHT9 yapısının parametrelerini değiştirerek değişik tipte,pozisyonlarda,renklerde vs. değişik özelliklerde ışık kaynaklarını değişik index numaraları vererek sürücüye atayabiliriz. Istediğiniz kadar ışık kaynağı oluşturabilirsiniz ancak directx aynı anda en fazla 8 dinamik ışığı destekler. 
g_pd3dDevice->LightEnable( 0, TRUE );//Oluşturduğumuz 0 indexli ışık kaynağını aktive et/aç. En fazla 8 ışık.
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );//Işıklandırmayı aç. Sahnedeki tüm ışıklar parametreye göre aktif yada pasif olurlar.
 
 
//Ambient ışığın kullanımı
m_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00ff0000);

IDirect3DDevice9::SetMaterial: Sürücü için kullanılacak materyal özelliklerini ayarlamakta kullanılır. Işıklandırmaya doğrudan etkisi bulunmaktadır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
mtrl.Diffuse.r = mtrl.Ambient.r =mtrl.Specular.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g =mtrl.Specular.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b =mtrl.Specular.b = 1.0f;
mtrl.Diffuse.a = mtrl.Ambient.a =mtrl.Specular.a = 1.0f;
mtrl.Power = 100;
lpDevice->SetMaterial( &mtrl );

IDirect3DDevice9::SetNPatchMode: Çizilmekte olan patchin segment sayısını birbaşka deyişle çözünürlüğünü ayarlamakta kullanılır. Parametre olarak 0 (sıfır) verildiğinde primitif 0 numaralı şekildeki gibi çizilir.

IDirect3DDevice9::SetPaletteEntries: Renk paleti oluşturmak için kullanılır. Oluşturulan her renk paleti bir indexe atanır.
Aşağıdaki resimde farklı renk paletlerinin dokular üzerinde meydana getirdiği etkileri görebilirsiniz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
PALETTEENTRY plt[256];
for (int k=0;k<256;k++)
{
    plt[k].peRed=k;
    plt[k].peGreen=k;
    plt[k].peBlue=k;
    plt[k].peFlags=0x99;
}
g_pd3dDevice->SetPaletteEntries(1,plt);//1 numaralı indexe paletimizi atıyoruz.

IDirect3DDevice9::SetPixelShader: Sürücüye belirtilen pixel shaderi atar.

IDirect3DDevice9::SetPixelShaderConstantB: Pixel shaderde belirtilen BOOL tipli değişkenin değerini atar.

IDirect3DDevice9::SetPixelShaderConstantF: Pixel shaderde belirtilen float tipli değişkenin değerini atar.

IDirect3DDevice9::SetPixelShaderConstantI: Pixel shaderde belirtilen integer tipli değişkenin değerini atar.

IDirect3DDevice9::SetRenderState: Sürücüye belirtilen durum belirtecini atar. Direct3D çok sayıda durum belirteci destekler. Bunlardan bir tanesi aşağıdaki örnekte gösterilmektedir. Geri kalanları sdk dokümanlarından inceleyebilirsiniz. Zamanla diğer durum belirteçlerini de yeri geldikçe örneklerimizde kullanacağız.
Fonksiyonun örnek kullanımı:
//Aşağıdaki durum belirteci ile sürücüye polygon çizimi sırasında polygon arka yüzeylerinin elenmemesini söyledik. Normalde ilk ayar olarak polygonların saat yününün tersi tarafında kalan yüzeyleri elenir. Daha doğrusu rasterize işlemine tabi tutulmayarak çizilmezler. Bu da performans artışı sağlar. Istisnaği durumlar haricinde herzaman polygonların arka yüzeyleri elenir. Bu istisnaği durumlar; cam çizimi, çim çizimi, ağaçların yapraklarının çizimi gibi durumlardır.

C/C++ kodu:
 
lpDevice->SetRenderState(D3DRS_CULLMODE, //Durum belirtecinin tipi
              D3DCULL_NONE);  //Durum belirtecine ait ayar

IDirect3DDevice9::SetRenderTarget: Sürücüye çizimin yapılacağı hedef yüzeyin belirtilmesinde kullanılır. CreateAdditionalSwapChain fonksiyonunun açıklamasında fonksiyonun kullanımı görebilirsiniz.

IDirect3DDevice9::SetSamplerState: Sürücüye atanmış olan dokunun adresleme ve filtreleme ile ilgili özelliklerini değiştirmekte kullanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
//Sıfırıncı katmana ait dokuya hangi filtrelerin uygulanması gerektiğini belirttik. Örneğin linear filtresi dokuların çözünürlüklerinin düşük olduğu durumlarda dokuya yumuşak bir görünüm katar.
lpDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
lpDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
lpDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

IDirect3DDevice9::SetScissorRect: Ekran bazında kırpma işlemi yapmak için kullanılır. Belirtilen dörtgen alan dışında kalan kısımlar kırpılır. Bu işlemde sadece kırpma işlemini açan ve kapatan bloklar arasında yapılan çizimlerde kırpma uygulanır. Bu bloklar dışında kalan çizim işlemlerinde kırpma uygulanmaz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
RECT rc={100,100,800,600};
lpDevice->SetScissorRect(&rc);
lpDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 
 
//Sadece buradaki çizim işlemlerinde kırpma uygulanır
//Çizim işlemleri
 
lpDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
 
//Buradaki çizim işlemlerine kırpma uygulanmaz.
//Çizim işlemleri


IDirect3DDevice9::SetSoftwareVertexProcessing: Sürücüye vertexleri yazılımsal yada donanımsal olarak işleneceğini belirtmek için kullanılır. Donanımsal vertex işleme yazılımsal vertex işlemeye oranla çok daha hızlıdır. Günümüzde yeni ekran kartlarının tümü donanımsal vertex işlemeyi desteklemektedir. Bu fonksiyon sadece sürücü D3DCREATE_MIXED_VERTEXPROCESSING parametresi ile oluşturdu ise çalışır. Yani çalışma zamanı sürücüye vertexleri yazılımsal yada donanımsal olarak işle diyebiliriz. Ancak sürücü önceden D3DCREATE_SOFTWARE_VERTEXPROCESSING yada D3DCREATE_HARDWARE_VERTEXPROCESSING parametrelerinden biri ile oluşturuldu ise çalışma zamanı bu ayar değiştirilemez.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
lpDevice->SetSoftwareVertexProcessing(TRUE);//FALSE

IDirect3DDevice9::SetStreamSource: Sürücüye primitif çizimi sırasında kullanılacak olan vertex bufferin belirtilmesinde kullanılır. Primitif çizimi ile ilgili fonksiyonların örneklerinde fonksiyonun nerelerde kullanıldığını görebilirisiniz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX) );//çizim sırasında kullanılacak vertex buffer belirtiliyor.

IDirect3DDevice9::SetStreamSourceFreq: Örnekleme (instancing) tekniği ile çizilecek primitifden kaç adet çizileceğini sürücüye belirtmek için kullanılır. Örnekleme tekniğini aynı primitifi birden çok kere çizmek istediğimizde kullanabiliriz. Bu teknik aynı primitifi değişik boyutlarda, renklerde ve konumlarda çizebilmemize olanak sağlar. Bu teknik primitif çizimi sırasında kullanılan veri miktarını düşürdüğünden performans artışı sağlar. Partikül sistemlerinde, aynı objenin birden çok çizilmesi gerektiği yerlerde (örneğin bir tapınaktaki sütünların çiziminde) kullanılabilir.

IDirect3DDevice9::SetTexture: Primitif çizimi esnasında belirtilen doku kaynağının sürücüye atanmasında kullanılır. Durumu biraz daha açarsak. Mesela sahneye bir model çizeceğiz. Önce SetTexture komutu ile sürücüye modeli kaplarken şu dokuyu kullan deriz sonra modeli çizeriz. Çizeceğimiz model birden çok doku da kullanabilir. Mesela bir ev modeli. Evin çatısı, duvarları, zemini, kapısı, penceresi vs. değişik dokular kullanır. Bu tür durumlarda da yine aynı mantıkla önce SetTexture komutu ile polygonların kullanacağı doku kaynağı sürücüye bildirilir sonra sahneye belirtilen dokuyu kullanan polygon grubu çizilir. Durumu aşağıdaki gibi örneklersek daha da anlaşılır olacaktır.
Ev modeli

1.adım Çatı dokusunu kullan

   Çatıya ait polygonları çiz

2.adım Duvar doksunu kullan

   Duvarlara ait polygonları çiz

3.adım Kapı dokusunu kullan

   Kapılara ait polygonları çiz

4.adım...

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
...
lpDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
lpDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
lpDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
lpDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
lpDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
lpDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
//Triangle list
for(int k=0;k<dwNumMaterialIndex;k++){
    if((mMaterialIndex[k].nID-1)<dwNumMaterialIndex && lpTexture[mMaterialIndex[k].nID-1]!=NULL){
        lpDevice->SetTexture( 0, lpTexture[mMaterialIndex[k].nID-1]);//belirtilen dokuyu kullan
    } 
    lpDevice->SetStreamSource( 0, lpVertexBuffer, 0, sizeof(POLYGON_VERTEX) );
    lpDevice->SetFVF(POLYGON_VERTEX::FVF);
    lpDevice->DrawPrimitive( D3DPT_TRIANGLELIST, mMaterialIndex[k].Offset, mMaterialIndex[k].nNumPoly );
}
...

IDirect3DDevice9::SetTextureStageState: Sürücüye atanmış olan x katmanındaki dokunun özelliklerini değiştirmek için kullanılır. Kullanabileceğimiz doku katmanı sayısı ekran kartının donanım özelliklerine göre değişiklik gösterebilir. Birden çok doku katmanı ile primitifler üzerinde çoklu doku kullanımını (multi texturing) gerçekleştirebiliriz. Bu fonksiyon katmanların özelliklerini değiştirebilmenin yanında katmanların birbirleri ile bir takım operasyonların gerçekleştirilebilmesine de imkan vermektedir. Operasyon işlemleri iki argüman üzerinde gerçekleştirilir. Iki argüman belirtilen operasyon doğrultusunda işlenir ve bir sonuç meydana gelir. Bu sonuç başka bir katmanın operasyonlarında argüman olarak kullanılabilir. Katmanlar üzerinde gerçekleştirilebilecek birçok operasyon türü bulunmaktadır. Bunlar renk, saydamlık, doku koordinatları, bump (kabartı) operasyonlarıdır. Bu operasyonlar birbirlerinden bağımsız ve ayrı ayrı olarak gerçekleşir. Aşağıdaki resimde çoklu doku kullanımının tasviri bir görüntüsü ve katmanlar arasındaki operasyonların işleyişi gösterilmektedir.
Olayı örneklerle biraz daha pekiştirelim. Fonksiyonun örnek kullanımı:

Örnek 1:
Aşağıdaki örneğimizde operasyon tek katman üzerinde geçerli olacak. Kullanacağımız argümanlar aşağıdaki resimde gösterilmiştir. Birinci argümanda kullanacağımız dokuda beyaz renkli olan yerler aslında şeffaftır.

C/C++ kodu:
 
//Direct3D de indexler hep sıfırdan başlar. 0 indexli katman bizim birinci ve en alttaki katmanımız.
//Sıfır indexli katmana yani birinci katmana bir doku atıyoruz.
g_pd3dDevice->SetTexture( 0, g_pTexture );
g_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,0x99ffffff); //Dışarıdan belirtilen bir alpha değeri. D3DTOP_BLENDFACTORALPHA operasyonu tarafından kullanılmakta.
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,     //Renk operasyonu yapacağız
                                       D3DTOP_MODULATE );  //Iki argüman arasında gerçekleştirilecek operasyon türünü seçiyoruz. Modulate operasyonu iki argüman arasında çarpma işlemini gerçekleşitir. 
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //Birinci argüman olarak dokunun kendisini (dokuya ait renkler) kullanacağımızı belirttik.
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); //Ikinci argüman olarak vertexlerin diffuse rengini kullanacağımızı belirttik. 
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );  //Saydamlık operasyonu yapılmayacak

Aşağıdaki resimde örneğimizin modulate operasyonu sonucu meydana gelen görüntüyü ve diğer operasyonların sonuçlarını görebilirsiniz. Bazı operasyonlar işlem sırasında resmin alpha (saydamlık) bilgisini kullanmaktadır. Bazıları ise SetRenderState ile atanan bilgilere bağlı olarak hesap yaparlar. Vertexlere atanan diffuse reklerinin farklı olması durumlarında da farklı sonuçlar ortaya çıkabilir. Onun için SDK dökümanlarından operasyonların gereklerini hangi parametrelere bağlı olarak işlem gerçekleştirdiklerini inceleyiniz. Bu örneğimizde gereksinimlerinin farklı olmasından dolayı bump (kabartı) operasyonlarına yer verilmemiştir.

Örnek 2:

Bir önceki örneğimiz sadece tek katman üzerinde geçerliydi. Şimdiki örneğimizde bu operasyonları katmanlar arasında gerçekleştireceğiz. Örneğimizde ilk katman üzerinde herhangi bir operasyon gerçekleştirmeyeceğiz. Ikinci katmanda gerçekleştireceğimiz operasyon da "Argüman 2" olarak ilk katmanda meydana gelen sonucu kullanacağız. Ilk katmanda herhangi bir operasyon gerçekleştirmediğimiz için atadığımız doku herhangi bir değişime uğramadan diskten okunduğu hali ile kullanılacaktır.

C/C++ kodu:
 
g_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,0x99ffffff);
g_pd3dDevice->SetTexture(0,g_Texture);
g_pd3dDevice->SetTexture(1,g_Texture2);
//Birinci katmana ait işlemler.
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); //Birinci katmanda herhangi bir operasyon gerçekleştirmek istemiyoruz. Bunun için parametre olarak argüman 1 i verdik.
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );//Birinci argüman olarak dokunun kendisini (dokuya ait renkler) kullanacağımızı belirttik.
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );//Saydamlık operasyonu yapılmayacak
//Ikinci katmana ait işlemler.
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE);//Iki argüman arasında gerçekleştirilecek operasyon türünü seçiyoruz. Modulate operasyonu iki argüman arasında çarpma işlemini gerçekleşitir. 
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );//Birinci argüman olarak dokunun kendisini (dokuya ait renkler) kullanacağımızı belirttik.
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );//Ikinci argüman olarak ilk katmandan meydana gelen sonucu kullanacağımızı belirttik.
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );//Saydamlık operasyonu yapılmayacak

Aşağıdaki resimde örneğimizin modulate operasyonu sonucu meydana gelen görüntüyü ve diğer operasyonların sonuçlarını görebilirsiniz. Önceki örneğimizde operasyonlar hakkında belirttiğim dikkat edilecek unsurlar bu örneğimiz için de geçerlidir.

IDirect3DDevice9::SetTransform: Dönüşüm matrislerinin sürücüye atanmasında kullanılır. Atanma işleminden sonra çizilen primitifler üzerine dönüşüm uygulanır. Matrixleri ilerleyen zamanlarda daha detaylı olarak ele alacağız. Grafik programlamada matrixler çok büyük öneme sahiptir. Bu yüzden matrixlerin bu konulardaki rolünün çok iyi kavranılması gerekmektedir.

Fonksiyonun örnek kullanımı:

Örnek 1:  
C/C++ kodu:
 
//Aşağıdaki örnekte Direct3D de kullanılan kamera sistemi için gerekli dönüşüm matrixlerinin kullanımı gösterilmektedir. Bu örnekte belirtilen özelliklere sahip bir kamera görüşü elde ediyoruz.
D3DXMATRIX matProj, //Projeksiyon matrixi
matView; //Görüş matrixi
//Sol el görüş matrixi oluşturuluyor. Kameranın konumu, bakış noktası ve kameranın yukarı vektörü belirtiliyor. 
D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(225,30,-400),&D3DXVECTOR3(225,30,0),&D3DXVECTOR3(0,1,0));
//Elde edilen matrix sürücüye aktarılıyor.
g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
//Sol el perspektif matrixi oluşturuluyor. Kameranın görüş açısı , görüş alanının en/boy oranı, görüş alanının yakındaki zemini ve uzaktaki zemininin değerleri belirtiliyor.
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4,1.33f,1.0f, 10000.0f);
//Elde edilen matrix sürücüye aktarılıyor.
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

Örnek 2:
C/C++ kodu:
 
//Bir primitifi istediğimiz bir konuma taşıyalım (primitifi istediğimiz bir konumda çizdirelim).
D3DXMATRIX matTrans;//Bir matrix tanımladık.
D3DXMatrixTranslation(&matTrans,0.0f,50.0f,0.0f); //Modelin çizileceği konumu belirtiyoruz. Temelde bu fonksiyon matrixin translate ile ilgili satırlarını belirtilen değerler ile dolduruluyor.
g_pd3dDevice->SetTransform( D3DTS_WORLD,&matTrans); //Matrixi dünya koordinat sisteminde sürücüye atıyoruz. 
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );//Primitifi çiz

Örnek 3:  
C/C++ kodu:
 
//Bir primitifi istediğimiz bir eksende döndürelim.
D3DXMATRIX matRot;//Bir matrix tanımladık.
D3DXMatrixRotationY(&matRot,D3DXToRadian(45));//Primitifi Y ekseninde 45 derece döndürdük.
g_pd3dDevice->SetTransform( D3DTS_WORLD,&matRot); //Matrixi dünya koordinat sisteminde sürücüye atıyoruz. 
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );//Primitifi çiz

Bunlar gibi daha birçok örnek yazılabilir ancak geri kalan örneklere matrixleri daha detaylı incelerken değineceğiz.

IDirect3DDevice9::SetVertexDeclaration: CreateVertexDeclaration fonksiyonu ile oluşturduğumuz vertex deklarasyon yapısını shaderin çizdirilme esnasında sürücüye atanmasında kullanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
...
//Efekti çizdir
lpDevice->SetVertexDeclaration(g_VertDecl);
UINT numPasses = 0;
Effect->Begin( &numPasses, 0 );
for( UINT i = 0; i < numPasses; i++ ){
    Effect->BeginPass( i );
    lpDevice->SetTransform( D3DTS_WORLD, &matDM );
    //mesh->Render();
    Effect->EndPass();
}
Effect->End();
...

IDirect3DDevice9::SetVertexShader: Sürücüye belirtilen vertex shaderi atar.

IDirect3DDevice9::SetVertexShaderConstantB: Vertex shaderde belirtilen BOOL tipli değişkenin değerini atar.

IDirect3DDevice9::SetVertexShaderConstantF: Vertex shaderde belirtilen float tipli değişkenin değerini atar.

IDirect3DDevice9::SetVertexShaderConstantI: Vertex shaderde belirtilen integer tipli değişkenin değerini atar.

IDirect3DDevice9::SetViewport: Direct3D sürücüsüne ait görüş alanı özelliklerini değiştirmekte kullanılır. Görüş alanına ait özellikler aşağıdaki D3DVIEWPORT9 yapısında saklanmaktadır. X,Y görüş alanının sol üst noktasının koordinatlarını, Width ve Height görüş alanının en ve boyunun uzunluğunu, MinZ ve MaxZ de derinlik bilgisinin minimum ve maksimum değer aralığını belirtir. MinZ genelde 0.0 MaxZ ise genelde 1.0 olarak kullanılır. Örneğin MinZ ve MaxZ değerlerinin ikisini de 0.0 yaparsak objelerimiz sahnenin en önünde çizdirilecektir. Her iki değeri de 1.0 yaparsak objelerimiz sahnenin en arkasında çizdirilecektir.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DVIEWPORT9 vPort;
vPort.X = 100;
vPort.Y = 100;
vPort.Width = 320;
vPort.Height = 240;
vPort.MinZ = 0.0f;
vPort.MaxZ = 1.0f;
 
lpDevice->SetViewport(&vPort);

Örneğimiz aşağıdaki sonucu verecektir.


IDirect3DDevice9::ShowCursor: Fare imlecini gösterir yada gizler. Fonksiyonun örnek kullanımı:  

C/C++ kodu:
 
SetCursor( NULL ); //windowsa ait olan imleci gizle
m_pd3dDevice->ShowCursor( TRUE ); //SetCursorProperties fonksiyonu ile özelliklerini verdiğimiz imleci görüntüler. FALSE parametresi verilirse gizler.

IDirect3DDevice9::StretchRect: Bir yüzeyin belirtilen dörtgen bir alanını başka bir yüzeyin belirtilen dörtgen bir alanına sığdırarak kopyalar. Bu işlemde kaynak yüzey üzerinde filtre de uygulanabilir. Fonksiyonu kullanırken dikkat edilecek hususları sdk dokümanlarından inceleyiniz.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DXCreateTextureFromFileEx(g_pd3dDevice, "C:\\birdhouse.jpg",518, 324,0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, 
                D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, NULL, NULL, NULL, &txTmp);
 
D3DXCreateTextureFromFileEx(g_pd3dDevice, "C:\\bird.jpg",215, 243, 0,NULL, D3DFMT_X8R8G8B8,
                D3DPOOL_DEFAULT ,D3DX_DEFAULT,D3DX_DEFAULT, NULL,NULL , NULL, &txTmp2);
 
LPDIRECT3DSURFACE9 lpDSSrc;
LPDIRECT3DSURFACE9 lpDSDest;
RECT rcSrc ={1,1,215,243};//kaynak bölge
RECT rcDest={400,50,500,300};//hedef bölge
txTmp2->GetSurfaceLevel(0, &lpDSSrc); //1. dokunun yüzeyini aldık
txTmp->GetSurfaceLevel(0, &lpDSDest);//2. dokunun yüzeyini aldık
g_pd3dDevice->StretchRect(lpDSSrc,&rcSrc,lpDSDest,&rcDest,D3DTEXF_LINEAR); //Sığdırarak kopyalama işlemine linear filtresini de uyguladık.

Örneğimiz aşağıdaki sonucu verecektir.

IDirect3DDevice9::TestCooperativeLevel: Direct3D sürücüsünün durumu hakkında bilgiler döndürür. D3DERR_DEVICELOST olumsuz bir durum karşısında sürücünün arızaya geçtiğini belirtir. Böyle bir durumla karşılaşıldığında sürücüyü kurtarmak için Render işlemini durdurup belirli aralıklarla TestCooperativeLevel fonksiyonu çağırmak gerekir. Taa ki sürücü durumu bize D3DERR_DEVICENOTRESET dönene kadar. Bu aşamadan sonra sürücüyü IDirect3DDevice9::Reset fonksiyonu ile resetlemek gerekir. Reset fonksiyonu temelde sürücüye ağit özellikleri çalışma zamanı değiştirmeye yarar. Reset fonksiyonu ile çalışma zamanı uygulamamızın çözünürlüğünü değiştirmek için kullanabiliriz. Yada uygulamamızı tamekran-pencere modu, pencere modu-tamekran modlarına geçirmek içinde reset fonksiyonunu kullanabiliriz. Ancak reset işleminin doğru çalışabilmesi için şunu göz önünde tutmak gerekir. Eğer kaynaklar (dokular, vertex bufer,index bufferlar) daha önceden ekran kartı hafızasına yüklendi ise kaynakları serbest bırakıp sürücüyü resetleyip serbest bırakılan kaynakları tekrar yüklemek gerekir. Ancak daha önceden kaynaklar sistem hafızasına yüklendi ise kaynakları serbest bırakıp tekrar yüklemeye gerek kalmadan sürücüyü direk resetleyebilirsiniz. Sürücünün arızaya geçmesi durumunu şöyle açıklayayım. Mesela uygulamamız tam ekran modunda çalışıyorken Alt-tab tuş kombinasyonunu kullandığımızda bu işlem sürücünün arızaya geçmesine neden olacaktır. Bu durumda ekrana hiçbir şey çizilmeyecektir. Sürücüyü daha önce de belirttiğim gibi kurtardığımızda uygulamamız kaldığı yerden çalışmaya devam edecektir. Yani uygulamayı kapatıp tekrar çalıştırmadan en son kaldığımız ana geri dönebiliriz. D3DERR_DRIVERINTERNALERROR ekran kartı sürücülerinden kaynaklanan bir hata ile karşılaşıldığını belirtir. Sürücü kurtarılamaz.

IDirect3DDevice9::UpdateSurface: Bir yüzeyin belirtilen dörtgen bir bölgesini başka bir yüzeyin belirtilen noktasına kopyalamakta kullanılır. Fonksiyonu kullanırken dikkat edilecek bazı hususlar.
-Kaynak ve hedef yüzeylerin formatı aynı olmalıdır.
-Kaynak yüzey sistem hafızasında hedef yüzeyin ise ekran kartı hafızasında olması gerekmektedir. D3DPOOL_SYSTEMMEM parametresi kaynakların sistem hafızasında tutulmasını sağlar. D3DPOOL_DEFAULT parametresi kaynakları hız bakımından yen iyi hafızaya yerleştirir. Bu hafıza bölgesi de genellikle ekran kartı hafızasıdır.
-Yüzey formatları derinlik formatlarından biri olmamalıdır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
D3DXCreateTextureFromFileEx(g_pd3dDevice, "C:\\elma.jpg",NULL, NULL, 0,0, D3DFMT_X8R8G8B8, 
                D3DPOOL_SYSTEMMEM,D3DX_DEFAULT,D3DX_DEFAULT, NULL, NULL, NULL, &txTmp);
 
D3DXCreateTextureFromFileEx(g_pd3dDevice, "C:\\greenbox.jpg",NULL, NULL, 0,0, D3DFMT_X8R8G8B8,
                D3DPOOL_DEFAULT ,D3DX_DEFAULT,D3DX_DEFAULT, NULL, NULL, NULL, &txTmp2);
 
LPDIRECT3DSURFACE9 lpDSSrc;
LPDIRECT3DSURFACE9 lpDSDest;
RECT rcSrc[]={0,0,128,125,  0,0,128,125}; //2 adet dörtgen tanımladık
POINT ptPoint[]= { 0, 0,   150,150};  //2 adet nokta tanımladık
txTmp->GetSurfaceLevel(0, &lpDSSrc);  //1. dokunun yüzeyini aldık
txTmp2->GetSurfaceLevel(0, &lpDSDest);//2. dokunun yüzeyini aldık
g_pd3dDevice->UpdateSurface(lpDSSrc,&rcSrc[0],lpDSDest,&ptPoint[0]);
g_pd3dDevice->UpdateSurface(lpDSSrc,&rcSrc[1],lpDSDest,&ptPoint[1]);

Örneğimiz aşağıdaki sonucu verecektir.


IDirect3DDevice9::UpdateTexture: Sistem hafızasında bulunan bir doku kaynağını ekran kartı hafızasında bulunan başka bir doku kaynağına kopyalamak için kullanılır.Fonksiyonu kullanırken dikkat edilecek bazı hususlar.
-Kaynak ve hedef doku kaynaklarının formatı aynı olmalıdır.
-Kaynak doku sistem hafızasında hedef doku ise ekran kartı hafızasında olması gerekmektedir. D3DPOOL_SYSTEMMEM parametresi kaynakların sistem hafızasında tutulmasını sağlar. D3DPOOL_DEFAULT parametresi kaynakları hız bakımından yen iyi hafızaya yerleştirir. Bu hafıza bölgesi de genellikle ekran kartı hafızasıdır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
//Ekran hafızasında belirtilen boyutlarda ve formatta bir doku kaynağı oluştur.
g_pd3dDevice->CreateTexture(600,400,0,NULL, D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&txTmp,NULL);
//Diskteki bir dokuyu sistem hafızasına yükle.
D3DXCreateTextureFromFileEx(g_pd3dDevice, "C:\\greenbox.jpg",600, 400, 0,NULL, D3DFMT_X8R8G8B8,
                D3DPOOL_SYSTEMMEM ,D3DX_DEFAULT,D3DX_DEFAULT, NULL,NULL , NULL, &txTmp2);
 
//Sistem hafızasındaki doku kaynağını ekran kartı hafızasındaki doku kaynağına kopyala.
g_pd3dDevice->UpdateTexture(txTmp2,txTmp);

IDirect3DDevice9::ValidateDevice: Sürücünün texture-blending (doku harmanlama) operasyonlarını kaç çizim işleminde (pass) yapabileceğini sorgulamakta kullanılır.

Fonksiyonun örnek kullanımı:  
C/C++ kodu:
 
g_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,0x99ffffff);
g_pd3dDevice->SetTexture(0,g_Texture);
g_pd3dDevice->SetTexture(1,g_Texture2);
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
 
DWORD dwNumPass;HRESULT hr;
//Eğer dwNumPass değeri 1 ise tek çizim işleminde işlem gerçekleşir. Daha büyük bir değer ise değer miktarı kadarki çizim işleminde işlem gerçekleşir.
//Bazı ekran kartları kullandığımız opreasyonları desteklemiyor da olabilir. Bu sefer fonksiyon olumsuz bir değer döndürür.
hr=g_pd3dDevice->ValidateDevice(&dwNumPass);

Bilgin Terzi  (3ddreams)

Yorumlar

Bu blogdaki popüler yayınlar

SDL Nedir?

Doxygen Kullanımı

OpenGL'de Line (çizgi) Çizdirme