c++ - 关于directx11中读取obj文件的问题
黄舟
黄舟 2017-04-17 13:12:05
0
1
682

问题已经解决,感谢@vczh 的帮助,最后锁定问题.原来是因为obj的索引 a/b/c 分别代表相应的pos、texture、normal。


原始问题在下方


有两个文件:
1.cube.obj: http://pan.baidu.com/s/1dEvjwnn
2.MianJu_2.obj: http://pan.baidu.com/s/1jHuZk9o

写了一个类将obj读取并转换。

1.顶点信息为Vector<VertexPos>:
struct VertexPos
{
    XMFLOAT3 pos;    
    XMFLOAT2 tex0;
    XMFLOAT3 nor;
};
2.索引信息为Vector<WORD>

读取之后,在绘制过程出现问题,第一个相对规模小的cube绘制成功:

但是另一个文件(一个面具的建模)却什么都显示:

请大家帮看看是哪里出了问题?

D3D部分代码:

HLSL:


Texture2D colorMap : register( t0 );
Texture2D secondMap : register(t1);
SamplerState colorSampler : register( s0 );
vector colorCube : register(t2);


cbuffer cbChangesEveryFrame : register( b0 )
{
    matrix worldMatrix;
};

cbuffer cbNeverChanges : register( b1 )
{
    matrix viewMatrix;
};

cbuffer cbChangeOnResize : register( b2 )
{
    matrix projMatrix;
};

cbuffer cbChangeRotationMatrix : register(b3)
{
    matrix rotationMatrix;
};


struct VS_Input
{
    float4 pos  : POSITION;
    float2 tex0 : TEXCOORD0;
    float3 nor  :  NORMAL;
};

struct PS_Input
{
    float4 pos  : SV_POSITION;
    float4 temp : POSITION;
    float2 tex0 : TEXCOORD0;
    float3 nor  : NORMAL;
};


PS_Input VS_Main( VS_Input vertex )
{
    PS_Input vsOut = ( PS_Input )0;

    //变换为世界坐标系
    vsOut.pos = mul(vertex.pos, rotationMatrix);
    vsOut.pos = mul(vsOut.pos, worldMatrix);
    vsOut.pos = mul( vsOut.pos, viewMatrix );
    vsOut.pos = mul( vsOut.pos, projMatrix );
   
    vsOut.tex0 = vertex.tex0;
    vsOut.nor = vertex.nor;

    return vsOut;
}


float4 PS_Main( PS_Input frag ) : SV_TARGET
{
    float4 col = colorMap.Sample(colorSampler, frag.tex0);
    float4 col2 = secondMap.Sample(colorSampler, frag.tex0);

    if(col.x - 0.0f < 0.035f)
    {
    }
    else
    {
        col.x = colorCube.x;
        col.y = colorCube.y;
        col.z = colorCube.z;
    }

    return col * col2;
}


technique11 ColorInversion
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_5_0, VS_Main() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_5_0, PS_Main() ) );
    }
}

Render:

void Cube::Render()
{
    if (d3dContext_ == 0)
        return;

    //清屏
    float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
    d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);

    //新增
    d3dContext_->ClearDepthStencilView(depthStencilView_, D3D11_CLEAR_DEPTH, 1.0f, 0);

    unsigned int stride = sizeof(NinoObj::VertexPos);
    unsigned int offset = 0;


    d3dContext_->IASetInputLayout(inputLayout_);
    d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &stride, &offset);
    d3dContext_->IASetIndexBuffer(indexBuffer_, DXGI_FORMAT_R16_UINT, 0);
    d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    XMMATRIX rotationMat = XMMatrixRotationRollPitchYaw(0.0f, 0.0f, 0.0f);
    XMMATRIX translationMat = XMMatrixTranslation(0.0f, 0.0f, 6.0f);
    XMMATRIX worldMat = rotationMat * translationMat;

    //更改effect内的外部变量

    ID3DX11EffectShaderResourceVariable* colorMap;
    colorMap = effect_->GetVariableByName("colorMap")->AsShaderResource();
    colorMap->SetResource(colorMap_);

    ID3DX11EffectShaderResourceVariable* secondMap;
    secondMap = effect_->GetVariableByName("secondMap")->AsShaderResource();
    secondMap->SetResource(secondMap_);

    ID3DX11EffectSamplerVariable* colorMapSampler;
    colorMapSampler = effect_->GetVariableByName("colorSampler")->AsSampler();
    colorMapSampler->SetSampler(0, colorMapSampler_);

    ID3DX11EffectMatrixVariable* worldMatrix;
    worldMatrix = effect_->GetVariableByName("worldMatrix")->AsMatrix();
    worldMatrix->SetMatrix((float*)&worldMat);

    ID3DX11EffectMatrixVariable* viewMatrix;
    viewMatrix = effect_->GetVariableByName("viewMatrix")->AsMatrix();
    viewMatrix->SetMatrix((float*)&viewMatrix_);

    ID3DX11EffectMatrixVariable* projMatrix;
    projMatrix = effect_->GetVariableByName("projMatrix")->AsMatrix();
    projMatrix->SetMatrix((float*)&projMatrix_);

    auto *rotationMatrix = effect_->GetVariableByName("rotationMatrix")->AsMatrix();
    rotationMatrix->SetMatrix((float*)&rotationMatrix_);

    ID3DX11EffectTechnique* colorInvTechnique;
    colorInvTechnique = effect_->GetTechniqueByName("ColorInversion");

    D3DX11_TECHNIQUE_DESC techDesc;
    colorInvTechnique->GetDesc(&techDesc);

    for (unsigned int p = 0; p < techDesc.Passes; p++)
    {
        ID3DX11EffectPass* pass = colorInvTechnique->GetPassByIndex(p);

        if (pass != 0)
        {
            pass->Apply(0, d3dContext_);
            d3dContext_->DrawIndexed(indices_.size(), 0, 0);
        }
    }

    //更改颜色

    auto* colorTemp = effect_->GetVariableByName("colorCube")->AsVector();
    colorTemp->SetFloatVector(colorArray_);

    swapChain_->Present(0, 0);
}

