Directx10,实例化渲染,顶点缓冲区输入
Directx10, instanced rendering, vertex buffer input
因此,我尝试在DirectX10中使用一个简单的着色器进行硬件实例化,其中顶点结构为顶点获取位置、纹理坐标和法线,并为实例获取模型矩阵。创建将数据发送到着色器中的模型矩阵的输入布局时出现问题。使用PIX进行调试表明,矩阵只得到无意义的值。
相关代码:
输入布局
m_Tech = m_Effect->GetTechniqueByName("SimpleTech");
//Position-normal-texture vertex
D3D10_INPUT_ELEMENT_DESC posNormalTexVertexDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"mTransform", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1}
};
D3D10_PASS_DESC PassDesc;
m_Effect->GetTechniqueByName("SimpleTech")->GetPassByIndex(0)->GetDesc(&PassDesc);
HR(mp_D3DDevice->CreateInputLayout(posNormalTexVertexDesc, 7, PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize, &m_InputLayout));
着色器结构
struct VS_IN
{
float4 Pos : POSITION;
float2 TexCoord : TEXCOORD0;
float4 Normal : NORMAL;
row_major float4x4 mTransform : mTransform;
};
缓冲
void Model::BuildVertexBuffer()
{
D3D10_BUFFER_DESC vbd;
vbd.Usage = D3D10_USAGE_DEFAULT;
vbd.ByteWidth = sizeof(MeshVertex) * (UINT)m_Mesh->VertexCount();
vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = m_Mesh->VertexData();
m_D3DDevice->CreateBuffer(&vbd, &vinitData, &m_VertexBuffer);
}
void Model::BuildInstanceBuffer()
{
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(D3DXMATRIX) * (UINT)m_instanceData->size();
ibd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &m_instanceData[0];
m_D3DDevice->CreateBuffer(&ibd, &vinitData, &m_InstanceBuffer);
}
提取调用
void Model::Draw(Camera& camera)
{
UINT strides[2];
UINT offsets[2];
ID3D10Buffer* bufferPointers[2];
//Set buffer strides
strides[0] = sizeof(MeshVertex);
strides[1] = sizeof(D3DXMATRIX);
//Set buffer offsets
offsets[0] = 0;
offsets[1] = 0;
//Set the array of pointers to the vertex and instance buffers
bufferPointers[0] = m_VertexBuffer;
bufferPointers[1] = m_InstanceBuffer;
//Set the vertex and instance buffers to active in the input assembler so it may be rendered
m_D3DDevice->IASetVertexBuffers(0,2,bufferPointers, strides, offsets);
m_D3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Set input layout
m_D3DDevice->IASetInputLayout(m_Effect->GetLayout());
//Set
m_Effect->SetResources(camera, NULL);
D3D10_TECHNIQUE_DESC techDesc;
ID3D10EffectTechnique* tech = m_Effect->GetTech();
tech->GetDesc( &techDesc );
for(UINT i = 0; i < techDesc.Passes; ++i)
{
ID3D10EffectPass* pass = tech->GetPassByIndex(i);
pass->Apply(0);
m_D3DDevice->DrawInstanced(m_Mesh->VertexCount(), m_instanceData->size(),0,0);
}
}
m_instanceData是一个向量,它为每个实例保存一个D3DXMIX。看过SDK附带的示例吗?我们的输入布局看起来似乎是一样的,但矩阵没有正确传输?
我目前只是发送一个身份矩阵作为测试目的的模型矩阵,但它显示的是完全不同的东西。我已经检查过,以便在初始化实例缓冲区时,数据确实在向量中。
第1版:已将BuildInstanceBuffer()方法更改为
void Model::BuildInstanceBuffer()
{
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(D3DXMATRIX) * (UINT)m_instanceData->size();
ibd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &m_instanceData[0];
m_D3DDevice->CreateBuffer(&ibd, &vinitData, &m_InstanceBuffer);
D3DXMATRIX* pMatrices = NULL;
m_InstanceBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, ( void** )&pMatrices );
memcpy( pMatrices, m_InstanceBuffer, m_instanceData->size() * sizeof( D3DXMATRIX ) );
m_InstanceBuffer->Unmap();
}
第二次编辑:我想这有点早熟。似乎我在着色器中的模型矩阵被"正确"填充,因为每一行都在正确的点上获得一个值。但这个值仍然不是我传递的值
老实说,这一点一分钟比一分钟陌生。当我在visualstudio中调试程序时,我得到了一个绿色网格。在PIX中,它显示为黑色。我真的需要帮助,我不知道现在发生了什么。
我想最好迟到,以防其他人偶然发现这个问题。将BuildInstanceBuffer更改为:
void Model::BuildInstanceBuffer()
{
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(D3DXMATRIX) * (UINT)m_instanceData->size();
ibd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
m_D3DDevice->CreateBuffer(&ibd, NULL, &m_InstanceBuffer);
D3DXMATRIX* pMatrices = NULL;
m_InstanceBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, ( void** )&pMatrices );
memcpy( pMatrices, m_instanceData->data(), m_instanceData->size() * sizeof( D3DXMATRIX ) );
m_InstanceBuffer->Unmap();
}
基本上,从那时起就是小菜一碟。
相关文章:
- 套接字读取后,我在缓冲区中看到意外输入
- 清除输入缓冲区后未提取字符串流
- 快速读取标准输入缓冲区,无需检查
- C++ 为什么还剩下输入缓冲区?
- C++ - 有什么方法可以将输入插入缓冲区/停止 cin.忽略需要输入?
- 如果输入缓冲区不为空,请使用getchar.()检测Ctrl+d
- 如果我在 C++ 中为 int 提供双精度,输入缓冲区中存储了什么?
- 有没有办法将两个输入图像堆叠到卤化物发生器中的单个 4 维缓冲区中?
- 用于了解输入和输出流缓冲区实际工作方式的程序
- 如何重复使用原始输入缓冲区内存?
- 从输入缓冲区读取
- 如果用户输入两个或多个由空格分隔的字符串C++如何防止缓冲区溢出?
- 多线程使用者未产生与使用升压环形缓冲区的输入相同的输出
- 从超强的AndroidAudioIO输入读取缓冲区
- 安全操作以清除C++中的空输入缓冲区
- 如何检查输入缓冲区是否为空
- 我可以做一个循环,直到“std::cin”在输入缓冲区中看到“”字符
- 从gstreamer缓冲区创建输入张量
- 从缓冲区输入的位
- Directx10,实例化渲染,顶点缓冲区输入