首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Directx10,实例化渲染,顶点缓冲区输入

Directx10,实例化渲染,顶点缓冲区输入
EN

Stack Overflow用户
提问于 2012-02-03 01:06:43
回答 1查看 1.7K关注 0票数 0

所以,我试着用一个简单的着色器在DirectX10中做硬件实例化,其中顶点结构接受顶点的位置,纹理坐标和法线,以及实例的模型矩阵。问题是创建将数据发送到着色器中的模型矩阵的输入布局。使用PIX进行调试表明,该矩阵仅获得无意义的值。

相关代码:

输入布局

代码语言:javascript
复制
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));

着色器结构

代码语言:javascript
复制
struct VS_IN
{
    float4 Pos : POSITION;
    float2 TexCoord : TEXCOORD0;
    float4 Normal : NORMAL;
    row_major float4x4 mTransform : mTransform;
};

缓冲区

代码语言:javascript
复制
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);
}

绘制调用

代码语言:javascript
复制
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()方法更改为

代码语言:javascript
复制
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中,它显示为黑色。我真的需要你的帮助,我不知道现在发生了什么。

EN

回答 1

Stack Overflow用户

发布于 2012-03-02 01:11:47

我想,迟到总比永远不来好,以防其他人偶然发现这个问题。将BuildInstanceBuffer更改为:

代码语言:javascript
复制
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();
}

基本上,从那时起,小菜一碟。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9116608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档