问题已经解决,感谢@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;
}
根據我的經驗,多半是你的座標系統已經飛了。因為你第一個模型可以顯示,所以程式碼出問題的機率不大,太長我也不想看。我以前也遇到這樣的問題,調試到最後發現,竟然是因為模型的座標系和我想像的不一樣,於是攝影機根本就沒有對準。
我認為你應該在load完模型之後,自己算一個包圍盒,再用一個球來覆蓋他,得到球心和半徑兩個值,輸出出來。然後你寫程式碼對準他並調整好距離,對準並完全顯示一個球是很容易的。這樣你就能看到模型了。