[英]DirectX11 IASetVertexBuffers with nullptrs or empty buffers
[英]DirectX11 IASetVertexBuffers “ID3D11Buffer*” is incompatible with
從 class 返回指針的問題
我正在為涉及使用 DirectX 11 的 3D 課程制作一個項目。在 scope 中小得多的作業中,我們被鼓勵將所有代碼放在主文件中及其周圍。 對於這個項目,我想要更多的結構,所以我決定將代碼細分為三個類:WindowHandler、D3DHandler 和 PipelineHandler。
D3DHandler 位於 WindowHandler 中,而 PipelineHandler 位於 D3DHandler 中,如下所示:
class WindowHandler
{
private:
HWND window;
MSG message
class D3DHandler()
{
private:
ID3D11Device*;
ID3D11DeviceContext*;
IDXGISwapChain*;
ID3D11RenderTargetView*;
ID3D11Texture2D*;
ID3D11DepthStencilView*;
D3D11_VIEWPORT;
class PipelineHandler()
{
private:
ID3D11VertexShader* vShader;
ID3D11PixelShader* pShader;
ID3D11InputLayout* inputLayout;
ID3D11Buffer* vertexBuffer;
}
}
}
(這些類被分成了自己的.h庫,我只是想壓縮一下代碼)
一切都很順利,直到我嘗試將 VertexBuffer 綁定到我的Render()
function 中。
void D3DHandler::Render()
{
float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
this->immediateContext->ClearRenderTargetView(this->rtv, clearColor); //Clear backbuffer
this->immediateContext->ClearDepthStencilView(this->dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
UINT32 vertexSize = sizeof(Vertex); //Will be the size of 8 floats, x y z, r g b, u v
UINT32 offset = 0;
this->immediateContext->VSSetShader(this->ph.GetVertexShader(), nullptr, 0);
this->immediateContext->IASetVertexBuffers(0, 1, this->ph.GetVertexBuffer(), &vertexSize, &offset);
this->immediateContext->IASetInputLayout(this->ph.GetInputLayout());
this->immediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
this->immediateContext->PSSetShader(this->ph.GetPixelShader(), nullptr, 0);
//
// Draw geometry
this->immediateContext->Draw(3, 0);
}
問題發生在IASetVertexBuffers
,其中this->ph.GetVertexBuffer()
給出錯誤
“ID3D11Buffer*”與“ID3D11Buffer *const *”類型的參數不兼容
PipelineHandler 中的 Get-function 返回指向 COM object 的指針,對於 VertexBuffer,它看起來像這樣:
ID3D11Buffer * PipelineHandler::GetVertexBuffer() const
{
return this->vertexBuffer;
}
從我找到的文檔中, IASetVertexBuffers
需要一個緩沖區數組,因此是一個雙指針。 但是,在我之前使用過的代碼中, ID3D11Buffer *
是全局的,相同的代碼沒有產生任何錯誤(是的,到目前為止我正在使用的大部分代碼都是從最后一個作業中大量復制的當然,只是放在課堂上)。
我試圖:
ID3D11Buffer & GetVertexBufferRef() const
,它返回return *this->vertexBuffer;
改用那個。我還沒有嘗試:
vertexBuffer
從 PipelineHandler 移動到 D3DHandler。 我有一種感覺會起作用,但它也會將頂點緩沖區與我認為是管道的一部分而不是上下文的其他對象斷開連接,這是我想避免的。我很感激我能得到的任何反饋。 我對編程很陌生,所以任何不能解決我的問題的評論都同樣受歡迎。
您遇到的問題是這個 function 簽名不采用ID3D11Buffer*
接口指針。 它需要一個ID3D11Buffer*
接口指針數組。
this->immediateContext->IASetVertexBuffers(0, 1, this->ph.GetVertexBuffer(), &vertexSize, &offset);
可以是以下任何一種:
this->immediateContext->IASetVertexBuffers(0, 1, &this->ph.GetVertexBuffer(), &vertexSize, &offset);
-或者-
ID3D11Buffer* vb = this->ph.GetVertexBuffer();
this->immediateContext->IASetVertexBuffers(0, 1, &vb, &vertexSize, &offset);
-或者-
ID3D11Buffer* vb[] = { this->ph.GetVertexBuffer() };
this->immediateContext->IASetVertexBuffers(0, 1, vb, &vertexSize, &offset);
這是因為 Direct3D 11 API 支持“多流”渲染,其中輸入布局中引用了多個頂點緩沖區,並在繪制時合並。 function 還采用一個頂點大小和偏移量數組,這就是為什么您必須采用值vertexSize
和offset
的地址,而不是僅按值傳遞。 有關 function 簽名的完整詳細信息,請參閱Microsoft Docs 。
此功能最早是在 Direct3D 9 中引入的,因此可以在此處找到對它的最佳介紹。 使用 Direct3D 11,根據Direct3D 硬件功能級別,您一次最多可以使用 16 或 32 個插槽。 也就是說,大多數基本渲染使用單個流/VertexBuffer。
您應該查看此頁面,了解為什么上面的“第一個”選項會讓您陷入智能指針的麻煩。
對於“第二個”選項,我建議使用 C++11 的auto
鍵盤,因此它是: auto vb = this->ph.GetVertexBuffer();
如果您使用多個 VertexBuffer 進行多流渲染,“第三個”選項顯然最有意義。
請注意,對於索引緩沖區,您永遠不能有多個活動的
ID3D11Buffer
,因此 function 簽名實際上在這種情況下采用ID3D11Buffer*
而不是數組。 請參閱Microsoft 文檔
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.