为什么DirectX跳过每秒钟的着色器调用
Why is DirectX skipping every second shader call?
我有点沮丧,试图找出为什么我必须调用DirectX 11着色器两次看到所需的结果。
这是我的当前状态:我有一个由顶点和索引缓冲区构建的3d对象。然后这个对象被实例化几次。稍后,将会有更多的对象,但现在,我只使用这个对象进行测试。在我的渲染例程中,我迭代所有实例,改变世界矩阵(以便所有对象实例放在一起并形成"一个大的,完整的对象"),并调用shader方法将数据渲染到屏幕上。
这是目前为止的代码,它不起作用:
m_pLevel->Simulate(0.1f);
std::list<CLevelElementInstance*>& lst = m_pLevel->GetInstances();
float x = -(*lst.begin())->GetPosition().x, y = -(*lst.begin())->GetPosition().y, z = -(*lst.begin())->GetPosition().z;
int i = 0;
for (std::list<CLevelElementInstance*>::iterator it = lst.begin(); it != lst.end(); it++)
{
// Extract base element from current instance
CLevelElement* elem = (*it)->GetBaseElement();
// Write vertex and index buffer to video memory
elem->Render(m_pDirect3D->GetDeviceContext());
// Call shader
m_pTextureShader->Render(m_pDirect3D->GetDeviceContext(), elem->GetIndexCount(), XMMatrixTranslation(x, y, z + (i * 8)), viewMatrix, projectionMatrix, elem->GetTexture());
++i;
}
我的std::list
由4个3d物体组成,它们都是相同的。它们只是在三维空间中的位置不同。所有的对象都是8.0 × 8.0 × 8.0,为了简单起见,我把它们排成一行。(可以在着色器渲染线上看到,我只是在Z维度上添加了8个单位)
结果如下:我只看到两个元素呈现在屏幕上。在它们之间,有一个元素大小的空白空间。一开始,我认为我在3d数学上犯了一些错误,但经过大量的时间调试我的代码,我没有发现任何错误。
现在是令人困惑的部分:如果我改变for循环的内容并添加对着色器的另一个调用,我就会突然看到所有四个元素;它们都在3d空间中的正确位置:
m_pLevel->Simulate(0.1f);
std::list<CLevelElementInstance*>& lst = m_pLevel->GetInstances();
float x = -(*lst.begin())->GetPosition().x, y = -(*lst.begin())->GetPosition().y, z = -(*lst.begin())->GetPosition().z;
int i = 0;
for (std::list<CLevelElementInstance*>::iterator it = lst.begin(); it != lst.end(); it++)
{
// Extract base element from current instance
CLevelElement* elem = (*it)->GetBaseElement();
// Write vertex and index buffer to video memory
elem->Render(m_pDirect3D->GetDeviceContext());
// Call shader
m_pTextureShader->Render(m_pDirect3D->GetDeviceContext(), elem->GetIndexCount(), XMMatrixTranslation(x, y, z + (i * 8)), viewMatrix, projectionMatrix, elem->GetTexture());
// Call shader a second time - this seems to have no effect but to allow the next iteration to perform it's shader rendering...
m_pTextureShader->Render(m_pDirect3D->GetDeviceContext(), elem->GetIndexCount(), XMMatrixTranslation(x, y, z + (i * 8)), viewMatrix, projectionMatrix, elem->GetTexture());
++i;
}
有人知道这里发生了什么吗?
如果有帮助,这里是着色器的代码:
bool CTextureShader::Render(ID3D11DeviceContext* _pDeviceContext, const int _IndexCount, XMMATRIX& _pWorldMatrix, XMMATRIX& _pViewMatrix, XMMATRIX& _pProjectionMatrix, ID3D11ShaderResourceView* _pTexture)
{
bool result = SetShaderParameters(_pDeviceContext, _pWorldMatrix, _pViewMatrix, _pProjectionMatrix, _pTexture);
if (!result)
return false;
RenderShader(_pDeviceContext, _IndexCount);
return true;
}
bool CTextureShader::SetShaderParameters(ID3D11DeviceContext* _pDeviceContext, XMMATRIX& _WorldMatrix, XMMATRIX& _ViewMatrix, XMMATRIX& _ProjectionMatrix, ID3D11ShaderResourceView* _pTexture)
{
HRESULT result;
D3D11_MAPPED_SUBRESOURCE mappedResource;
MatrixBufferType* dataPtr;
unsigned int bufferNumber;
_WorldMatrix = XMMatrixTranspose(_WorldMatrix);
_ViewMatrix = XMMatrixTranspose(_ViewMatrix);
_ProjectionMatrix = XMMatrixTranspose(_ProjectionMatrix);
result = _pDeviceContext->Map(m_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
return false;
dataPtr = (MatrixBufferType*)mappedResource.pData;
dataPtr->world = _WorldMatrix;
dataPtr->view = _ViewMatrix;
dataPtr->projection = _ProjectionMatrix;
_pDeviceContext->Unmap(m_pMatrixBuffer, 0);
bufferNumber = 0;
_pDeviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_pMatrixBuffer);
_pDeviceContext->PSSetShaderResources(0, 1, &_pTexture);
return true;
}
void CTextureShader::RenderShader(ID3D11DeviceContext* _pDeviceContext, const int _IndexCount)
{
_pDeviceContext->IASetInputLayout(m_pLayout);
_pDeviceContext->VSSetShader(m_pVertexShader, NULL, 0);
_pDeviceContext->PSSetShader(m_pPixelShader, NULL, 0);
_pDeviceContext->PSSetSamplers(0, 1, &m_pSampleState);
_pDeviceContext->DrawIndexed(_IndexCount, 0, 0);
}
如果有帮助的话,我也可以在这里发布着色器的代码。
任何帮助将不胜感激-我完全被困在这里:-(
问题是你每一帧都在转换你的数据,所以它每隔一帧才"正确":
_WorldMatrix = XMMatrixTranspose(_WorldMatrix);
_ViewMatrix = XMMatrixTranspose(_ViewMatrix);
_ProjectionMatrix = XMMatrixTranspose(_ProjectionMatrix);
相反,你应该这样做:
XMMATRIX worldMatrix = XMMatrixTranspose(_WorldMatrix);
XMMATRIX viewMatrix = XMMatrixTranspose(_ViewMatrix);
XMMATRIX projectionMatrix = XMMatrixTranspose(_ProjectionMatrix);
result = _pDeviceContext->Map(m_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
return false;
dataPtr = (MatrixBufferType*)mappedResource.pData;
dataPtr->world = worldMatrix;
dataPtr->view = viewMatrix;
dataPtr->projection = projectionMatrix;
_pDeviceContext->Unmap(m_pMatrixBuffer, 0);
我想知道的问题是,临时创建的调用XMMatrixTranslation(x, y, z + (I * 8))正在通过引用传递到一个函数,然后通过引用传递到另一个函数,在那里它被修改。
我对c++规范的了解还不够完整,无法判断这是否是未定义行为(但我知道这方面有一些棘手的规则——例如,不支持将临时对象赋值给非const临时对象)。无论如何,它接近于怀疑,即使它是定义良好的c++,它仍然可能是一个尘土飞扬的角落,可能会绊倒不兼容的编译器。
要排除这种可能性,试着这样做:
XMMatrix worldMatrix = XMMatrixTranslation(x, y, z + (i * 8));
m_pTextureShader->Render(m_pDirect3D->GetDeviceContext(), elem->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, elem->GetTexture());
- C++每 x 秒调用一次函数
- 每 1 秒(准确地)调用一个函数
- 为什么除了最后一帧之外,每一帧都没有调用命令
- 调用每种类型的变异模板的正确模板专业化
- Cocos2dx 如何在没有调度选择器的情况下每 5 秒调用一次函数
- 每60秒钟C 草图每60秒采取电压
- 如何每秒调用更新Qt小部件的函数
- 每隔几秒钟移动一次对象
- C++ 每 5 分钟调用一次函数
- 我的函数返回的是打印到控制台,它只会在我调用它时每隔一段时间C++
- gsoap 在我调用的每一秒都会对我的应用程序(用 C 编写)进行分段错误
- 随着时间的推移,每几秒钟喷一次精灵SFML C++
- 如何使用 QT 每 15 秒调用一次函数
- 奇怪的行为 printf( ) 每行调用 10-13 次
- 每帧的性能函数调用
- WinSock closesocket() 调用在某些计算机上需要一秒钟
- 二维数组每秒钟两行c++
- 我有一个C++2d数组,我必须调用函数.它只对每5个位置进行平均,例如[0][0]+[5][0]这看起来是否正确,或者有
- 为什么DirectX跳过每秒钟的着色器调用
- Std::ostream,为每行调用一个回调