2014-10-19 187 views
3

我初始化了所有的Direct3D 11,但是当我绘制几何图形时几何图形不显示。Direct3D 11 - 绘制三角形

我已经创建了管线,几何图形并为要绘制的几何图形创建了绘图函数。我的主要问题是任何人都可以帮助我理解为什么三角形没有绘制在窗口中?

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; 
} 

链接到节目的PIC是在这里:http://i.imgur.com/JyNkPqQ.png

的呼叫在程序的执行正确地进行,但没有显示。 为防万一我的问题从顶部被遗忘,为什么三角形不显示?

我希望有人能帮助.. :)

+0

请注意,不推荐使用D3DX的所有版本。我建议你避免使用传统的D3DXMath库,而应该使用[DirectXMath](http://blogs.msdn.com/b/chuckw/archive/2012/03/27/introducing-directxmath.aspx)。您不需要使用D3DX11来编译着色器,因为您可以使用[D3DCompile](http://blogs.msdn.com/b/chuckw/archive/2012/05/07/hlsl-fxc-and-d3dcompile .aspx)直接。你也可以查看这个[Direct3D 11教程](https://code.msdn.microsoft.com/Direct3D-Tutorial-Win32-829979ef)。 – 2014-10-23 19:35:17

回答

2

我在DirectX11的无大师(其实我只是最近才开始),但它似乎是,即使你的顶点着色器将获得的一个D3DXVECTOR3顶点的位置,你告诉它POSITION

四种成分,32位无符号标准化整数支持每个信道包括α8位格式。

在您的输入布局。现在令人困惑!

您应该使用DXGI_FORMAT_R32G32B32_FLOAT

谢谢您的阅读。

+0

感谢您的回放,我将格式更改为DXGI_FORMAT_R32G32B32_FLOAT。 但仍然没有,但是,谢谢你,我会一直坚持下去,直到我取得成功。 – 2014-10-19 16:58:41

+0

没问题。编程图形时很难进行调试,因为您只知道它看起来是错误的,所以您必须确定自己在做什么(如数据类型和渲染管线)。 – Nard 2014-10-19 17:02:43

+0

我会承认我并没有完全按照我正在阅读的教程进行操作,而是按照我的方式做了些事情。我认为最好的做法是坚持这本书的信。 是的,gfx编程很难,我仍然无法获得与输出设备相关的显示模式列表。我到了那里寿。 :) – 2014-10-19 17:08:46

0

这可能不完全是答案,但希望它有帮助。有时很难说出为什么某些东西不仅仅是通过查看代码来绘制。可能有多种原因,有时他们可能会隐藏起来。

一般来说,当我遇到这个问题时,我加载了一个图形调试器,就像Visual Studio中包含的一个图形调试器一样,并且我会查看发送给GPU的每一个状态以找出错误。然而,当你不确切知道每个状态是什么以及它应该是什么时,这可能会很困难。但是,最终你会学习,并且需要通过猜测来弄清楚出了什么问题。

另一件通常有用的事情是在您的ID3D11Device上启用调试模式。为此,请将Flags参数D3D11CreateDeviceD3D11CreateDeviceAndSwapChain(无论您正在使用的)设置为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 } 

否则,着色器不知道在哪里找到顶点流中的颜色。注意Nard的答案中提到的位置也必须是DXGI_FORMAT_R32G32B32_FLOAT。没有这两件事,CreateInputLayout将返回空输入布局,因为它不匹配顶点着色器的输入签名。

另外请确保您正在设置视口。

可能还有其他问题,但是如果没有看到每个API调用都可能很难说清楚。

+0

谢谢,我已经使用了调试宏,但我没有看到足够的输出窗口..图形调试你的意思是dxdiag?或者有什么我可以使用作为即时通讯使用莫名其妙lol – 2014-10-26 05:51:02

+0

您是否尝试添加像我提到的输入布局的颜色元素和设置视口?图形调试器是Visual Studio中Debug-> Graphics-> Start Diagnostics下的一个功能。它可以让你捕捉一个帧,然后分析D3D状态。它在Pro版本中,但我不确定它是否在免费的Express版本中。 – megadan 2014-10-27 04:23:22

+0

是的,我添加了它,我也跟着教程确切的信。它是一个谜。我设置了D3D11_APPEND_ALIGNED_ELEMENT,它已经设置了调试,我下载了图形调试器的免费试用版,但仍然没有任何运气。 明天我会把所有的几何数据和管道重新启动,并希望最好的,因为我真的把很多这个小项目。 – 2014-10-28 03:44:28

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>控制矩阵,例如,使用XMMatrixTranslationXMMatrixRotation改变mWorld,使用XMMatrixLookAtLH改变MView的,使用XMMatrixPerspective改变mProjection。

在获得cpu内存的矩阵后,您需要使用ID3D11DeviceContext::UpdateSubresource将数据更新为gpu内存(上面创建的常量缓冲区)。记得在通过矩阵之前做XMMatrixTranspose