Direct3D 11 — Рисование треугольника

Я инициализировал все Direct3D 11, но когда я пришел нарисовать некоторую геометрию, геометрия не показывается.

Я создал Pipeline, Geometry и создал функцию рисования для геометрии, которую нужно нарисовать. Мой главный вопрос: может ли кто-нибудь помочь мне понять, почему в окне не нарисован треугольник?

void cSystem::Draw(UINT count)
{
// draw stuff...
UINT stride = sizeof(Vertex);
UINT offset = 0;
p_D3D11DeviceContext->IASetVertexBuffers(0, 1, &p_VertextBuffer, &stride, &offset);

p_D3D11DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

p_D3D11DeviceContext->Draw(3, 0);

if (count == 0)
{
INFO(L"Draw() Complete");
}
}

void cSystem::InitGeometry() // initialise the geometry for the scene
{
Vertex vertices[] =
{
{ D3DXVECTOR3(0.0f, 0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
{ D3DXVECTOR3(0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
{ D3DXVECTOR3(-0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) }
};

D3D11_BUFFER_DESC bdsc;
ZeroMemory(&bdsc, sizeof(D3D11_BUFFER_DESC));
bdsc.Usage = D3D11_USAGE_IMMUTABLE;
bdsc.ByteWidth = sizeof(Vertex) * 3;
bdsc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bdsc.CPUAccessFlags = 0;
bdsc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitdata;
ZeroMemory(&vinitdata, sizeof(D3D11_SUBRESOURCE_DATA));
vinitdata.pSysMem = vertices;

p_D3D11Device->CreateBuffer(&bdsc, &vinitdata, &p_VertextBuffer);

/*D3D11_MAPPED_SUBRESOURCE ms;
p_D3D11DeviceContext->Map(p_VertextBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, vertices, sizeof(Vertex));
p_D3D11DeviceContext->Unmap(p_VertextBuffer, NULL);*/

INFO(L"InitGeometry() Complete");
}

void cSystem::InitPipeline(void)
{
#if defined(DEBUG) || (_DEBUG)
DWORD shaderflags = 0;
#endif
//p_D3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0;
ID3D10Blob *VS_, *PS_ = NULL;
D3DX11CompileFromFile(L"Shader.shader", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_, 0, 0);
D3DX11CompileFromFile(L"Shader.shader", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_, 0, 0);

p_D3D11Device->CreateVertexShader(VS_->GetBufferPointer(), VS_->GetBufferSize(), NULL, &p_VS);
p_D3D11Device->CreatePixelShader(PS_->GetBufferPointer(), PS_->GetBufferSize(), NULL, &p_PS);

p_D3D11DeviceContext->VSSetShader(p_VS, 0, 0);
p_D3D11DeviceContext->PSSetShader(p_PS, 0, 0);

D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT NumElements = ARRAYSIZE(layout);

p_D3D11Device->CreateInputLayout(layout, NumElements, VS_->GetBufferPointer(),
VS_->GetBufferSize(), &p_InputLayout);

p_D3D11DeviceContext->IASetInputLayout(p_InputLayout);

VS_->Release();
PS_->Release();

INFO(L"InitPipeline() Complete");
}

void cSystem::D3D11RenderFrame_(void)
{
// clear the back buffer
p_D3D11DeviceContext->ClearRenderTargetView(p_D3D11RenderTargetView, m_BackBufferColour[0]);
// clear the depth buffer
p_D3D11DeviceContext->ClearDepthStencilView(p_D3D11DepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0.0f);

// draw
Draw(count++);

// switch the back buffer and the front buffer
p_D3D11SwapChain->Present(0, 0);
}

Шейдер (или .fx файл)

struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};

VOut VS(float4 position : POSITION, float4 color : COLOR)
{
VOut output;

output.position = position;
output.color = color;

return output;
}float4 PS(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}

Ссылка на картинку программы находится здесь: http://i.imgur.com/JyNkPqQ.png

Вызовы сделаны правильно при исполнении программы, но не отображаются ..
На всякий случай, если мой вопрос забыт сверху, почему не отображается треугольник?

Я надеюсь, что кто-то может помочь.. 🙂

3

Решение

Я не гуру в DirectX11 (на самом деле я только недавно начал), но кажется, что даже если ваш вершинный шейдер получит D3DXVECTOR3 для положения вершины, вы говорите, что POSITION является

Четырехкомпонентный 32-битный формат unsigned-normalized-integer, поддерживающий 8 бит на канал, включая альфа-канал.

в вашей структуре ввода. Теперь это сбивает с толку!

Вы должны использовать DXGI_FORMAT_R32G32B32_FLOAT,

Спасибо за чтение.

2

Другие решения

Это может быть не совсем ответ, но, надеюсь, это полезно. Иногда трудно понять, почему что-то не рисуется, просто глядя на код. Причин может быть несколько, а иногда они могут быть как бы скрытыми.

Обычно, когда я сталкиваюсь с этой проблемой, я загружаю графический отладчик, подобный тому, который включен в Visual Studio, и я просматриваю каждый фрагмент состояния, отправляемый в GPU, чтобы выяснить, что пошло не так. Однако вначале это может быть сложно, когда вы не знаете точно, что делает каждый кусочек государства и каким он должен быть. Но, в конце концов, вы учитесь, и вам нужно угадать догадки, выясняя, что пошло не так.

Еще одна полезная вещь — включить режим отладки на вашем компьютере. ID3D11Device, Для этого установите Flags параметр D3D11CreateDevice или же D3D11CreateDeviceAndSwapChain (что вы используете), чтобы D3D11_CREATE_DEVICE_DEBUG, Это выдаст предупреждения, если что-то идет не так.

В конце концов вам захочется научиться пользоваться графическим отладчиком, но прежде чем вы подойдете к этому, я бы рекомендовал сначала попытаться точно следовать учебному руководству, а затем вернуться и изменить его по своему вкусу. С каждым значительным изменением запускайте программу, чтобы убедиться, что она все еще работает. Когда это не так, вы знаете, что пошло не так.

К вашей проблеме. Одна проблема, которую я вижу, заключается в том, что вы не объявили свой элемент цвета в макете ввода. Вам нужно будет добавить это после элемента позиции:

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }

В противном случае ваш шейдер не знает, где найти цвет в потоке вершин. Обратите внимание, что позиция также должна быть DXGI_FORMAT_R32G32B32_FLOAT как упоминалось в ответе Нарда. Без этих двух вещей, CreateInputLayout вернет нулевой входной макет, потому что он не соответствует входной сигнатуре вершинного шейдера.

Также убедитесь, что вы настраиваете область просмотра.

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

0

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

 cbuffer Transform
{
matrix mWorld;
matrix mView;
matrix mProjection;
}

затем в вершинном шейдере, сделайте это

output.position= mul(position, mWorld);
output.position= mul(output.position, mView);
output.position= mul(output.position, mProjection);

вам нужно создать для него буфер D3D11_BIND_CONSTANT_BUFFER и использовать ID3D11DeviceContext::VSSetConstantBuffers связать это.

ты можешь использовать #include <DirectXMath.h> для управления матрицей, например, используйте XMMatrixTranslation а также XMMatrixRotation чтобы изменить mWorld, используйте XMMatrixLookAtLH чтобы изменить mView, используйте XMMatrixPerspective изменить mProjection.

после того, как вы получите матрицу в памяти процессора, вам нужно использовать ID3D11DeviceContext::UpdateSubresource обновить данные в памяти gpu (постоянные буферы, которые вы создали выше). не забудьте сделать XMMatrixTranspose прежде чем пройти матрицу.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector