2012-02-02 79 views
0

所以,我试图在DirectX10中使用简单着色器进行硬件实例化,其中顶点结构为顶点和实例的顶点和模型矩阵提供位置,纹理坐标和法线。问题在于创建将数据发送到着色器中的模型矩阵的输入布局。用PIX进行调试表明,该矩阵只能得到无意义的值。DirectX10,实例渲染,顶点缓冲区输入

相关代码:

输入布局

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

的Shader结构

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是为每个实例保存D3DXMATRIX的向量。看过SDK附带的例子,我们的输入布局似乎看起来是一样的,但矩阵没有正确传输?

我目前只是发送一个标识矩阵作为测试用途的模型矩阵,但它显示为完全不同的东西。我已经检查过,确保一旦我初始化实例缓冲区后,数据就在向量中。

EDIT1: 改变了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(); 

} 

第二编辑:想这是一个比特的预成熟。似乎在着色器中我的模型矩阵正在被“正确”填充,因为每一行都在正确的位置得到了一个值。但是,这个价值仍然不是我通过的价值。

这真诚地在一分钟内变得陌生。当我在Visual Studio中调试程序时,我会看到绿色的网格。在PIX中,它显示为黑色。我真的可以使用这个帮助,我不知道现在发生了什么。

+0

那么什么值在GPU上的实例缓冲区(使用PIX检查它)?另外,网格是否正确渲染?你说它被渲染成绿色,而PIX是黑色的?你可以张贴一些截图吗? – 2012-02-03 12:48:20

回答

0

更晚的时候,我再也猜不到,万一有人在这个问题上发愁。 更改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(); 
} 

基本上,从那里一块蛋糕。