简体   繁体   English

DirectX11 IASetVertexBuffers “ID3D11Buffer*” 不兼容

[英]DirectX11 IASetVertexBuffers “ID3D11Buffer*” is incompatible with

A problem with returning a pointer from a class从 class 返回指针的问题

I am making a project for a 3D course that involves utilizing DirectX 11. In assignments that were much smaller in scope we were encouraged to just put all the code in and around the main-file.我正在为涉及使用 DirectX 11 的 3D 课程制作一个项目。在 scope 中小得多的作业中,我们被鼓励将所有代码放在主文件中及其周围。 For this project I wanted more structure, so I decided to subdivide the code into three classes: WindowHandler, D3DHandler and PipelineHandler.对于这个项目,我想要更多的结构,所以我决定将代码细分为三个类:WindowHandler、D3DHandler 和 PipelineHandler。

D3DHandler sits in WindowHandler, and PipelineHandler sits in D3DHandler like so: 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;
            }
      } 
}

(The classes are divided into their own.h libraries, I just wanted to compress the code a bit) (这些类被分成了自己的.h库,我只是想压缩一下代码)

Everything ran smoothly until I tried to bind my VertexBuffer in my Render() function.一切都很顺利,直到我尝试将 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);
}

The problem occurs at IASetVertexBuffers , where this->ph.GetVertexBuffer() gives the error问题发生在IASetVertexBuffers ,其中this->ph.GetVertexBuffer()给出错误

"ID3D11Buffer*" is incomaptible with parameter of type "ID3D11Buffer *const *" “ID3D11Buffer*”与“ID3D11Buffer *const *”类型的参数不兼容

The Get-function in PipelineHandler returns a pointer to the COM object, and for VertexBuffer it looks like this: PipelineHandler 中的 Get-function 返回指向 COM object 的指针,对于 VertexBuffer,它看起来像这样:

ID3D11Buffer * PipelineHandler::GetVertexBuffer() const
{
   return this->vertexBuffer;
}

From what documentation I've found, IASetVertexBuffers expects an array of buffers, so a double pointer.从我找到的文档中, IASetVertexBuffers需要一个缓冲区数组,因此是一个双指针。 However, in the code I've worked with before, where the ID3D11Buffer * has been global, the same code generated no errors (and yes, most of the code I'm working so far has been wholesale copied from the last assignment in this course, just placed into classes).但是,在我之前使用过的代码中, ID3D11Buffer *是全局的,相同的代码没有产生任何错误(是的,到目前为止我正在使用的大部分代码都是从最后一个作业中大量复制的当然,只是放在课堂上)。

I have tried to:我试图:

  • to remove the this-> pointer in front of the ph删除 ph 前面的 this-> 指针
  • Creating a new function called ID3D11Buffer & GetVertexBufferRef() const which returns return *this->vertexBuffer;创建一个名为ID3D11Buffer & GetVertexBufferRef() const ,它返回return *this->vertexBuffer; using that instead.改用那个。

I yet to try:我还没有尝试:

  • Moving vertexBuffer from the PipelineHandler and up to D3DHandler.vertexBuffer从 PipelineHandler 移动到 D3DHandler。 I have a feeling that would work, but it would also disconnect the vertex buffer from the other objects that I deem to be part of the pipeline and not the context, which is something I would like to avoid.我有一种感觉会起作用,但它也会将顶点缓冲区与我认为是管道的一部分而不是上下文的其他对象断开连接,这是我想避免的。

I am grateful for any feedback I can get.我很感激我能得到的任何反馈。 I'm fairly new to programming, so any comments that aren't a solution to my problem are just as welcome.我对编程很陌生,所以任何不能解决我的问题的评论都同样受欢迎。

The problem your are having is that this function signature does not take a ID3D11Buffer* interface pointer.您遇到的问题是这个 function 签名不采用ID3D11Buffer*接口指针。 It takes an array of ID3D11Buffer* interface pointers.它需要一个ID3D11Buffer*接口指针数组

this->immediateContext->IASetVertexBuffers(0, 1, this->ph.GetVertexBuffer(), &vertexSize, &offset);

Can be any of the following:可以是以下任何一种:

this->immediateContext->IASetVertexBuffers(0, 1, &this->ph.GetVertexBuffer(), &vertexSize, &offset);

-or- -或者-

ID3D11Buffer* vb = this->ph.GetVertexBuffer();
this->immediateContext->IASetVertexBuffers(0, 1, &vb, &vertexSize, &offset);

-or- -或者-

ID3D11Buffer* vb[] = { this->ph.GetVertexBuffer() };
this->immediateContext->IASetVertexBuffers(0, 1, vb, &vertexSize, &offset);

This is because the Direct3D 11 API supports 'multi-stream' rendering where you have more than one Vertex Buffer referenced in the Input Layout which is merged as it is drawn.这是因为 Direct3D 11 API 支持“多流”渲染,其中输入布局中引用了多个顶点缓冲区,并在绘制时合并。 The function also takes an array of vertex sizes and offsets, which is why you had to take the address of the values vertexSize and offset instead of just passing by value. function 还采用一个顶点大小和偏移量数组,这就是为什么您必须采用值vertexSizeoffset的地址,而不是仅按值传递。 See Microsoft Docs for full details on the function signature.有关 function 签名的完整详细信息,请参阅Microsoft Docs

This feature was first introduced back in Direct3D 9, so the best introduction to it is found here .此功能最早是在 Direct3D 9 中引入的,因此可以在此处找到对它的最佳介绍。 With Direct3D 11, depending on Direct3D hardware feature level you can use up to 16 or 32 slots at once.使用 Direct3D 11,根据Direct3D 硬件功能级别,您一次最多可以使用 16 或 32 个插槽。 That said, most basic rendering uses a single stream/VertexBuffer.也就是说,大多数基本渲染使用单个流/VertexBuffer。

  1. You should take a look at this page as to why the 'first' option above can get you into trouble with smart-pointers.您应该查看此页面,了解为什么上面的“第一个”选项会让您陷入智能指针的麻烦。

  2. For the 'second' option, I'd recommend using C++11's auto keyboard so it would be: auto vb = this->ph.GetVertexBuffer();对于“第二个”选项,我建议使用 C++11 的auto键盘,因此它是: auto vb = this->ph.GetVertexBuffer();

  3. The 'third' option obviously makes most sense if you are using more than one VertexBuffer for multi-stream rendering.如果您使用多个 VertexBuffer 进行多流渲染,“第三个”选项显然最有意义。

Note that you can never have more than one ID3D11Buffer active for the Index Buffer, so the function signature does in fact take a ID3D11Buffer* in that case and not an array.请注意,对于索引缓冲区,您永远不能有多个活动的ID3D11Buffer ,因此 function 签名实际上在这种情况下采用ID3D11Buffer*而不是数组。 See Microsoft Docs请参阅Microsoft 文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM