Треугольники, кажется, ссылаются на неправильные вершины при попытке визуализации меша в directx11 - PullRequest
0 голосов
/ 25 июня 2019

У меня есть проект c ++ / cx, в котором я рендерил процедурные сетки с использованием DirectX-11.Раньше это работало, но теперь, с новой сеткой, треугольники кажутся неправильными, как будто они ссылаются на неправильный индекс вершины.Я потратил целую вечность, пытаясь выяснить, что не так, но я абсолютно не представляю, что может быть причиной этого.

Я загружаю данные вершин и треугольников из текстового файла, передаю их в свой собственный класс сетки,который создает сетку из данных.когда я записываю данные о вершинах и треугольниках, это все правильно, так что это заставляет меня думать, что что-то идет не так при отправке данных в шейдеры, но я понятия не имею, что может вызвать это.

Вот (база) Класс сетки:

#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:

#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 просто так:

        struct VertexPositionColor
        {
            XMFLOAT3 Position;
            XMFLOAT3 Color;
        };

Я знаюэто много кода, но я понятия не имею, что может быть причиной этого.Я был бы очень признателен за любые указатели в правильном направлении.

...