我正在创建一个游戏引擎,并且我想要绘制线框形状以进行调试(碰撞器、触发器、光线投射等)。我以前使用带有线框光栅化器状态的网格,但现在我想使用它们的 PrimitiveBatch 类将系统迁移到DirectXTK 的示例,以便我可以绘制光线。
但是,当我调用批处理的 DrawIndexed() 方法时遇到了一个问题,在该方法中,我绘制该框架的所有内容,包括来自 ID3D11DeviceContext 的 DrawIndexed() 的对象,都变成了线框。
我的调试绘图方法:
void Renderer::DrawDebugShapes(ID3D11DeviceContext* context, Camera* camera, float deltaTime)
{
if (debugObjs[0].size() < 1 && debugObjs[1].size() < 1 && debugObjs[2].size() < 1
&& debugObjs[3].size() < 1)
return;
db_effect->SetView(XMLoadFloat4x4(&camera->GetViewMatrix()));
db_effect->SetProjection(XMLoadFloat4x4(&camera->GetProjectionMatrix()));
context->OMSetBlendState(db_states->Opaque(), nullptr, 0xFFFFFFFF);
context->OMSetDepthStencilState(db_states->DepthNone(), 0);
context->RSSetState(db_states->CullNone());
db_effect->Apply(context);
context->IASetInputLayout(db_inputLayout.Get());
db_batch->Begin();
//Loop through all debug objs
//0 = cubes, 1 = spheres, 2 = cylinders, 3 = rays
for (short i = 0; i < 4; i++)
{
if (debugObjs[i].size() > 0)
{
for (auto iter = debugObjs[i].end() - 1; iter > debugObjs[i].begin(); iter--)
{
switch (i)
{
case 0:
DrawShape(db_batch.get(), iter->world);
break;
case 1:
//Draw sphere
break;
case 2:
//Draw capsule
break;
case 3:
//Draw rays
break;
default: break;
}
if (iter->type == DebugDrawType::ForDuration)
iter->duration -= deltaTime;
//Erase objs that need to be
if (iter->type == DebugDrawType::SingleFrame ||
(iter->type == DebugDrawType::ForDuration && iter->duration <= 0))
iter = debugObjs[i].erase(iter);
}
}
}
db_batch->End();
context->RSSetState(0);
context->OMSetDepthStencilState(0, 0);
context->OMSetBlendState(0, 0, 0xFFFFFFFF);
context->IASetInputLayout(0);
}
可以将案例 0 中的 DrawShape() 调用注释掉以消除问题。我的正常渲染是基本的网格前向渲染,对每个对象调用 context->DrawIndexed() 并在绘制所有内容(包括调试形状)后调用 swapChain->Present(0,0)。我尝试将调试图移到交换链之后,但这并没有解决它。
DrawShape() 只是将世界矩阵发送到使用原始批处理(来自 DirectXTK wiki)绘制立方体的函数:
inline void XM_CALLCONV DrawCube(PrimitiveBatch<VertexPositionColor>* batch,
CXMMATRIX matWorld,
FXMVECTOR color)
{
static const XMVECTORF32 s_verts[8] =
{
{ -1.f, -1.f, -1.f, 0.f },
{ 1.f, -1.f, -1.f, 0.f },
{ 1.f, -1.f, 1.f, 0.f },
{ -1.f, -1.f, 1.f, 0.f },
{ -1.f, 1.f, -1.f, 0.f },
{ 1.f, 1.f, -1.f, 0.f },
{ 1.f, 1.f, 1.f, 0.f },
{ -1.f, 1.f, 1.f, 0.f }
};
static const WORD s_indices[] =
{
0, 1,
1, 2,
2, 3,
3, 0,
4, 5,
5, 6,
6, 7,
7, 4,
0, 4,
1, 5,
2, 6,
3, 7
};
VertexPositionColor verts[8];
for (size_t i = 0; i < 8; ++i)
{
XMVECTOR v = XMVector3Transform(s_verts[i], matWorld);
XMStoreFloat3(&verts[i].position, v);
XMStoreFloat4(&verts[i].color, color);
}
batch->DrawIndexed(D3D_PRIMITIVE_TOPOLOGY_LINELIST, s_indices, _countof(s_indices), verts, 8);
}
我也尝试在调试绘图完成后重置状态无济于事。有没有人有任何想法?