LoadContent:

bool Cube::LoadContent()
{
    /*************************Effect******************************/

    ID3DBlob* vsBuffer = 0;

    //创建effect对象
    if (CompileD3DShader(L"ColorInversion.fx", 0, "fx_5_0", &vsBuffer) == false)
    {
        MessageBox(0, "Error compile the effect shader!", "Compile Error", MB_OK);
    }
    if (FAILED(D3DX11CreateEffectFromMemory(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, d3dDevice_, &effect_)))
    {
        MessageBox(0, "Error Create the effect shader!", "Create Error", MB_OK);

        if (vsBuffer)
            vsBuffer->Release();
        return false;
    }

    /*************************顶点布局******************************/

    D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },    //位置
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },        //纹理
        { "NORMAL" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0  }    //法线
    };

    unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout);

    ID3DX11EffectTechnique* colorInvTechnique;
    colorInvTechnique = effect_->GetTechniqueByName("ColorInversion");
    ID3DX11EffectPass* effectPass = colorInvTechnique->GetPassByIndex(0);

    D3DX11_PASS_SHADER_DESC passDesc;
    D3DX11_EFFECT_SHADER_DESC shaderDesc;
    effectPass->GetVertexShaderDesc(&passDesc);
    passDesc.pShaderVariable->GetShaderDesc(passDesc.ShaderIndex, &shaderDesc);

    if (FAILED(d3dDevice_->CreateInputLayout(solidColorLayout, totalLayoutElements,
        shaderDesc.pBytecode, shaderDesc.BytecodeLength, &inputLayout_)))
    {
        MessageBox(0, "Error Create the input layout!", "Create Error", MB_OK);
        return false;
    }

    vsBuffer->Release();

    /*************************顶点部分******************************/

    NinoObj ninoObj;

    ninoObj.CreateVertexAndIndex("MianJu_2.obj", vertices_, indices_);

    auto vertexVector = vertices_.GetVector();

    D3D11_BUFFER_DESC vertexDesc;
    ZeroMemory(&vertexDesc, sizeof(vertexDesc));
    vertexDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexDesc.ByteWidth = sizeof(NinoObj::VertexPos) * vertexVector.size();

    D3D11_SUBRESOURCE_DATA resourceData;
    ZeroMemory(&resourceData, sizeof(resourceData));
    resourceData.pSysMem = &vertexVector[0];

    if (FAILED(d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, &vertexBuffer_)))
    {
        MessageBox(0, "Failed to create vertex buffer!", "Create Error", MB_OK);
        return false;
    }

    /*************************索引部分******************************/

    D3D11_BUFFER_DESC indexDesc;
    ZeroMemory(&indexDesc, sizeof(indexDesc));
    indexDesc.Usage = D3D11_USAGE_DEFAULT;
    indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    indexDesc.ByteWidth = sizeof(WORD) * indices_.size();
    indexDesc.CPUAccessFlags = 0;

    resourceData.pSysMem = &(indices_[0]);

    if (FAILED(d3dDevice_->CreateBuffer(&indexDesc, &resourceData, &indexBuffer_)))
    {
        MessageBox(0, "Failed to create index buffer!", "Create Error", MB_OK);
        return false;
    }

    //读取图片文件
    if (FAILED(CreateDDSTextureFromFile(d3dDevice_, L"magic.dds", nullptr, &colorMap_)))
    {
        MessageBox(0, "Failed to load the texture image!!", "Load Error", MB_OK);
        return false;
    }

    //读取图片文件
    if (FAILED(CreateDDSTextureFromFile(d3dDevice_, L"demo.dds", nullptr, &secondMap_)))
    {
        MessageBox(0, "Failed to load the texture image!!", "Load Error", MB_OK);
        return false;
    }

    D3D11_SAMPLER_DESC colorMapDesc;
    ZeroMemory(&colorMapDesc, sizeof(colorMapDesc));
    colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;

    if (FAILED(d3dDevice_->CreateSamplerState(&colorMapDesc, &colorMapSampler_)))
    {
        MessageBox(0, "Failed to create color map sampler state!", "Load Error", MB_OK);
        return false;
    }

    viewMatrix_ = XMMatrixIdentity();
    projMatrix_ = XMMatrixPerspectiveFovLH(XM_PIp4, 800.0f / 600.0f, 0.01f, 100.0f);

    rotationMatrix_ = GetRotationMartix(NinoVector3<float>(1.0f, 0.0f, 0.0f), 0.00f);

    return true;
}
黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

reply all(1)
黄舟

According to my experience, it’s probably because your coordinate system is out of whack. Because your first model can be displayed, there is little chance of something going wrong with the code. I don’t want to read it if it’s too long. I have encountered such a problem before. After debugging, I found out that it was because the coordinate system of the model was different from what I imagined, so the camera was not aligned at all.

I think you should calculate a bounding box yourself after loading the model, then cover it with a ball, get the center and radius of the ball, and output them. Then you write code to align it and adjust the distance. It's easy to align and fully display a ball. So you can see the model.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template