Temel bir kafes oluşturma ve görüntüleme

3-B Evrensel Windows Platformu (UWP) oyunları genellikle oyundaki nesneleri ve yüzeyleri temsil etmek için çokgenler kullanır. Bu çokgen nesnelerin ve yüzeylerin yapısını oluşturan köşe listeleri, kafes olarak adlandırılır. Burada bir küp nesnesi için temel bir mesh oluşturacak ve bunu işleme ve görüntüleme için gölgelendirici işlem hattına sağlayacağız.

Önemli Burada yer alan örnek kod türleri (DirectX::XMFLOAT3 ve DirectX::XMFLOAT4X4 gibi) ve DirectXMath.h içinde bildirilen satır içi yöntemleri kullanır. Kod parçasını kesip yapıştırıyorsanız, projenizde #include <DirectXMath.h> kodunu ekleyin.

 

Bilmeniz gerekenler

Teknolojileri

Önkoşullar

  • Doğrusal cebir ve 3B koordinat sistemleri hakkında temel bilgi
  • Visual Studio 2015 veya sonraki bir Direct3D şablonu

Yönergeler

Bu adımlar, temel bir mesh küpü oluşturma adımlarını gösterir.

1. Adım: Model için örgü oluşturma

Çoğu oyunda, bir oyun nesnesinin ağı belirli köşe verilerini içeren bir dosyadan yüklenir. Bu köşelerin sırası uygulamaya bağlıdır, ancak genellikle şeritler veya fanlar olarak serileştirilir. Köşe verileri herhangi bir yazılım kaynağından gelebilir veya elle oluşturulabilir. Verileri köşe gölgelendiricisinin etkili bir şekilde işleyebileceği şekilde yorumlamak sizin oyununuza bağlıdır.

Örneğimizde bir küp için basit bir ağ kullanıyoruz. Küp, işlem hattındaki bu aşamadaki herhangi bir nesne ağı gibi kendi koordinat sistemi kullanılarak temsil edilir. Köşe gölgelendiricisi koordinatlarını alır ve sağladığınız dönüşüm matrislerini uygulayarak homojen koordinat sisteminde son 2D görünüm projeksiyonunu döndürür.

Bir küp için ağı tanımlayın. (Veya bir dosyadan yükleyin. Karar sizin!)

SimpleCubeVertex cubeVertices[] =
{
    { DirectX::XMFLOAT3(-0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f) }, // +Y (top face)
    { DirectX::XMFLOAT3( 0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(1.0f, 1.0f, 0.0f) },
    { DirectX::XMFLOAT3( 0.5f, 0.5f,  0.5f), DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f) },
    { DirectX::XMFLOAT3(-0.5f, 0.5f,  0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 1.0f) },

    { DirectX::XMFLOAT3(-0.5f, -0.5f,  0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f) }, // -Y (bottom face)
    { DirectX::XMFLOAT3( 0.5f, -0.5f,  0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 1.0f) },
    { DirectX::XMFLOAT3( 0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f) },
    { DirectX::XMFLOAT3(-0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f) },
};

Küpün koordinat sistemi, küpün merkezini başlangıç noktası olarak belirleyerek, y eksenini yukarıdan aşağıya doğru çalışacak şekilde sol el kuralına göre yerleştirir. Koordinat değerleri, -1 ile 1 arasında 32 bit kayan değerler olarak ifade edilir.

Köşeli parantez içindeki her eşleşmede, ikinci DirectX::XMFLOAT3 değer grubu, tepe noktasıyla ilişkili rengi RGB değeri olarak belirtmektedir. Örneğin, (-0,5, 0,5, -0,5) konumundaki ilk köşe tam yeşil renge sahiptir (G değeri 1,0 olarak ayarlanır ve "R" ve "B" değerleri 0 olarak ayarlanır).

Bu nedenle, her birinin belirli bir renge sahip olduğu 8 köşeniz vardır. Her köşe/renk eşleştirme örneğimizdeki bir köşenin tam verileridir. Bizim köşe arabelleğimizi belirttiğinizde, bu özel düzeni göz önünde bulundurmanız gerekir. Köşe verilerinizi anlayabilmesi için bu giriş düzenini köşe gölgelendiricisine sağlarız.

2. Adım: Giriş düzenini ayarlama

Şimdi, hafızanda köşeler var. Ancak grafik cihazınızın kendi belleği vardır ve buna erişmek için Direct3D kullanırsınız. Köşe verilerinizi işlemek üzere grafik cihazına aktarmak için yolu açmanız gerekir: Grafik cihazının, oyununuzdan aldığında doğru yorumlayabilmesi için köşe verilerinin nasıl yerleştirildiğini bildirmeniz gerekir. Bunu yapmak için id3D11InputLayoutkullanırsınız.

Verteks arabelleği için giriş düzenini bildirin ve ayarlayın.

const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

ComPtr<ID3D11InputLayout> inputLayout;
m_d3dDevice->CreateInputLayout(
                basicVertexLayoutDesc,
                ARRAYSIZE(basicVertexLayoutDesc),
                vertexShaderBytecode->Data,
                vertexShaderBytecode->Length,
                &inputLayout)
);

Bu kodda köşeler için özellikle köşe listesindeki her öğenin hangi verileri içerdiğini belirten bir düzen belirtirsiniz. basicVertexLayoutDesc'de iki veri bileşeni belirtirsiniz: burada,

  • POSITION: Bu, gölgelendiriciye sağlanan konum verileri için bir HLSL semantiğidir. Bu kodda, DirectX::XMFLOAT3, özellikle 3B koordinata (x, y, z) karşılık gelen 3 adet 32 bit kayan nokta değerine sahip bir yapıdır. Homojen "w" koordinatını sağladığınızda float4 de kullanabilirsiniz ve bu durumda DXGI_FORMAT_R32G32B32A32_FLOAT belirtirsiniz. İster DirectX::XMFLOAT3 ister float4 kullanın, oyununuzun belirli gereksinimlerine göre değişir. Ağınız için köşe verilerinin kullandığınız biçime doğru şekilde karşılık olduğundan emin olun!

    Her koordinat değeri, nesnenin koordinat alanında -1 ile 1 arasında kayan nokta değeri olarak ifade edilir. Köşe gölgelendiricisi tamamlandığında, dönüştürülen köşe homojen (perspektif düzeltilmiş) görünüm projeksiyon uzayında olur.

    "Ancak numaralandırma değeri RGB'yi gösterir, XYZ'yi değil!" akıllıca not alırsınız. İyi göz! Hem renk verileri hem de eşgüdüm verileri için genellikle 3 veya 4 bileşen değeri kullanırsınız, bu nedenle neden her ikisi için de aynı biçimi kullanmıyorsunuz? Biçim adı değil HLSL semantiği, gölgelendiricinin verilere nasıl davrandığını gösterir.

  • COLOR: Bu, renk verileri için bir HLSL semantiğidir. POSITIONgibi, 3 32 bit kayan nokta değerlerinden (DirectX::XMFLOAT3) oluşur. Her değer bir renk bileşeni içerir: kırmızı (r), mavi (b) veya yeşil (g), 0 ile 1 arasında kayan sayı olarak ifade edilir.

    COLOR değerleri genellikle gölgelendirici işlem hattının sonunda 4 bileşenli RGBA değeri olarak döndürülür. Bu örnekte, tüm pikseller için gölgelendirici işlem hattında "A" alfa değerini 1,0 (maksimum opaklık) olarak ayarlayacaksınız.

Biçimlerin tam listesi için bkz. DXGI_FORMAT. HLSL semantiklerinin tam listesi için bkz. Semantik.

