首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试在directx11中渲染网格时,三角形似乎引用了错误的顶点

尝试在directx11中渲染网格时,三角形似乎引用了错误的顶点
EN

Stack Overflow用户
提问于 2019-06-25 23:13:41
回答 1查看 129关注 0票数 0

我有一个使用DirectX-11渲染程序网格的c++/cx项目。它以前是有效的,但现在,使用新的网格,三角形看起来不正确,就像它们引用了错误的顶点索引一样。我花了很长时间试图找出问题所在,但我完全不知道是什么原因造成了这种情况。

我从一个文本文件中加载顶点和三角形数据,并将其传递给我的自定义网格类,后者根据数据创建网格。当我记录顶点和三角形数据时,它们都是正确的,所以这让我认为在将数据发送到着色器时出现了问题,但我不知道是什么导致了这种情况。

下面是(基础) Mesh类:

代码语言:javascript
复制
#include <array>

#include "Data\Mesh.h"
#include "Utilities.h"

using namespace Ambiorix::Track3DComponent;
using namespace Ambiorix::Track3DComponent::Data;

Mesh::Mesh(ITrack3DLogger^ logger, ComPtr<ID3D11Device1> d3dDevice, ComPtr<ID3D11DeviceContext1> d3dContext)
    : _logger(logger),
    _inputLayout(nullptr),
    _vertexBuffer(nullptr),
    _indexBuffer(nullptr),
    _vertexBufferStride(0u),
    _vertexBufferOffset(0u),
    _indexFormat(DXGI_FORMAT_R16_UINT),
    _indexCount(0u),
    _primitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST),
    _isVertexShaderCreated(false),
    _isPixelShaderCreated(false)
{
    _d3dDevice = d3dDevice;
    _d3dContext = d3dContext;
    _modelMatrix = Utilities::CreateFloat4x4IdentityMatrix();
}

void Mesh::Render(ModelViewProjectionConstantBuffer* const modelViewProjectionConstantBuffer, bool visible)
{
    if (!_isVertexShaderCreated || !_isPixelShaderCreated)
    {
        return;
    }

    XMStoreFloat4x4(&modelViewProjectionConstantBuffer->model, XMLoadFloat4x4(&_modelMatrix));

    const unsigned int DESTINATION_SUB_RESOURCE = 0u;
    const D3D11_BOX* DESTINATION_BOX = nullptr;
    const unsigned int SOURCE_ROW_PITCH = 0u;
    const unsigned int SOURCE_DEPTH_PITCH = 0u;
    _d3dContext->UpdateSubresource(_constantBuffer.Get(), DESTINATION_SUB_RESOURCE, DESTINATION_BOX, modelViewProjectionConstantBuffer, SOURCE_ROW_PITCH, SOURCE_DEPTH_PITCH);

    const unsigned int START_SLOT = 0u;
    const unsigned int NUM_BUFFERS = 1u;
    _d3dContext->IASetVertexBuffers(START_SLOT, NUM_BUFFERS, _vertexBuffer.GetAddressOf(), &_vertexBufferStride, &_vertexBufferOffset);

    const unsigned int OFFSET = 0u;
    _d3dContext->IASetIndexBuffer(_indexBuffer.Get(), _indexFormat, OFFSET);

    _d3dContext->IASetPrimitiveTopology(_primitiveTopology);

    _d3dContext->IASetInputLayout(_inputLayout.Get());

    ID3D11ClassInstance*const* CLASS_INSTANCES = nullptr;
    const unsigned int NUM_CLASS_INSTANCES = 0u;
    _d3dContext->VSSetShader(_vertexShader.Get(), CLASS_INSTANCES, NUM_CLASS_INSTANCES);

    _d3dContext->VSSetConstantBuffers(START_SLOT, NUM_BUFFERS, _constantBuffer.GetAddressOf());

    _d3dContext->PSSetShader(_pixelShader.Get(), CLASS_INSTANCES, NUM_CLASS_INSTANCES);

    SetTexture();

    ID3D11BlendState* d3dBlendState;
    D3D11_BLEND_DESC omDesc;
    ZeroMemory(&omDesc, sizeof(D3D11_BLEND_DESC));
    omDesc.RenderTarget[0].BlendEnable = true;
    omDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    omDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
    if (visible)
    {
        omDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; //apparently it's premultiplied. (cause otherwise it should be D3D11_BLEND_SRC_ALPHA)
        omDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
        omDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
    }
    else
    {
        omDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ZERO; //invisible
        omDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; //invisible
        omDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
    }
    omDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
    omDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

    //if (FAILED(d3dDevice->CreateBlendState(&omDesc, &d3dBlendState)))return false;
    _d3dDevice->CreateBlendState(&omDesc, &d3dBlendState);
    _d3dContext->OMSetBlendState(d3dBlendState, 0, 0xffffffff);

    const unsigned int START_INDEX_LOCATION = 0u;
    const int BASE_VERTEX_LOCATION = 0;
    _d3dContext->DrawIndexed(_indexCount, START_INDEX_LOCATION, BASE_VERTEX_LOCATION);
}

