在 DirectX11 中,对象未绘制

in directx11 object didn't draw

本文关键字:绘制 对象 DirectX11      更新时间:2023-10-16

我想用directx11显示。obj文件,所以我写了一些代码,当我尝试构建时,他们说没有什么特别的错误,但没有银上下文显示什么。我找不到哪里不对。这是我的全部代码。请给我一些建议。

这些代码是基于"Introduction to 3D game programming with directx 11 by Frank Luna"。d3dApp.h只是创建窗口代码。

也许,你会觉得这段代码太长了,我知道。我对此感到很抱歉,但我试图在绘图时减少无关代码。所以,请给我一些宽容,给我一些建议。请。

这是我的主代码

class Read_Pawn : public D3DApp
{
public:
Read_Pawn(HINSTANCE hInstance);
bool Init();
void DrawScene();
private:
XMFLOAT4X4 mView;
XMFLOAT4X4 mProj;
float mTheta;
float mPhi;
float mRadius;
POINT mLastMousePos;
Object Pawn;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
Read_Pawn Pawn(hInstance);
if (!Pawn.Init())
    return 0;
return Pawn.Run();
}
Read_Pawn::Read_Pawn(HINSTANCE hInstance)
: D3DApp(hInstance), mTheta(1.5f*MathHelper::Pi), mPhi(0.25f*MathHelper::Pi), mRadius(5.0f), Pawn("Pawn")
{
mMainWndCaption = L"Pawn Read";
mLastMousePos.x = 0;
mLastMousePos.y = 0;
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I);
}
bool Read_Pawn::Init()
{
if (!D3DApp::Init())
    return false;
Effects::InitAll(md3dDevice);
Pawn.Init(md3dDevice);
Pawn.Create(md3dDevice, "pawn.obj");
return true;
}
void Read_Pawn::DrawScene()
{
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::Silver));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
Pawn.Draw(md3dImmediateContext, &mView, &mProj);
HR(mSwapChain->Present(0, 0));
}

这是我的。fx代码

cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
struct VertexIn
{
float3 PosL : POSITION;
float3 Normal : NORMAL;
float2 Texcoord : TEXCOORD0;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float4 Color : COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
vout.Color = float4(1.0f, 0.0f, 0.0f, 0.0f);
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
return pin.Color;
}
technique11 LoadVertex
{
pass P0
{
    SetVertexShader(CompileShader(vs_5_0, VS()));
    SetPixelShader(CompileShader(ps_5_0, PS()));
}
};

这是我的效果代码头

class Effect
{
public:
Effect(ID3D11Device* pdevice, const std::wstring& filename);
private:
Effect(const Effect& rhs);
protected:
ID3DX11Effect* mFX;
};
class BasicEffect : public Effect
{
public:
BasicEffect(ID3D11Device* pdevice, const std::wstring& filename);
void SetWorldViewProj(CXMMATRIX M) { WorldViewProj->SetMatrix(reinterpret_cast<const float*>(&M)); };
public:
ID3DX11EffectTechnique* pLoadVertex;
ID3DX11EffectMatrixVariable* WorldViewProj;
};
class Effects
{
public:
static void InitAll(ID3D11Device* pdevice);
public:
static BasicEffect* BasicFX;
};
身体

Effect::Effect(ID3D11Device* pdevice, const std::wstring& Filename) : mFX(0)
{
std::ifstream fin(Filename, std::ios::binary);
fin.seekg(0, std::ios_base::end);
int size = (int)fin.tellg();
fin.seekg(0, std::ios_base::beg);
std::vector<char> CompiledShader(size);
fin.read(&CompiledShader[0], size);
fin.close();
HR(D3DX11CreateEffectFromMemory(&CompiledShader[0], size, 0, pdevice, &mFX));
}
BasicEffect::BasicEffect(ID3D11Device* pdevice, const std::wstring& Filename) : Effect(pdevice, Filename)
{
pLoadVertex = mFX->GetTechniqueByName("LoadVertex");
WorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
}
BasicEffect* Effects::BasicFX = 0;
void Effects::InitAll(ID3D11Device* pdevice)
{
_chdir("FX");
BasicFX = new BasicEffect(pdevice, L"Basic.fxo");
_chdir("..");
}