ID3D11Device::CreateInputLayout çağırın ve Direct3D cihazında giriş düzenini oluşturun. Şimdi, verileri gerçekten tutabilecek bir arabellek oluşturmanız gerekir!

3. Adım: Köşe arabelleklerini doldurma

Köşe arabellekleri, ağ içindeki her üçgen için köşe listesini içerir. Her köşe bu listede benzersiz olmalıdır. Bizim örneğimizde, küp için 8 köşeniz vardır. Köşe gölgelendiricisi grafik cihazında çalışır ve köşe arabelleğinden okur ve verileri önceki adımda belirttiğiniz giriş düzenine göre yorumlar.

Bir sonraki örnekte, Direct3D'ye düğüm verilerinin fiziksel eşlemesi ve grafik cihazında bellekte nasıl işlendiği hakkında bilgi veren bir açıklama ile arabellek için bir alt kaynak sağlarsınız. Her şeyi içerebilen genel bir ID3D11Bufferkullandığınızdan bu gereklidir! D3D11_BUFFER_DESC ve D3D11_SUBRESOURCE_DATA yapıları, Direct3D'nin arabellekteki her köşe öğesinin boyutu ve en büyük köşe listesi boyutu dahil olmak üzere arabelleğin fiziksel bellek düzenini anlamasını sağlamak için sağlanır. Burada arabellek belleğine erişimi ve nasıl işlendiğini de denetleyebilirsiniz, ancak bu, bu kılavuzun kapsamının biraz dışındadır.

Arabelleği yapılandırdıktan sonra, gerçekten oluşturmak için ID3D11Device::CreateBuffer çağırmanız gerekir. Açıkçası, birden fazla nesneniz varsa, her benzersiz model için arabellekler oluşturun.

Köşe arabelleğini bildirin ve oluşturun.

D3D11_BUFFER_DESC vertexBufferDesc = {0};
vertexBufferDesc.ByteWidth = sizeof(SimpleCubeVertex) * ARRAYSIZE(cubeVertices);
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA vertexBufferData;
vertexBufferData.pSysMem = cubeVertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;

ComPtr<ID3D11Buffer> vertexBuffer;
m_d3dDevice->CreateBuffer(
                &vertexBufferDesc,
                &vertexBufferData,
                &vertexBuffer);

Köşeler yüklendi. Peki bu köşeleri işlemenin sırası nedir? Bu işlem, köşelere dizinlerin listesini sağladığınızda işlenir. Bu dizinlerin sırası, köşe gölgelendiricisinin bunları işlediği sıradır.

4. Adım: Dizin arabelleklerini doldurma

Şimdi, köşelerin her biri için dizinlerin listesini sağlarsınız. Bu dizinler, 0 ile başlayarak köşe arabelleğindeki köşenin konumuna karşılık gelir. Bunu görselleştirmenize yardımcı olmak için ağınızdaki her benzersiz köşeye kimlik gibi benzersiz bir sayı atandığını göz önünde bulundurun. Bu ID, köşe arabelleğindeki köşenin tamsayıyla ifade edilen konumudur.

Sekiz numaralı köşeli bir küp

Örnek küpümüzde, 8 köşe vardır ve bunlar 6 dörtgen oluşturur. Sekiz köşemizi kullanan toplam 12 üçgen elde etmek için dörtgenleri üçgenlere bölersiniz. Üçgen başına 3 köşe ile, dizin arabelleğimizde toplam 36 giriş vardır. Örneğimizde, bu dizin deseni üçgen liste olarak bilinir ve ilkel topolojiyi ayarladığınızda bunu D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST olarak Direct3D olarak belirtirsiniz.

Muhtemelen bu, üçgenler noktaları ve kenarları paylaştığında birçok tekrar meydana geldiği için indisleri listelemenin en verimsiz yoludur. Örneğin, üçgen eşkenar şeklindeki bir tarafı paylaştığında, dört köşe için 6 dizin listelersiniz, örneğin:

