InstanceBuffer在DX 11_0中不起作用

InstanceBuffer not working in DX 11_0

本文关键字:不起作用 DX InstanceBuffer      更新时间:2023-10-16

所以我遇到了这个问题,我已经坚持了几个星期了,因为实例缓冲区在我的DX 11_0应用程序中不起作用,顶点缓冲区和索引缓冲区只起作用,但由于某种原因,即使实例缓冲区是用S_OK创建的,并且没有抛出错误,也没有任何东西传递到实例缓冲区。

以下是实例缓冲区的定义和创建

instanceDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    instanceDesc.ByteWidth = sizeof(InstanceVertex2) * MAX_INSTANCES;
    instanceDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    instanceDesc.MiscFlags = 0;
    instanceDesc.StructureByteStride = 0;
    instanceDesc.Usage = D3D11_USAGE_DYNAMIC;
    instanceData.pSysMem = new InstanceVertex2[MAX_INSTANCES];
    instanceData.SysMemPitch = 0;
    instanceData.SysMemSlicePitch = 0;
    //create the instance buffer
    result = device->CreateBuffer(&instanceDesc, &instanceData, &m_instanceBuffer);
    if (FAILED(result))
    {
        return false;
    }

这是多边形布局

//vertex position, by vertex
    polygonLayout[0].AlignedByteOffset = 0;
    polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
    polygonLayout[0].InputSlot = 0;
    polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    polygonLayout[0].InstanceDataStepRate = 0;
    polygonLayout[0].SemanticIndex = 0;
    polygonLayout[0].SemanticName = "POSITION";
    //uv coords, by vertex
    polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
    polygonLayout[1].InputSlot = 0;
    polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    polygonLayout[1].InstanceDataStepRate = 0;
    polygonLayout[1].SemanticIndex = 0;
    polygonLayout[1].SemanticName = "TEXCOORD";
    //texture ID, by instance
    polygonLayout[2].AlignedByteOffset = 0;
    polygonLayout[2].Format = DXGI_FORMAT_R32_SINT;
    polygonLayout[2].InputSlot = 1;
    polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[2].InstanceDataStepRate = 1;
    polygonLayout[2].SemanticIndex = 0;
    polygonLayout[2].SemanticName = "TEXTUREID";
    //color, by instance
    polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[3].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[3].InputSlot = 1;
    polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[3].InstanceDataStepRate = 1;
    polygonLayout[3].SemanticIndex = 0;
    polygonLayout[3].SemanticName = "COLOR";
    //UVAdd , by instance
    polygonLayout[4].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[4].Format = DXGI_FORMAT_R32G32_FLOAT;
    polygonLayout[4].InputSlot = 1;
    polygonLayout[4].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[4].InstanceDataStepRate = 1;
    polygonLayout[4].SemanticIndex = 0;
    polygonLayout[4].SemanticName = "UVADD";
    //UVMultiply, by instance
    polygonLayout[5].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[5].Format = DXGI_FORMAT_R32G32_FLOAT;
    polygonLayout[5].InputSlot = 1;
    polygonLayout[5].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[5].InstanceDataStepRate = 1;
    polygonLayout[5].SemanticIndex = 0;
    polygonLayout[5].SemanticName = "UVMULTIPLY";
    //matrix row 1
    polygonLayout[6].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[6].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[6].InputSlot = 1;
    polygonLayout[6].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[6].InstanceDataStepRate = 1;
    polygonLayout[6].SemanticIndex = 0;
    polygonLayout[6].SemanticName = "MATRIX";
    //matrix row 2
    polygonLayout[7].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[7].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[7].InputSlot = 1;
    polygonLayout[7].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[7].InstanceDataStepRate = 1;
    polygonLayout[7].SemanticIndex = 1;
    polygonLayout[7].SemanticName = "MATRIX";
    //matrix row 3
    polygonLayout[8].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[8].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[8].InputSlot = 1;
    polygonLayout[8].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[8].InstanceDataStepRate = 1;
    polygonLayout[8].SemanticIndex = 2;
    polygonLayout[8].SemanticName = "MATRIX";
    //matrix row 4
    polygonLayout[9].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[9].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[9].InputSlot = 1;
    polygonLayout[9].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
    polygonLayout[9].InstanceDataStepRate = 1;
    polygonLayout[9].SemanticIndex = 3;
    polygonLayout[9].SemanticName = "MATRIX";
    numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
    //create the input layout
    result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &m_layout);
    if (FAILED(result))
    {
        MessageBox(hwnd, TEXT("Failed to create the input layout"), TEXT("Error initializaing shader"), MB_OK);
        return false;
    }

这是我实际更新实例缓冲区(它是动态的)

result = deviceContext->Map(m_instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
    if (FAILED(result))
    {
        return false;
    }
    instancesPtr = (InstanceVertex2*)data.pData;
    memcpy(instancesPtr, (void*)instances, sizeof(&m_vertices[0]));
    //now un map
     deviceContext->Unmap(m_instanceBuffer, 0);

最后,这是我将缓冲区放入设备上下文的代码

//set the buffers
    buffers[0] = m_vertexBuffer;
    buffers[1] = m_instanceBuffer;
    //set the strides
    strides[0] = sizeof(InstanceVertex1);
    strides[1] = sizeof(InstanceVertex2);
    //set the offsets
    offsets[0] = 0;
    offsets[1] = 0;
    //set the vertex buffers
    deviceContext->IASetVertexBuffers(0, 2, buffers, strides, offsets);
    //set the index buffers
    deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
    deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

这看起来确实有很多代码需要查看,但我不知道到底出了什么问题,我过去有实例化和动态顶点缓冲区可以正常工作,而且由于某种原因,当我将它们组合在一起时,我无法使其正常工作。我有nvidea-nsight,所以我可以直接查看顶点着色器和缓冲区,从我所看到的情况可以看出,没有任何东西被传递到实例缓冲区。如果有人愿意给我任何帮助或建议,我将不胜感激,这样我就能解决我的问题。

我想明白了,问题不在于实例缓冲区的初始化,而在于我更新它的方式,我将包括它的答案,以便其他人能够获得类似问题的帮助。

我改了:

result = deviceContext->Map(m_instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
if (FAILED(result))
{
    return false;
}
instancesPtr = (InstanceVertex2*)data.pData;
memcpy(instancesPtr, (void*)instances, sizeof(&m_vertices[0]));
//now un map
 deviceContext->Unmap(m_instanceBuffer, 0);

收件人:

result = deviceContext->Map(m_instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &data);
    if (FAILED(result))
    {
        return false;
    }
    instancesPtr = (InstanceVertex2*)data.pData;
    for (int i = 0;i < m_vertices.size();i++)
    {
        instancesPtr[i].color = m_vertices[i].color;
        instancesPtr[i].matrixInstance = m_vertices[i].matrixInstance;
        instancesPtr[i].textureID = m_vertices[i].textureID;
        instancesPtr[i].UVAdd = m_vertices[i].UVAdd;
        instancesPtr[i].UVMultiply = m_vertices[i].UVMultiply;
    }
    //memcpy(instancesPtr, (void*)instances, sizeof(&m_vertices[0]));
    //now un map
     deviceContext->Unmap(m_instanceBuffer, 0);

我希望有一天这能帮助其他人解决这个问题,这确实花了我足够长的时间。