关于directx11中读取obj文件的问题

问题已经解决,感谢@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_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f);

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

return true;

}

回答:

根据我的经验,多半是你的坐标系统已经飞了。因为你第一个模型能显示,所以代码出问题的概率不大,太长我也不想看。我以前也遇到这样的问题,调试到最后发现,竟然是因为模型的坐标系和我想象的不一样,于是摄像机根本就没有对准。

我认为你应该在load完模型之后,自己算一个包围盒,再用一个球来覆盖他,得到球心和半径两个值,输出出来。然后你写代码对准他并调整好距离,对准并完全显示一个球是很容易的。这样你就能看到模型了。

以上是 关于directx11中读取obj文件的问题 的全部内容, 来源链接: utcz.com/p/190999.html

回到顶部