Rhombus oluştururken dizinlerin sırasını

  • Üçgen 1: [0, 1, 2]
  • Üçgen 2: [0, 2, 3]

Şerit veya fan topolojisinde köşeleri, dolaşma sırasında çok fazla yedekli tarafı ortadan kaldıracak şekilde sıralarsınız (örneğin, görüntüde dizin 0'dan dizin 2'ye olan taraf).) Büyük ağlar için bu, köşe gölgelendiricisinin çalışma sayısını önemli ölçüde azaltır ve performansı önemli ölçüde artırır. Ancak, bunu basit tutacağız ve üçgen listesine bağlı kalacağız.

Köşe arabelleği için indisleri basit bir üçgen liste topolojisi olarak tanımlayın.

unsigned short cubeIndices[] =
{   0, 1, 2,
    0, 2, 3,

    4, 5, 6,
    4, 6, 7,

    3, 2, 5,
    3, 5, 4,

    2, 1, 6,
    2, 6, 5,

    1, 7, 6,
    1, 0, 7,

    0, 3, 4,
    0, 4, 7 };

Tamponda otuz altı indeks elemanı olması, yalnızca 8 köşeniz varken oldukça yedeklidir! Bazı gereksizlikleri ortadan kaldırmayı ve bir şerit veya fan gibi farklı bir köşe listesi türü kullanmayı seçerseniz, D3D11_PRIMITIVE_TOPOLOGY değerini id3D11DeviceContext::IASetPrimitiveTopology yönteminin parametresi olarak sağlarken bu türü belirtmeniz gerekir.

Farklı dizin listesi teknikleri hakkında daha fazla bilgi için bkz. Temel Topolojiler.

5. Adım: Dönüştürme matrisleriniz için sabit bir arabellek oluşturma

Köşeleri işlemeye başlayabilmeniz için önce, çalıştırıldığında her köşeye uygulanacak (çarpılmış) dönüştürme matrislerini sağlamanız gerekir. Çoğu 3B oyun için bunlardan üç tanesi vardır:

  • Nesne (model) koordinat sisteminden genel dünya koordinat sistemine dönüşen 4x4 matrisi.
  • Dünya koordinat sisteminden kamera (görüntüleme) koordinat sistemine dönüşen 4x4 matris.
  • Kamera koordinat sisteminden 2D görünüm projeksiyon koordinat sistemine dönüşüm sağlayan 4x4 matris.

Bu matrisler sabit arabellek içindegölgelendiriciye aktarılır. Sabit tampon, gölgelendirici işlem hattının bir sonraki geçişi sırasında sabit kalan ve gölgelendiriciler tarafından HLSL kodunuz vasıtasıyla doğrudan erişilebilen bir bellek bölgesidir. Her sabit arabelleği iki defa tanımlarsınız: önce oyununuzun C++ kodunda ve ardından en az bir kez C benzeri HLSL söz diziminde, gölgelendirici kodunuz için. İki bildirimin türler ve veri hizalama açısından doğrudan karşılık gelen olması gerekir. HLSL bildirimi, C++'da bildirilen verileri yorumlamak için kullanıldığında ve türler eşleşmediğinde veya verilerin hizalaması hatalı olduğunda, fark edilmesi zor hatalar üretmek kolaydır!

Sabit arabellekler HLSL tarafından değiştirilmez. Oyununuz belirli verileri güncelleştirdiğinde bunları değiştirebilirsiniz. Genellikle, oyun geliştirmeleri 4 sabit arabellek sınıfı oluşturur: çerçeve başına güncelleştirmeler için bir tür; model/nesne başına güncelleştirmeler için bir tür; oyun durumu yenilemesi başına güncelleştirmeler için bir tür; ve oyunun ömrü boyunca hiçbir zaman değişmemiş veriler için bir tür.

