Bagikan melalui


Pemrograman Satu atau Beberapa Aliran (Direct3D 9)

Bagian ini menjelaskan shader yang dapat digunakan untuk model aliran yang dapat diprogram.

Menggunakan Stream

DirectX 8 memperkenalkan gagasan aliran untuk mengikat data ke register input untuk digunakan oleh shader. Aliran adalah array data komponen yang seragam, di mana setiap komponen terdiri dari satu atau beberapa elemen yang mewakili satu entitas seperti posisi, normal, warna, dan sebagainya. Aliran memungkinkan chip grafis untuk melakukan akses memori langsung dari beberapa buffer vertex secara paralel dan juga menyediakan pemetaan yang lebih alami dari data aplikasi. Mereka juga memungkinkan multitekstur sepele versus multipass. Anggap saja seperti ini:

  • Vertex terdiri dari aliran n.
  • Aliran terdiri dari elemen m.
  • Elemen adalah [posisi, warna, normal, koordinat tekstur].

Metode IDirect3DDevice9::SetStreamSource mengikat buffer vertex ke aliran data perangkat, membuat hubungan antara data vertex dan salah satu dari beberapa port aliran data yang memberi umpan fungsi pemrosesan primitif. Referensi aktual ke data aliran tidak terjadi sampai metode menggambar, seperti IDirect3DDevice9::D rawPrimitive, dipanggil.

Pemetaan elemen vertex input ke daftar input vertex untuk shader vertex yang dapat diprogram didefinisikan dalam deklarasi shader, tetapi elemen vertex input tidak memiliki semantik tertentu tentang penggunaannya. Interpretasi elemen vertex input diprogram menggunakan instruksi shader. Fungsi shader vertex didefinisikan oleh array instruksi yang diterapkan ke setiap vertex. Register output vertex ditulis secara eksplisit, menggunakan instruksi dalam fungsi shader.

Namun, untuk diskusi ini, kurang peduli dengan pemetaan semantik elemen untuk mendaftar dan lebih peduli dengan alasan untuk menggunakan aliran dan masalah apa yang diselesaikan dengan menggunakan aliran. Manfaat utama aliran adalah mereka menghapus biaya data puncak yang sebelumnya terkait dengan multitekstur. Sebelum melakukan streaming, pengguna harus menduplikasi himpunan data vertex untuk menangani kasus tunggal dan multitekstur tanpa elemen data yang tidak digunakan, atau membawa elemen data yang tidak akan digunakan kecuali dalam kasus multitekstur.

Berikut adalah contoh penggunaan dua set data puncak, satu untuk tekstur tunggal dan satu untuk multitekstur.

struct CUSTOMVERTEX_TEX1
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_1, tv_1;   // Texture coordinates for a single texture
};
 
struct CUSTOMVERTEX_TEX2
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_2, tv_2;   // Texture coordinates for multitexturing
};

Alternatifnya adalah memiliki elemen vertex tunggal yang berisi kedua set koordinat tekstur.

struct CUSTOMVERTEX_TEX2
{
    FLOAT x, y, z;      // The untransformed position for the vertex
    DWORD diffColor;    // The vertex diffuse color    
    DWORD specColor;    // The vertex specular color
    float tu_1, tv_1;   // Texture coordinates for a single texture
    float tu_2, tv_2;   // Texture coordinates for multitexturing
};

Dengan data puncak ini, hanya satu salinan posisi dan data warna yang dibawa dalam memori, dengan mengorbankan kedua set koordinat tekstur untuk penyajian bahkan dalam kasus tekstur tunggal.

Sekarang setelah tradeoff jelas, aliran memberikan perbaikan elegan untuk dilema ini. Berikut adalah sekumpulan definisi puncak untuk mendukung tiga aliran: satu dengan posisi dan warna, satu dengan satu set koordinat tekstur pertama, dan satu dengan serangkaian koordinat tekstur kedua.

// Multistream vertex
// Stream 0, pos, diffuse, specular
struct POSCOLORVERTEX
{
    FLOAT x, y, z;
    DWORD diffColor, specColor;
};
#define D3DFVF_POSCOLORVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR)
// Stream 1, tex coord 0
struct TEXC0VERTEX
{
    FLOAT tu1, tv1;
};
#define D3DFVF_TEXC0VERTEX (D3DFVF_TEX1)

// Stream 2, tex coord 1
struct TEXC1VERTEX
{
    FLOAT tu2, tv2;
};
#define D3DFVF_TEXC1VERTEX (D3DFVF_TEX0)

Deklarasi puncak adalah sebagai berikut:

// Multitexture - multistream

D3DVERTEXELEMENT9 dwDecl3[] = 
{
    {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_POSITION, 0},
    {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 0},
    {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 1},
    {1,  0, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 0},
    {2,  0, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 1},
    D3DDECL_END()
};

Sekarang buat objek deklarasi puncak dan atur seperti yang ditunjukkan:

LPDIRECT3DVERTEXDECLARATION9 m_pVertexDeclaration;
g_d3dDevice->CreateVertexDeclaration(dwDecl3, &m_pVertexDeclaration);

m_pd3dDevice->SetVertexDeclaration(m_pVertexDeclaration);

Contoh Kombinasi

Satu Warna Difus Aliran

Deklarasi puncak dan pengaturan aliran untuk penyajian warna difus akan terlihat seperti ini:

D3DVERTEXELEMENT9 dwDecl3[] = 
{
    {0,  0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_POSITION, 0},
    {0, 12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 0 ,
    {0, 16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 1},
    D3DDECL_END()
};
   m_pd3dDevice->SetStreamSource(0, m_pVBVertexShader0, 0,
                                      sizeof(CUSTOMVERTEX));
   m_pd3dDevice->SetStreamSource(1, NULL, 0, 0);
   m_pd3dDevice->SetStreamSource(2, NULL, 0, 0);

Dua Aliran dengan Warna dan Tekstur

Deklarasi puncak dan pengaturan streaming untuk penyajian tekstur tunggal akan terlihat seperti ini:

D3DVERTEXELEMENT9 dwDecl3[] = 
{
    {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_POSITION, 0},
    {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 0},
    {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 1},

    {1,  0, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 0},

    D3DDECL_END()
};
   m_pd3dDevice->SetStreamSource(0, m_pVBPosColor, 0,
                                           sizeof(POSCOLORVERTEX));
   m_pd3dDevice->SetStreamSource(1, m_pVBTexC0, 0,
                                           sizeof(TEXC0VERTEX));
   m_pd3dDevice->SetStreamSource(2, NULL, 0, 0);

Dua Aliran dengan Warna dan dua Tekstur

Deklarasi puncak dan pengaturan streaming untuk penyajian multi-tekstur dua tekstur akan terlihat seperti ini:

D3DVERTEXELEMENT9 dwDecl3[] = 
{
    {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_POSITION, 0},
    {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 0},
    {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_COLOR, 1},

    {1,  0, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 0},

    {2,  0, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, 
                                      D3DDECLUSAGE_TEXCOORD, 1},
    
    D3DDECL_END()
};
 
m_pd3dDevice->SetStreamSource(0, m_pVBPosColor, 0, 
                                          sizeof(POSCOLORVERTEX));
m_pd3dDevice->SetStreamSource(1, m_pVBTexC0, 0, 
                                          sizeof(TEXC0VERTEX));
m_pd3dDevice->SetStreamSource(2, m_pVBTexC1, 0, 
                                          sizeof(TEXC1VERTEX));

Dalam setiap kasus, IDirect3DDevice9::D rawPrimitive invocation berikut cukup.

       m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, NUM_TRIS);

Ini menunjukkan fleksibilitas aliran dalam memecahkan masalah duplikasi data/transmisi data redundan di seluruh bus (yaitu, membuang-buang bandwidth).

Deklarasi Puncak