这是顶点代码头

namespace VERTEX
{
struct objVertex
{
    XMFLOAT3 position;
    XMFLOAT3 normal;
    XMFLOAT2 texcoord;
};
}
class InputLayoutDesc
{
public:
static const D3D11_INPUT_ELEMENT_DESC objVertex[3];
};
class InputLayouts
{
public:
static void Init(ID3D11Device* device);
static ID3D11InputLayout* Get_objVertex() { return objVertex; };
private:
static ID3D11InputLayout* objVertex;
};

cpp

const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::objVertex[3] = 
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
ID3D11InputLayout* InputLayouts::objVertex = 0;
void InputLayouts::Init(ID3D11Device* device)
{
D3DX11_PASS_DESC passDesc;
//objVertex
Effects::BasicFX->pLoadVertex->GetPassByIndex(0)->GetDesc(&passDesc);
HR(device->CreateInputLayout(InputLayoutDesc::objVertex, 3, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &objVertex));
}

对象头

class Object
{
void Init(ID3D11Device* pDevice);
HRESULT Create(ID3D11Device* pDevice, const char* Filename);
void Draw(ID3D11DeviceContext* DeviceContext, XMFLOAT4X4* View, XMFLOAT4X4* Proj);
private:
ID3D11Buffer* pmVB;
ID3D11Buffer* pmIB;
UINT mVCount;
UINT mTCount;
UINT mNCount;
UINT mICount;
XMFLOAT4X4 mWorld;
typedef std::unordered_multimap<UINT, UINT> VertexCache;
VertexCache  vertexCache;
std::vector<VERTEX::objVertex> vertices;
private:
HRESULT LoadGeometryFromOBJ(const WCHAR* strFilename, vector<UINT>* vindices);
HRESULT CreateBuffer(ID3D11Device* Device, vector<UINT>* vindices);
DWORD AddVertex(UINT hash, VERTEX::objVertex* pVertex, VertexCache& cache);
};
身体

//this code read only vertex without meterial.
void Object::Init(ID3D11Device* pDevice)
{
InputLayouts::Init(pDevice);
}
HRESULT Object::Create(ID3D11Device* pDevice, const char* Filename)
{
vector<UINT> Indices;
wchar_t* strFilename = new wchar_t[MAX_PATH];
mbstowcs(strFilename, Filename, strlen(Filename) + 1);
HR(LoadGeometryFromOBJ(strFilename, &Indices));
HR(CreateBuffer(pDevice, &Indices));
return S_OK;
}
HRESULT Object::LoadGeometryFromOBJ(const WCHAR* strFilename, vector<UINT>* Indices)
{
vector<XMFLOAT3> Positions;
vector<XMFLOAT2> TexCoords;
vector<XMFLOAT3> Normals;
//change directory
_chdir("Models");
std::ifstream InFile;
InFile.open(strFilename);
char strCommand[256] = { 0 };
for (;;)
{
    InFile >> strCommand;
    if (!InFile)
        break;
    if (0 == strcmp(strCommand, "#"))
    {
        // Comment
    }
    else if (0 == strcmp(strCommand, "v"))
    {
        // Vertex Position
        float x = 0, y = 0, z = 0;
        InFile >> x >> y >> z;
        Positions.push_back(XMFLOAT3(x, y, z));
        mVCount++;
    }
    else if (0 == strcmp(strCommand, "vt"))
    {
        // Vertex TexCoord
        float u, v;
        InFile >> u >> v;
        TexCoords.push_back(XMFLOAT2(u, v));
        mTCount++;
    }
    else if (0 == strcmp(strCommand, "vn"))
    {
        // Vertex Normal
        float x, y, z;
        InFile >> x >> y >> z;
        Normals.push_back(XMFLOAT3(x, y, z));
        mNCount++;
    }
    else if (0 == strcmp(strCommand, "f"))
    {
        // Face
        UINT iPosition, iTexCoord, iNormal;
        VERTEX::objVertex vertex;
        for (UINT iFace = 0; iFace < 3; iFace++)
        {
            ZeroMemory(&vertex, sizeof(VERTEX::objVertex));
            // OBJ format uses 1-based arrays
            InFile >> iPosition;
            vertex.position = (Positions)[iPosition - 1];
            if ('/' == InFile.peek())
            {
                InFile.ignore();
                if ('/' != InFile.peek())
                {
                    // Optional texture coordinate
                    InFile >> iTexCoord;
                    vertex.texcoord = (TexCoords)[iTexCoord - 1];
                }
                if ('/' == InFile.peek())
                {
                    InFile.ignore();
                    // Optional vertex normal
                    InFile >> iNormal;
                    vertex.normal = (Normals)[iNormal - 1];
                }
            }
            /////////////////////////////////////////////////////////////
            DWORD index = AddVertex(iPosition, &vertex, vertexCache);
            Indices->push_back((UINT)index);
            mICount++;
            /////////////////////////////////////////////////////////////
        }
    }
}
InFile.close();
_chdir("..");
return S_OK;
}
HRESULT Object::CreateBuffer(ID3D11Device* Device, vector<UINT>* indices)
{
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(VERTEX::objVertex) * mVCount;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &(vertices[0]);
HR(Device->CreateBuffer(&vbd, &vinitData, &pmVB));
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT)* mICount;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &((*indices)[0]);
HR(Device->CreateBuffer(&ibd, &iinitData, &pmIB));
return S_OK;
}
void Object::Draw(ID3D11DeviceContext* Dc, XMFLOAT4X4* View, XMFLOAT4X4* Proj)
{
Dc->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Dc->IASetInputLayout(InputLayouts::Get_objVertex());
UINT stride = sizeof(VERTEX::objVertex);
UINT offset = 0;
Dc->IASetVertexBuffers(0, 1, &pmVB, &stride, &offset);
Dc->IASetIndexBuffer(pmIB, DXGI_FORMAT_R32_UINT, offset);
XMMATRIX view = XMLoadFloat4x4(View);
XMMATRIX proj = XMLoadFloat4x4(Proj);
XMMATRIX world = XMLoadFloat4x4(&mWorld);
XMMATRIX WorldViewProj = view * proj * world;
Effects::BasicFX->SetWorldViewProj(reinterpret_cast<float*>(&WorldViewProj));
ID3DX11EffectTechnique* tech = Effects::BasicFX->pLoadVertex;
D3DX11_TECHNIQUE_DESC techDesc;
tech->GetDesc(&techDesc);
for (UINT i = 0; i < techDesc.Passes; i++)
{
    tech->GetPassByIndex(i)->Apply(0, Dc);
    Dc->DrawIndexed(mICount, 0, 0);
}
}
DWORD Object::AddVertex(UINT hash, VERTEX::objVertex* pVertex, VertexCache& cache)
{
auto f = cache.equal_range(hash);
for (auto it = f.first; it != f.second; ++it)
{
    auto& tv = vertices[it->second];
    if (0 == memcmp(pVertex, &tv, sizeof(VERTEX::objVertex)))
    {
        return it->second;
    }
}
DWORD index = static_cast<UINT>(vertices.size());
vertices.push_back(*pVertex);
VertexCache::value_type entry(hash, index);
cache.insert(entry);
return index;
}

很难从你的代码中找出到底哪里出了问题。您可以尝试采取一些步骤来调试导致问题的部分。我要做的是:

  • 首先删除所有复杂的功能。简单地用默认着色器绘制一个普通三角形。如果你没有看到它,要么是设置错误,要么是相机没有看到你画三角形的位置。

  • 如果你看到一个三角形尝试启用你的着色器。如果三角形消失了,那么问题就在着色器代码中。

  • 如果你仍然看到三角形尝试加载对象。转储一些关于它的数据,比如边界框(X, Y, Z的最小最大值)。它可能是比例关闭,或者原点没有居中。

如果你设法找出问题在哪里,你可以更新问题并得到更好的答案(或提出另一个问题)。