Bu örnekte hiçbir zaman değişmemiş bir verimiz vardır: Üç matris için DirectX::XMFLOAT4X4 verileri.

Not Burada sunulan örnek kodda sütun ana matrisleri kullanılmaktadır. HLSL'de row_major anahtar kelimesini kullanarak ve kaynak matris verilerinizin de satır-major olduğundan emin olarak satır-major matrisleri kullanabilirsiniz. DirectXMath, satır ana matrislerini kullanır ve row_major anahtar sözcüğüyle tanımlanan HLSL matrisleriyle doğrudan kullanılabilir.

 

Her köşeyi dönüştürmek için kullandığınız üç matris için sabit bir arabellek bildirin ve oluşturun.

struct ConstantBuffer
{
    DirectX::XMFLOAT4X4 model;
    DirectX::XMFLOAT4X4 view;
    DirectX::XMFLOAT4X4 projection;
};
ComPtr<ID3D11Buffer> m_constantBuffer;
ConstantBuffer m_constantBufferData;

// ...

// Create a constant buffer for passing model, view, and projection matrices
// to the vertex shader.  This allows us to rotate the cube and apply
// a perspective projection to it.

D3D11_BUFFER_DESC constantBufferDesc = {0};
constantBufferDesc.ByteWidth = sizeof(m_constantBufferData);
constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = 0;
constantBufferDesc.MiscFlags = 0;
constantBufferDesc.StructureByteStride = 0;
m_d3dDevice->CreateBuffer(
                &constantBufferDesc,
                nullptr,
                &m_constantBuffer
             );

m_constantBufferData.model = DirectX::XMFLOAT4X4( // Identity matrix, since you are not animating the object
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f);

);
// Specify the view (camera) transform corresponding to a camera position of
// X = 0, Y = 1, Z = 2.  

m_constantBufferData.view = DirectX::XMFLOAT4X4(
            -1.00000000f, 0.00000000f,  0.00000000f,  0.00000000f,
             0.00000000f, 0.89442718f,  0.44721359f,  0.00000000f,
             0.00000000f, 0.44721359f, -0.89442718f, -2.23606800f,
             0.00000000f, 0.00000000f,  0.00000000f,  1.00000000f);

Not Genellikle cihaza özgü kaynakları ayarlarken projeksiyon matrisini bildirirsiniz, çünkü çarpmanın sonuçları geçerli 2-B görünüm penceresi boyutu parametreleriyle (genellikle ekranın piksel yüksekliğine ve genişliğine karşılık gelir) eşleşmelidir. Bunlar değişirse, x ve y koordinat değerlerini buna göre ölçeklendirmeniz gerekir.

 

// Finally, update the constant buffer perspective projection parameters
// to account for the size of the application window.  In this sample,
// the parameters are fixed to a 70-degree field of view, with a depth
// range of 0.01 to 100.  

float xScale = 1.42814801f;
float yScale = 1.42814801f;
if (backBufferDesc.Width > backBufferDesc.Height)
{
    xScale = yScale *
                static_cast<float>(backBufferDesc.Height) /
                static_cast<float>(backBufferDesc.Width);
}
else
{
    yScale = xScale *
                static_cast<float>(backBufferDesc.Width) /
                static_cast<float>(backBufferDesc.Height);
}
m_constantBufferData.projection = DirectX::XMFLOAT4X4(
            xScale, 0.0f,    0.0f,  0.0f,
            0.0f,   yScale,  0.0f,  0.0f,
            0.0f,   0.0f,   -1.0f, -0.01f,
            0.0f,   0.0f,   -1.0f,  0.0f
            );

Buradayken,ID3D11DeviceContextüzerinde köşe ve dizin arabelleklerinin yanı sıra kullandığınız topolojiyi ayarlayın.