void Mesh::Translate(XMVECTOR& position)
{
    XMStoreFloat4x4(&_modelMatrix, XMMatrixTranspose(XMMatrixTranslationFromVector(position)));
}

void Mesh::Rotate(XMVECTOR& axis, float angle)
{
    XMStoreFloat4x4(&_modelMatrix, XMMatrixRotationAxis(axis, angle));
}

void Mesh::Transform(XMVECTOR& position, XMVECTOR& rotationQuaternion)
{
    static const XMVECTOR ZERO = { 0.0f, 0.0f, 0.0f, 0.0f };
    static const XMVECTOR ONE = { 1.0f, 1.0f, 1.0f, 0.0f };

    XMStoreFloat4x4(&_modelMatrix, XMMatrixTranspose(XMMatrixAffineTransformation(ONE, ZERO, rotationQuaternion, position)));
}

task<void> Mesh::CreateVertexShaderAsync(Platform::String^ relativeFileName, const D3D11_INPUT_ELEMENT_DESC *const vertexDescriptions, unsigned int vertexDescriptionCount)
{
    _logger->Trace(L"Mesh.CreateVertexShaderAsync()");

    return Utilities::ReadAllFileBytesAsync(relativeFileName)
        .then([this, vertexDescriptions, vertexDescriptionCount] (const Platform::Array<byte>^ vertexShaderBytes)
        {
            critical_section::scoped_lock lock(_criticalSection);

            if (vertexShaderBytes->Length == 0u)
            {
                _logger->Error(L"Mesh.CreateVertexShaderAsync() | Failed to load vertex shader.");
                return;
            }

            auto createVertexShaderResult = _d3dDevice->CreateVertexShader(vertexShaderBytes->Data, vertexShaderBytes->Length, nullptr, _vertexShader.GetAddressOf());
            if (FAILED(createVertexShaderResult))
            {
                _logger->Error(L"Mesh.CreateVertexShaderAsync() | Failed to create vertex shader.");
                return;
            }

            auto createInputLayoutResult = _d3dDevice->CreateInputLayout(vertexDescriptions, vertexDescriptionCount, vertexShaderBytes->Data, vertexShaderBytes->Length, _inputLayout.GetAddressOf());
            if (FAILED(createInputLayoutResult))
            {
                _logger->Error(L"Mesh.CreateVertexShaderAsync() | Failed to create input layout.");
                return;
            }

            _logger->Trace(L"Mesh.CreateVertexShaderAsync() | Vertex shader created.");
            _isVertexShaderCreated = true;
        });
}

task<void> Mesh::CreatePixelShaderAsync(Platform::String^ relativeFileName)
{
    _logger->Trace(L"Mesh.CreatePixelShaderAsync()");

    return Utilities::ReadAllFileBytesAsync(relativeFileName)
        .then([this](const Platform::Array<byte>^ pixelShaderBytes)
        {
            critical_section::scoped_lock lock(_criticalSection);

            if (pixelShaderBytes->Length == 0u)
            {
                _logger->Error(L"Mesh.CreatePixelShaderAsync() | Failed to load pixel shader.");
                return;
            }

            auto createPixelShaderResult = _d3dDevice->CreatePixelShader(pixelShaderBytes->Data, pixelShaderBytes->Length, nullptr, _pixelShader.GetAddressOf());
            if (FAILED(createPixelShaderResult))
            {
                _logger->Error(L"Mesh.CreatePixelShaderAsync() | Failed to create pixel shader.");
                return;
            }

            ModelViewProjectionConstantBuffer modelViewProjectionConstantBuffer;

            D3D11_SUBRESOURCE_DATA InitData;
            InitData.pSysMem = &modelViewProjectionConstantBuffer;
            InitData.SysMemPitch = 0u;
            InitData.SysMemSlicePitch = 0u;

            CD3D11_BUFFER_DESC bufferDescription(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);

            auto createConstantBuffer = _d3dDevice->CreateBuffer(&bufferDescription, &InitData, _constantBuffer.GetAddressOf());
            if (FAILED(createConstantBuffer))
            {
                _logger->Error(L"Mesh.CreatePixelShaderAsync() | Failed to create constant buffer.");
                return;
            }

            _logger->Trace(L"Mesh.CreatePixelShaderAsync() | Pixel shader created.");
            _isPixelShaderCreated = true;
        });
}

下面是实际的网格类,名为CullingMesh:

代码语言:javascript
复制
#include "Data\CullingMesh.h"
#include "ShaderStructures\VertexPositionColor.h"
#include <DDSTextureLoader.h>
#include "Utilities.h"

using namespace Ambiorix::Track3DComponent;
using namespace Ambiorix::Track3DComponent::Data;
using namespace Ambiorix::Track3DComponent::ShaderStructures;

