如何手动渲染使用DirectX工具包加载的网格

如何手动渲染使用DirectX工具包加载的网格,directx,shader,directx-11,c++-cx,directxtk,Directx,Shader,Directx 11,C++ Cx,Directxtk,我有一个c++/cx项目,我正在使用DirectX-11渲染程序网格,看起来一切都很好,但现在我还想从文件(确切地说是从fbx)导入和渲染网格。 我被告知要为此使用DirectX工具包 我学习了工具箱的教程,所有这些都很有效, 但后来我尝试在我的项目中这样做,但似乎不起作用。导入的网格不可见,并且现有程序网格渲染不正确(好像没有深度缓冲区) 然后,我尝试手动渲染导入的网格(与程序网格相同,不使用DirectXTK的Draw函数) 这样效果更好,现有网格都是正确的,但导入的网格颜色是错误的;我使用

我有一个c++/cx项目,我正在使用DirectX-11渲染程序网格,看起来一切都很好,但现在我还想从文件(确切地说是从fbx)导入和渲染网格。 我被告知要为此使用DirectX工具包

我学习了工具箱的教程,所有这些都很有效, 但后来我尝试在我的项目中这样做,但似乎不起作用。导入的网格不可见,并且现有程序网格渲染不正确(好像没有深度缓冲区)

然后,我尝试手动渲染导入的网格(与程序网格相同,不使用DirectXTK的Draw函数) 这样效果更好,现有网格都是正确的,但导入的网格颜色是错误的;我使用一个自定义的顶点和片段着色器,它只使用顶点位置和颜色数据,但出于某种原因,导入的网格法线将发送到着色器而不是顶点颜色

(我甚至不想将法线存储在网格中,但我似乎没有选项在没有法线的情况下导出到fbx,即使我手动将其从fbx中删除,在导入时DirectXTK似乎会重新计算法线)

有人知道我做错了什么吗? 这对我来说还是比较新的,所以非常感谢你的帮助。 如果你需要更多信息,请告诉我

以下是渲染网格的代码:

首先是主渲染函数(每次更新调用一次):

目前的职能是:

void Track3D::Present()
{
DXGI_PRESENT_PARAMETERS parameters = { 0 };
parameters.DirtyRectsCount = 0;
parameters.pDirtyRects = nullptr;
parameters.pScrollRect = nullptr;
parameters.pScrollOffset = nullptr;

HRESULT hr = S_OK;

hr = _swapChain->Present1(1, 0, &parameters);

if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
    OnDeviceLost();
}
else
{
    if (FAILED(hr))
    {
        throw Platform::Exception::CreateException(hr);
    }
}
}
下面是我在每个网格上调用的渲染函数: (所有特定于网格的数据都来自导入的网格)

这是顶点着色器:

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};

struct VertexShaderInput
{
float3 pos : POSITION;
//float3 normal : NORMAL0; //uncommenting these changes the color data for some reason (but always wrong)
//float2 uv1 : TEXCOORD0;
//float2 uv2 : TEXCOORD1;
float3 color : COLOR0;
};

struct VertexShaderOutput
{
float3 color : COLOR0;
float4 pos : SV_POSITION;
};

VertexShaderOutput main(VertexShaderInput input)
{
VertexShaderOutput output;
float4 pos = float4(input.pos, 1.0f);

// Transform the vertex position into projected space.
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;

output.color = input.color;

return output;
}
这是像素着色器:

struct PixelShaderInput
{
    float3 color: COLOR0;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    return float4(input.color.r, input.color.g, input.color.b, 1);
}

最可能的问题是您没有为图形设置足够的状态,并且DirectX工具包绘图函数正在设置与现有代码要求不匹配的状态

出于性能原因,DirectX工具包没有“保存和还原”状态。取而代之的是,每个draw函数都会完全设置它所需的状态,然后离开它。我在每个类的“状态管理”部分中记录了受影响的状态

上面的代码在插槽0中设置顶点缓冲区、索引缓冲区、输入布局、顶点着色器、像素着色器、基本体拓扑和VS常量缓冲区

您没有设置混合状态、深度/模具状态或光栅化器状态。您没有提供像素着色器,因此我不知道您是否需要任何PS常量缓冲区、采样器或着色器资源

在绘制程序网格之前,请尝试显式设置混合状态、深度/模具状态和光栅化器状态。如果您只想返回定义的默认值,而不是DirectX工具包所做的任何操作,请调用:

_d3dContext->RSSetState(nullptr);
_d3dContext->OMSetBlendState(nullptr, nullptr, 0);
_d3dContext->OMSetDepthStencilState(nullptr, 0xffffffff);
另请参见课程

在C++中使用从<>代码> 开始的标识符通常不是一个好主意。官方上,所有以
\ux
开头的标识符(其中X是大写字母或
\uux
)都是为编译器和库实现者保留的,因此它可能与某些编译器内容冲突
m
或类似的更好


谢谢你的回答,我试着添加了这些线,但是没有结果。我在问题中添加了更多的代码,主要是主渲染函数,我确实使用了ClearDepthStencilView()和OMSetRenderTargets(),这与设置SetDepthStencilState类似吗?我的代码是基于msdn和示例项目的,我花了一段时间才让它全部正常工作,我必须说,我并不完全理解它的全部内容,但我觉得奇怪的是,如果需要的话,它们也没有设置混合状态?另外,我没有使用DIrectXTK渲染导入的网格,我使用了我在问题中发布的Mesh:Render函数来渲染它。所以,如果这三行只将这些状态重置为默认状态,那么我不需要调用它们,因为它们从未更改过吗?
struct PixelShaderInput
{
    float3 color: COLOR0;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    return float4(input.color.r, input.color.g, input.color.b, 1);
}
_d3dContext->RSSetState(nullptr);
_d3dContext->OMSetBlendState(nullptr, nullptr, 0);
_d3dContext->OMSetDepthStencilState(nullptr, 0xffffffff);