У меня есть проект 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;
};
Я знаюэто много кода, но я понятия не имею, что может быть причиной этого.Я был бы очень признателен за любые указатели в правильном направлении.