// Set the vertex and index buffers, and specify the way they define geometry.
UINT stride = sizeof(SimpleCubeVertex);
UINT offset = 0;
m_d3dDeviceContext->IASetVertexBuffers(
                0,
                1,
                vertexBuffer.GetAddressOf(),
                &stride,
                &offset);

m_d3dDeviceContext->IASetIndexBuffer(
                indexBuffer.Get(),
                DXGI_FORMAT_R16_UINT,
                0);

 m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

Tamam! Giriş montajı tamamlandı. İşleme için her şey hazır. Köşe gölgelendiricisini çalıştıralım.

6. Adım: Ağı köşe gölgelendiricisi ile işleme

Ağınızı tanımlayan köşeleri içeren bir köşe arabelleğiniz ve köşelerin işlenme sırasını tanımlayan bir dizin arabelleğiniz olduğuna göre, bunları köşe gölgelendiricisine gönderirsiniz. Derlenmiş üst düzey gölgelendirici dili olarak ifade edilen köşe gölgelendiricisi kodu, köşe arabelleğindeki her köşe için bir kez çalıştırılır ve köşe başına dönüşümlerinizi gerçekleştirmenizi sağlar. Nihai sonuç genellikle 2-B projeksiyondur.

(Köşe gölgelendiricinizi yüklediniz mi? Aksi takdirde, DirectX oyununuzda kaynakları yüklemeyi nasıl yapacağınızı gözden geçirmek için vekısımlarını inceleyin.)

Burada köşe gölgelendiricisini oluşturacaksınız...

// Set the vertex and pixel shader stage state.
m_d3dDeviceContext->VSSetShader(
                vertexShader.Get(),
                nullptr,
                0);

... ve sabit arabellekleri ayarlayın.

m_d3dDeviceContext->VSSetConstantBuffers(
                0,
                1,
                m_constantBuffer.GetAddressOf());

Nesne koordinatlarından dünya koordinatlarına ve ardından 2-B görünüm projeksiyon koordinat sistemine dönüştürmeyi işleyen köşe gölgelendiricisi kodu aşağıdadır. Ayrıca, her şeyi güzel hale getirmek için köşe başına basit bir aydınlatma uygularsınız. Bu, köşe gölgelendiricinizin HLSL dosyasına gider (SimplerVertexShader.hlsl, bu örnekte).

cbuffer simpleConstantBuffer : register( b0 )
{
    matrix model;
    matrix view;
    matrix projection;
};

struct VertexShaderInput
{
    DirectX::XMFLOAT3 pos : POSITION;
    DirectX::XMFLOAT3 color : COLOR;
};

struct PixelShaderInput
{
    float4 pos : SV_POSITION;
    float4 color : COLOR;
};

PixelShaderInput SimpleVertexShader(VertexShaderInput input)
{
    PixelShaderInput vertexShaderOutput;
    float4 pos = float4(input.pos, 1.0f);

    // Transform the vertex position into projection space.
    pos = mul(pos, model);
    pos = mul(pos, view);
    pos = mul(pos, projection);
    vertexShaderOutput.pos = pos;

    // Pass the vertex color through to the pixel shader.
    vertexShaderOutput.color = float4(input.color, 1.0f);

    return vertexShaderOutput;
}

Yukarıdaki cbuffer'i görüyor musun? Bu, daha önce C++ kodumuzda bildirdiğimiz sabit arabelleğe ait HLSL analogu. Ve VertexShaderInputstruct? Bu, giriş düzeninize ve köşe veri bildiriminize benzer! C++ kodunuzdaki sabit arabellek ve köşe veri bildirimlerinin HLSL kodunuzdaki bildirimlerle eşleşmesi ve işaretler, türler ve veri hizalaması içermesi önemlidir.