CullingMesh::CullingMesh(ITrack3DLogger^ logger, ComPtr<ID3D11Device1> d3dDevice, ComPtr<ID3D11DeviceContext1> d3dContext)
    : Mesh(logger, d3dDevice, d3dContext)
{
    _vertexBufferStride = sizeof(VertexPositionColor);

    _vertexShaderRelativeFilePath = ref new Platform::String(L"Ambiorix.Track3DComponent\\RoadVertexShader.cso");
    _pixelShaderRelativeFilePath = ref new Platform::String(L"Ambiorix.Track3DComponent\\RoadPixelShader.cso");
}

task<void> CullingMesh::InitializeAsync(const std::vector<Vector>*const vertices, const std::vector<int>*const triangles)
{
    _logger->Trace(L"CullingMesh.InitializeAsync()");

    std::vector<task<void>> tasks;
    tasks.push_back(CreateVertexShaderAsync(_vertexShaderRelativeFilePath, _vertexDescriptions, ARRAYSIZE(_vertexDescriptions)));
    tasks.push_back(CreatePixelShaderAsync(_pixelShaderRelativeFilePath));

    return when_all(tasks.begin(), tasks.end())
        .then([this, vertices, triangles]
    {
        CreateMesh(vertices, triangles);

        _logger->Trace("CullingMesh.InitializeAsync() | Done.");
    });
}

void CullingMesh::CreateMesh(const std::vector<Vector>*const vertices, const std::vector<int>*const triangles)
{
    _logger->Trace(L"CullingMesh.Initialize()");

    static const size_t VERTEX_COUNT = vertices->size();
    _logger->Error("VERTEX_COUNT: " + VERTEX_COUNT.ToString());

    auto vertexData = new VertexPositionColor[VERTEX_COUNT];
    for (int i = 0; i < VERTEX_COUNT; i++)
    {
        auto currentVertexData = &vertexData[i];
        XMFLOAT3 pos;
        XMStoreFloat3(&pos, Utilities::ToVector(vertices->at(i)));
        currentVertexData->Position = pos;
        currentVertexData->Color = { 1,0,0 };
    }

    D3D11_SUBRESOURCE_DATA vertexBufferData = { 0 };
    vertexBufferData.pSysMem = vertexData;
    vertexBufferData.SysMemPitch = 0u;
    vertexBufferData.SysMemSlicePitch = 0u;

    CD3D11_BUFFER_DESC vertexBufferDescription(static_cast<unsigned int>(sizeof(*vertexData) * VERTEX_COUNT), D3D11_BIND_VERTEX_BUFFER);

    auto createVertexBufferResult = _d3dDevice->CreateBuffer(&vertexBufferDescription, &vertexBufferData, _vertexBuffer.GetAddressOf());
    if (FAILED(createVertexBufferResult))
    {
        _logger->Error(L"CullingMesh.Initialize() | Failed to create vertex buffer.");
    }

    delete vertexData;

    _indexCount = (unsigned int)triangles->size();
    _logger->Error("_indexCount: " + _indexCount.ToString());

    auto triangleIndices = new unsigned int[_indexCount];
    for (unsigned int i = 0; i < _indexCount; i++)
    {
        triangleIndices[i] = triangles->at(i);
    }

    D3D11_SUBRESOURCE_DATA indexBufferData = { 0 };
    indexBufferData.pSysMem = triangleIndices;
    indexBufferData.SysMemPitch = 0u;
    indexBufferData.SysMemSlicePitch = 0u;

    CD3D11_BUFFER_DESC indexBufferDescription(sizeof(*triangleIndices) * _indexCount, D3D11_BIND_INDEX_BUFFER);

    auto createIndexBufferResult = _d3dDevice->CreateBuffer(&indexBufferDescription, &indexBufferData, _indexBuffer.GetAddressOf());
    if (FAILED(createIndexBufferResult))
    {
        _logger->Error(L"CullingMesh.Initialize() | Failed to create index buffer.");
    }

    delete triangleIndices;

    _logger->Trace("CullingMesh.Initialize() | Done.");
}

void CullingMesh::SetTexture()
{
    //no texture
}

VertexPositionColor结构就是这样的:

代码语言:javascript
复制
        struct VertexPositionColor
        {
            XMFLOAT3 Position;
            XMFLOAT3 Color;
        };

我知道这是大量的代码,但我不知道是什么导致了这一点。我真的很感激任何在正确方向上的指点。

EN

回答 1

Stack Overflow用户

发布于 2019-08-06 06:09:56

这里有几点建议,因为我已经经历了与您所经历的相同的问题。

对于

  • 的内存对齐和大小,只需确保您的VertexPositionColour实际上是32字节宽的,并且没有将值打包到前24个字节中。确保您也遵循16字节边界对齐方式。您可以填充结构并使用XMFloat4来确保填充是correct.

  • Double检查您的索引缓冲区是32位索引。但这看起来没问题。

  • 在大多数情况下,我发现当数据看起来正确时,这是缓冲区中的对齐问题。您正在使用的一些便利函数还隐藏了我通常显式设置的一些细节。在您可能的情况下,有时在缓冲区定义中更加冗长也有助于找到难以找到的错误。

祝好运。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56757199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档