我一直在玩遊戲一段時間,現在一直在使用SDL,然後是SFML。爲我完成基礎知識已經很不錯了,但現在我想再邁一步,學習如何從頭開始製作圖形。所以我想學習Direct3D的知識,並且一直在閱讀D3D 11的一些教程以開始。我只是想通過在黑暗的背景上繪製白色三角形來獲得絕對的基礎知識......但我無法實現它的工作。開始Direct3D,簡單的三角形不渲染
我使用的是Visual Studio 2012 RC和Windows 8 SDK,因此這裏有一些C++ 11語法,再加上沒有D3DX。我設法設置窗口,Direct3D的初始化似乎很好。它運行主循環的渲染部分,因爲它以我指定的顏色清除屏幕。但是,我的白色三角形不會顯示出來。我已經多次閱讀我的代碼,並且由於缺乏經驗,我無法分辨它有什麼問題。我已經刪除了窗口初始化/ d3d關機和其他不相關的部分,但是如果有些部分與我的問題相關,我恐怕會切斷太多,所以......大量代碼警告。
我想我已經完成了所有必需的步驟;我創建設備,設備上下文,交換鏈和渲染目標。然後我創建一個頂點着色器+輸入佈局和一個像素着色器。之後,我創建一個頂點緩衝區,爲我的三角形添加頂點並將原始拓撲設置爲TRIANGLELIST,這就是初始化。在我的主循環中,我將D3D指向我的頂點/像素着色器,並告訴它繪製插入緩衝區的3個頂點。但只有調用ClearRenderTargetView的深藍色背景顯示出來;沒有三角形。我錯過了任何步驟,或者在路上做了什麼錯事?
下面是代碼我有(我可恥承認已經鬆懈一點與在這一個代碼約定,所以指針變量等之前沒有P):
主迴路:
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
g_d3dContext->ClearRenderTargetView(g_renderTarget, clearColor);
g_d3dContext->VSSetShader(g_vertexShader, nullptr, 0);
g_d3dContext->PSSetShader(g_pixelShader, nullptr, 0);
g_d3dContext->Draw(3, 0);
g_swapChain->Present(0, 0);
}
}
Direct3D的初始化:
HRESULT hr = S_OK;
RECT rc;
GetClientRect(g_hWnd, &rc);
float width = static_cast<float>(rc.right - rc.left);
float height = static_cast<float>(rc.bottom - rc.top);
uint createDeviceFlags = 0;
const uint numDriverTypes = 3;
D3D_DRIVER_TYPE driverTypes[ numDriverTypes ] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE
};
const uint numFeatureLevels = 3;
D3D_FEATURE_LEVEL featureLevels[ numFeatureLevels ] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
DXGI_SWAP_CHAIN_DESC sd = { 0 };
sd.BufferCount = 1;
sd.BufferDesc.Width = static_cast<uint>(width);
sd.BufferDesc.Height = static_cast<uint>(height);
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = true;
for(uint driverTypeIndex : driverTypes)
{
g_driverType = driverTypes[ driverTypeIndex ];
hr = D3D11CreateDeviceAndSwapChain(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_swapChain, &g_d3d, &g_featureLevel, &g_d3dContext);
if(SUCCEEDED(hr))
break;
}
if(FAILED(hr))
return hr;
// Create a render target view
ID3D11Texture2D* backBuffer = nullptr;
hr = g_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
if(FAILED(hr))
return hr;
hr = g_d3d->CreateRenderTargetView(backBuffer, nullptr, &g_renderTarget);
backBuffer->Release();
if(FAILED(hr))
return hr;
g_d3dContext->OMSetRenderTargets(1, &g_renderTarget, nullptr);
// Setup the viewport
D3D11_VIEWPORT vp = { 0 };
vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_d3dContext->RSSetViewports(1, &vp);
// Create vertex shader and input layout
ID3DBlob* vsBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
hr = D3DCompileFromFile(L"VertexShader.hlsl", nullptr, nullptr, "main", "vs_4_0", 0, 0, &vsBlob, &errorBlob);
if (FAILED(hr))
return hr;
hr = g_d3d->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &g_vertexShader);
if (FAILED(hr))
{
vsBlob->Release();
return hr;
}
D3D11_INPUT_ELEMENT_DESC ied = { 0 };
ied.AlignedByteOffset = 0;
ied.Format = DXGI_FORMAT_R32G32B32_FLOAT;
ied.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
ied.InputSlot = 0;
ied.InstanceDataStepRate = 0;
ied.SemanticIndex = 0;
ied.SemanticName = "POSITION";
hr = g_d3d->CreateInputLayout(&ied, 1, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &g_inputLayout);
vsBlob->Release();
if (FAILED (hr))
return hr;
g_d3dContext->IASetInputLayout(g_inputLayout);
// Create pixel shader
ID3DBlob* psBlob = nullptr;
errorBlob = nullptr;
hr = D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "main", "ps_4_0", 0, 0, &psBlob, &errorBlob);
if (FAILED(hr))
return hr;
hr = g_d3d->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &g_pixelShader);
psBlob->Release();
if (FAILED(hr))
return hr;
// Put some vertices up in this bitch
Vector3f vertices[] =
{
Vector3f(0.5f, -0.5f, 0.5f),
Vector3f(0.5f, -0.5f, 0.5f),
Vector3f(-0.5f, -0.5f, 0.5f)
};
D3D11_BUFFER_DESC bd = { 0 };
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.ByteWidth = sizeof(Vector3f) * 3;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = 0;
bd.Usage = D3D11_USAGE_DEFAULT;
D3D11_SUBRESOURCE_DATA initData = { 0 };
initData.pSysMem = vertices;
initData.SysMemPitch = 0;
initData.SysMemSlicePitch = 0;
hr = g_d3d->CreateBuffer(&bd, &initData, &g_vertexBuffer);
if (FAILED(hr))
return hr;
uint stride = sizeof(Vector3f);
uint offset = 0;
g_d3dContext->IASetVertexBuffers(0, 1, &g_vertexBuffer, &stride, &offset);
g_d3dContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
return S_OK;
我的頂點類型:
struct Vector3f
{
Vector3f(float ix, float iy, float iz)
: x(ix), y(iy), z(iz) {}
float x;
float y;
float z;
};
我的頂點着色器:
float4 main(float4 pos : POSITION) : SV_POSITION
{
return pos;
}
我的像素着色器:
float4 main() : SV_TARGET
{
return float4(1.0f, 1.0f, 1.0f, 1.0f);
}