问题描述
问题已经解决,感谢@vczh 的帮助,最后锁定问题.原来是因为obj的索引 a/b/c 分别代表相应的pos、texture、normal。
原始问题在下方
有两个文件:1.cube.obj: http://pan.baidu.com/s/1dEvjwnn2.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;}
问题解答
回答1:根据我的经验,多半是你的坐标系统已经飞了。因为你第一个模型能显示,所以代码出问题的概率不大,太长我也不想看。我以前也遇到这样的问题,调试到最后发现,竟然是因为模型的坐标系和我想象的不一样,于是摄像机根本就没有对准。
我认为你应该在load完模型之后,自己算一个包围盒,再用一个球来覆盖他,得到球心和半径两个值,输出出来。然后你写代码对准他并调整好距离,对准并完全显示一个球是很容易的。这样你就能看到模型了。