將材質套用至基本材質
這裡,我們載入原始的紋理資料,並將資料套用至三維基本資料,方法是使用我們在使用深度與效果基本資料中建立的立方體。 此外,還介紹一個簡單的點積發光模型,其中立方體表面會根據它們相對於光源的距離和角度而變亮或變暗。
目標:將材質套用至基本材質。
必要條件
若要充分利用此主題,您需要熟悉 C++。 您還需要基本的圖形程式設計經驗。 而且,理想情況下,您應該已經跟隨 Quickstart 一起進行:設定 DirectX 資源和顯示影像、建立著色器和繪製基元,以及使用基元的深度和效果。
完成時間:20 分鐘。
指示
1. 定義紋理立方結構的變數
首先,我們需要定義紋理立方體的 BasicVertex 和 ConstantBuffer 結構。 這些結構會指定立方結構的頂點位置、方向和材質,以及立方結構的檢視方式。 否則,我們將以類似於上一教程的方式宣告變數,即使用對基元的深度和效果。
struct BasicVertex
{
DirectX::XMFLOAT3 pos; // Position
DirectX::XMFLOAT3 norm; // Surface normal vector
DirectX::XMFLOAT2 tex; // Texture coordinate
};
struct ConstantBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
// This class defines the application as a whole.
ref class Direct3DTutorialFrameworkView : public IFrameworkView
{
private:
Platform::Agile<CoreWindow> m_window;
ComPtr<IDXGISwapChain1> m_swapChain;
ComPtr<ID3D11Device1> m_d3dDevice;
ComPtr<ID3D11DeviceContext1> m_d3dDeviceContext;
ComPtr<ID3D11RenderTargetView> m_renderTargetView;
ComPtr<ID3D11DepthStencilView> m_depthStencilView;
ComPtr<ID3D11Buffer> m_constantBuffer;
ConstantBuffer m_constantBufferData;
2. 建立具有曲面和紋理元素的頂點與畫素著色器
在這裡,我們建立的頂點與畫素著色器比先前的教學課程 Using depth and effects on primitives。 此應用程式的頂點著色器會將每個頂點位置轉換為投影空間,並將頂點紋理座標傳遞至畫素著色器。
應用程式的 D3D11_INPUT_ELEMENT_DESC 結構陣列描述頂點著色器程式碼的版面配置,它具有三個版面配置元素:一個元素定義頂點位置,另一個元素定義曲面法向量 (曲面通常面向的方向),第三個元素定義紋理座標。
我們建立頂點、索引和常數緩衝區,定義在軌道上的紋理立方體。
定義繞軌道紋理的立方結構
- 首先,我們定義立方體。 每個頂點都會被指定位置、曲面法向量和紋理座標。 我們使用多個頂點來為每個角點定義不同的法向量和紋理座標。
- 接下來,我們使用 cube 定義描述頂點和索引緩衝區 (D3D11_BUFFER_DESC 和 D3D11_SUBRESOURCE_DATA)。 我們針對每個緩衝區呼叫 ID3D11Device::CreateBuffer 一次。
- 接下來,我們會建立常數緩衝區 (D3D11_BUFFER_DESC),以將模型、檢視和投影矩陣傳遞至頂點著色器。 我們稍後可以使用常數緩衝區來旋轉 Cube,並將透視投影套用至 Cube。 我們呼叫 ID3D11Device::CreateBuffer,以建立常數緩衝區。
- 最後,我們指定一個對應於 X=0、Y=1、Z=2 的相機位置的檢視變換。
auto loadVSTask = DX::ReadDataAsync(L"SimpleVertexShader.cso");
auto loadPSTask = DX::ReadDataAsync(L"SimplePixelShader.cso");
auto createVSTask = loadVSTask.then([this](const std::vector<byte>& vertexShaderBytecode)
{
ComPtr<ID3D11VertexShader> vertexShader;
DX::ThrowIfFailed(
m_d3dDevice->CreateVertexShader(
vertexShaderBytecode->Data,
vertexShaderBytecode->Length,
nullptr,
&vertexShader
)
);
// Create an input layout that matches the layout defined in the vertex shader code.
// These correspond to the elements of the BasicVertex struct defined above.
const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
ComPtr<ID3D11InputLayout> inputLayout;
DX::ThrowIfFailed(
m_d3dDevice->CreateInputLayout(
basicVertexLayoutDesc,
ARRAYSIZE(basicVertexLayoutDesc),
vertexShaderBytecode->Data,
vertexShaderBytecode->Length,
&inputLayout
)
);
});
// Load the raw pixel shader bytecode from disk and create a pixel shader with it.
auto createPSTask = loadPSTask.then([this](const std::vector<byte>& pixelShaderBytecode)
{
ComPtr<ID3D11PixelShader> pixelShader;
DX::ThrowIfFailed(
m_d3dDevice->CreatePixelShader(
pixelShaderBytecode->Data,
pixelShaderBytecode->Length,
nullptr,
&pixelShader
)
);
});
// Create vertex and index buffers that define a simple unit cube.
auto createCubeTask = (createPSTask && createVSTask).then([this]()
{
// In the array below, which will be used to initialize the cube vertex buffers,
// multiple vertices are used for each corner to allow different normal vectors and
// texture coordinates to be defined for each face.
BasicVertex cubeVertices[] =
{
{ DirectX::XMFLOAT3(-0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // +Y (top face)
{ DirectX::XMFLOAT3(0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // -Y (bottom face)
{ DirectX::XMFLOAT3(0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // +X (right face)
{ DirectX::XMFLOAT3(0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // -X (left face)
{ DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // +Z (front face)
{ DirectX::XMFLOAT3(0.5f, 0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, 0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
{ DirectX::XMFLOAT3(0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) }, // -Z (back face)
{ DirectX::XMFLOAT3(-0.5f, 0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
{ DirectX::XMFLOAT3(-0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
{ DirectX::XMFLOAT3(0.5f, -0.5f, -0.5f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
};
unsigned short cubeIndices[] =
{
0, 1, 2,
0, 2, 3,
4, 5, 6,
4, 6, 7,
8, 9, 10,
8, 10, 11,
12, 13, 14,
12, 14, 15,
16, 17, 18,
16, 18, 19,
20, 21, 22,
20, 22, 23
};
D3D11_BUFFER_DESC vertexBufferDesc = { 0 };
vertexBufferDesc.ByteWidth = sizeof(BasicVertex) * 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;
DX::ThrowIfFailed(
m_d3dDevice->CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&vertexBuffer
)
);
D3D11_BUFFER_DESC indexBufferDesc;
indexBufferDesc.ByteWidth = sizeof(unsigned short) * ARRAYSIZE(cubeIndices);
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA indexBufferData;
indexBufferData.pSysMem = cubeIndices;
indexBufferData.SysMemPitch = 0;
indexBufferData.SysMemSlicePitch = 0;
ComPtr<ID3D11Buffer> indexBuffer;
DX::ThrowIfFailed(
m_d3dDevice->CreateBuffer(
&indexBufferDesc,
&indexBufferData,
&indexBuffer
)
);
// Create a constant buffer for passing model, view, and projection matrices
// to the vertex shader. This will allow 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;
DX::ThrowIfFailed(
m_d3dDevice->CreateBuffer(
&constantBufferDesc,
nullptr,
&m_constantBuffer
)
);
// Specify the view transform corresponding to a camera position of
// X = 0, Y = 1, Z = 2. For a generalized camera class, see Lesson 5.
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
);
});
3. 建立紋理與取樣器
在這裡,我們將紋理資料套用至立方結構,而不是像上一個教學課程 Using depth and effects on primitives 一樣,套用顏色。
我們使用原始紋理資料來建立紋理。
若要建立紋理與取樣器,請執行下列步驟:
- 首先,從磁碟上的 texturedata.bin 檔案中讀取原始紋理資料。
- 接下來,我們構造一個 D3D11_SUBRESOURCE_DATA 結構來引用該原始紋理資料。
- 然後,我們填充一個 D3D11_TEXTURE2D_DESC,來描述這個紋理。 然後我們將 D3D11_SUBRESOURCE_DATA 和 D3D11_TEXTURE2D_DESC 結構傳遞給 ID3D11Device::CreateTexture2D,以建立紋理。
- 接下來,我們建立紋理的著色器資源檢視,以便著色器能夠使用紋理。 若要建立著色器資源檢視,我們填入 D3D11_SHADER_RESOURCE_VIEW_DESC,以描述著色器資源檢視,並將著色器資源檢視描述和紋理傳遞至 ID3D11Device::CreateShaderResourceView。 一般而言,會將檢視描述與材質描述相配。
- 接下來,我們建立紋理的取樣器狀態。 此取樣器狀態使用相關紋理資料來定義如何確定特定紋理座標的顏色。 我們填充一個 D3D11_SAMPLER_DESC (D3D11_SAMPLER_DESC) 結構來描述取樣器狀態。 然後,我們將 D3D11_SAMPLER_DESC 結構傳遞給 ID3D11Device::CreateSamplerState ,以建立取樣器狀態。
- 最後,我們宣告一個 度變數,我們將用來將立方體旋轉到每一幀,以將其做成動畫。
// Load the raw texture data from disk and construct a subresource description that references it.
auto loadTDTask = DX::ReadDataAsync(L"texturedata.bin");
auto constructSubresourceTask = loadTDTask.then([this](const std::vector<byte>& textureData)
{
D3D11_SUBRESOURCE_DATA textureSubresourceData = { 0 };
textureSubresourceData.pSysMem = textureData.data();
// Specify the size of a row in bytes, known as a priori about the texture data.
textureSubresourceData.SysMemPitch = 1024;
// As this is not a texture array or 3D texture, this parameter is ignored.
textureSubresourceData.SysMemSlicePitch = 0;
// Create a texture description from information known as a priori about the data.
// Generalized texture loading code can be found in the Resource Loading sample.
D3D11_TEXTURE2D_DESC textureDesc = { 0 };
textureDesc.Width = 256;
textureDesc.Height = 256;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
// Most textures contain more than one MIP level. For simplicity, this sample uses only one.
textureDesc.MipLevels = 1;
// As this will not be a texture array, this parameter is ignored.
textureDesc.ArraySize = 1;
// Don't use multi-sampling.
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
// Allow the texture to be bound as a shader resource.
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
ComPtr<ID3D11Texture2D> texture;
DX::ThrowIfFailed(
m_d3dDevice->CreateTexture2D(
&textureDesc,
&textureSubresourceData,
&texture
)
);
// Once the texture is created, we must create a shader resource view of it
// so that shaders may use it. In general, the view description will match
// the texture description.
D3D11_SHADER_RESOURCE_VIEW_DESC textureViewDesc;
ZeroMemory(&textureViewDesc, sizeof(textureViewDesc));
textureViewDesc.Format = textureDesc.Format;
textureViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
textureViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
textureViewDesc.Texture2D.MostDetailedMip = 0;
ComPtr<ID3D11ShaderResourceView> textureView;
DX::ThrowIfFailed(
m_d3dDevice->CreateShaderResourceView(
texture.Get(),
&textureViewDesc,
&textureView
)
);
// Once the texture view is created, create a sampler. This defines how the color
// for a particular texture coordinate is determined using the relevant texture data.
D3D11_SAMPLER_DESC samplerDesc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
// The sampler does not use anisotropic filtering, so this parameter is ignored.
samplerDesc.MaxAnisotropy = 0;
// Specify how texture coordinates outside of the range 0..1 are resolved.
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
// Use no special MIP clamping or bias.
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
// Don't use a comparison function.
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
// Border address mode is not used, so this parameter is ignored.
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
ComPtr<ID3D11SamplerState> sampler;
DX::ThrowIfFailed(
m_d3dDevice->CreateSamplerState(
&samplerDesc,
&sampler
)
);
});
// This value will be used to animate the cube by rotating it every frame;
float degree = 0.0f;
4. 旋轉並繪製紋理立方體,呈現渲染後的影像
如同先前的教學課程一樣,我們進入無限回圈,以持續呈現和顯示場景。 我們使用旋轉量呼叫 rotationY 內聯函式 (BasicMath.h),以設定將立方結構的模型矩陣繞 Y 軸旋轉的值。 然後呼叫 ID3D11DeviceContext::UpdateSubresource,更新常數緩衝區並旋轉多維資料集模型。 接著,我們呼叫 ID3D11DeviceContext::OMSetRenderTargets,以指定轉譯目標和深度樣板檢視。 我們呼叫 ID3D11DeviceContext::ClearRenderTargetView,將呈現目標清除為純藍色,並呼叫 ID3D11DeviceContext::ClearDepthStencilView 以清除深度緩衝區。
在無限回圈中,在藍色曲面上繪製紋理立方體。
繪製紋理立方體
- 首先,我們呼叫 ID3D11DeviceContext::IASetInputLayout,描述頂點緩衝區資料如何流入input-assembler 階段。
- 接下來,我們會呼叫 ID3D11DeviceContext::IASetVertexBuffers 和 ID3D11DeviceContext::IASetIndexBuffer 將頂點和索引緩衝區繫結到輸入組譯工具階段。
- 接著,我們會使用 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP 值呼叫 ID3D11DeviceContext::IASetPrimitiveTopology 以指定輸入組譯工具階段將頂點資料解釋為三角形寬帶。
- 接下來,我們會呼叫 ID3D11DeviceContext::VSSetShader 以使用頂點著色器程式碼初始化頂點著色器階段,並且呼叫 ID3D11DeviceContext::PSSetShader 以使用像素著色器程式碼初始化像素著色器階段。
- 接下來,我們呼叫 ID3D11DeviceContext::VSSetConstantBuffers,以設定頂點著色器流程階段所使用的常數緩衝區。
- 接下來,我們呼叫 PSSetShaderResources,將紋理的著色器資源檢視繫結到畫素著色器流程階段。
- 接下來,我們呼叫 PSSetSamplers,將取樣器狀態設定為畫素著色器流程階段。
- 最後,我們呼叫 ID3D11DeviceContext::DrawIndexed,以繪製立方體,並將立方體提交至轉譯流程。
如同先前的教學課程一樣,我們呼叫 I DXGI SwapChain::Present,將呈現的影像呈現至視窗。
// Update the constant buffer to rotate the cube model.
m_constantBufferData.model = DirectX::XMMatrixRotationY(-degree);
degree += 1.0f;
m_d3dDeviceContext->UpdateSubresource(
m_constantBuffer.Get(),
0,
nullptr,
&m_constantBufferData,
0,
0
);
// Specify the render target and depth stencil we created as the output target.
m_d3dDeviceContext->OMSetRenderTargets(
1,
m_renderTargetView.GetAddressOf(),
m_depthStencilView.Get()
);
// Clear the render target to a solid color, and reset the depth stencil.
const float clearColor[4] = { 0.071f, 0.04f, 0.561f, 1.0f };
m_d3dDeviceContext->ClearRenderTargetView(
m_renderTargetView.Get(),
clearColor
);
m_d3dDeviceContext->ClearDepthStencilView(
m_depthStencilView.Get(),
D3D11_CLEAR_DEPTH,
1.0f,
0
);
m_d3dDeviceContext->IASetInputLayout(inputLayout.Get());
// Set the vertex and index buffers, and specify the way they define geometry.
UINT stride = sizeof(BasicVertex);
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);
// Set the vertex and pixel shader stage state.
m_d3dDeviceContext->VSSetShader(
vertexShader.Get(),
nullptr,
0
);
m_d3dDeviceContext->VSSetConstantBuffers(
0,
1,
m_constantBuffer.GetAddressOf()
);
m_d3dDeviceContext->PSSetShader(
pixelShader.Get(),
nullptr,
0
);
m_d3dDeviceContext->PSSetShaderResources(
0,
1,
textureView.GetAddressOf()
);
m_d3dDeviceContext->PSSetSamplers(
0,
1,
sampler.GetAddressOf()
);
// Draw the cube.
m_d3dDeviceContext->DrawIndexed(
ARRAYSIZE(cubeIndices),
0,
0
);
// Present the rendered image to the window. Because the maximum frame latency is set to 1,
// the render loop will generally be throttled to the screen refresh rate, typically around
// 60 Hz, by sleeping the application on Present until the screen is refreshed.
DX::ThrowIfFailed(
m_swapChain->Present(1, 0)
);
摘要
在本課題中,我們載入原始紋理資料,並將這些資料應用到三維圖元上。