PixelShaderInput köşe gölgelendiricisinin ana işlevi tarafından döndürülen verilerin düzenini belirtir. Bir köşeyi işlemeyi bitirdiğinizde, 2D projeksiyon uzayı içinde bir köşe konumu ve köşe başına aydınlatmada kullanılan bir renk döndüreceksiniz. Grafik kartı, işlem hattının bir sonraki aşamasında piksel gölgelendiricisi çalıştırıldığında renklendirilmiş olması gereken "parçaları" (olası pikseller) hesaplamak için gölgelendiricinin veri çıkışını kullanır.

7. Adım: Ağı piksel gölgelendiricisi üzerinden geçirme

Genellikle grafik işlem hattında bu aşamada nesnelerinizin görünür yansıtılan yüzeylerinde piksel başına işlemler gerçekleştirirsiniz. (İnsanlar dokuları sever.) Ancak, örnek amacıyla bu aşamadan geçirmeniz yeterlidir.

İlk olarak piksel gölgelendiricisinin bir örneğini oluşturalım. Piksel gölgelendiricisi, sahnenizin 2-B projeksiyonundaki her piksel için çalışır ve bu piksele bir renk atar. Bu durumda, köşe gölgelendiricisi tarafından döndürülen pikselin rengini doğrudan geçiririz.

Piksel gölgelendiricisini ayarlayın.

m_d3dDeviceContext->PSSetShader( pixelShader.Get(), nullptr, 0 );

HLSL'de bir geçiş piksel gölgelendiricisi tanımlayın.

struct PixelShaderInput
{
    float4 pos : SV_POSITION;
};

float4 SimplePixelShader(PixelShaderInput input) : SV_TARGET
{
    // Draw the entire triangle yellow.
    return float4(1.0f, 1.0f, 0.0f, 1.0f);
}

Bu kodu, köşe gölgelendiricisi HLSL'den (SimplePixelShader.hlsl gibi) ayrı bir HLSL dosyasına yerleştirin. Bu kod, görünüm penceresinizdeki her görünür piksel (çizdiğiniz ekranın bir bölümünün bellek içi gösterimi) için bir kez çalıştırılır ve bu durum ekranın tamamına eşlenir. Artık grafik işlem hattınız tamamen tanımlanmıştır!

8. Adım: Ağı rasterleştirme ve görüntüleme

şimdi işlem hattını çalıştıralım. Bu kolay: ID3D11DeviceContext::DrawIndexedçağrısını yapın.

Küpü çizin!

// Draw the cube.
m_d3dDeviceContext->DrawIndexed( ARRAYSIZE(cubeIndices), 0, 0 );
            

Grafik kartının içinde, her bir köşe noktası, dizin arabelleğinizde belirtilen sıraya göre işlenir. Kodunuz köşe gölgelendiricisini yürütüp 2-B parçalar tanımlandıktan sonra piksel gölgelendiricisi çağrılır ve üçgenler renklendirilir.

Şimdi küpü ekrana koy.

Bu çerçeve arabelleği ekrana sunun.

// Present the rendered image to the window.  Because the maximum frame latency is set to 1,
// the render loop is generally  throttled to the screen refresh rate, typically around
// 60 Hz, by sleeping the app on Present until the screen is refreshed.

m_swapChain->Present(1, 0);

Ve işiniz bitti! Modellerle dolu bir sahne için birden çok köşe ve dizin arabelleği kullanın; hatta farklı model türleri için farklı gölgelendiricileriniz bile olabilir. Her modelin kendi koordinat sistemine sahip olduğunu ve bunları sabit arabellekte tanımladığınız matrisleri kullanarak paylaşılan dünya koordinat sistemine dönüştürmeniz gerektiğini unutmayın.

Açıklamalar

Bu konu, kendi oluşturduğunuz basit geometriyi oluşturmayı ve görüntülemeyi kapsar. Bir dosyadan daha karmaşık geometri yükleme ve bunu örneğe özgü köşe arabelleği nesnesi (.vbo) biçimine dönüştürme hakkında daha fazla bilgi için bkz. DirectX oyununuzda kaynakları yükleme.