在directx11对象中没有绘制

时间:2015-07-22 08:28:15

标签: c++ draw directx-11 .obj

我想使用directx11显示.obj文件,所以我写了一些代码,当我尝试构建时,他们没有说任何特殊错误,但没有银色上下文没有显示。我找不到什么是错的。 这是我的整个代码。请给我一些建议。

这些代码基于“Frank Luna使用directx 11进行3D游戏编程简介”。 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;
}

1 个答案:

答案 0 :(得分:0)

很难弄清楚代码中到底出了什么问题。您可以尝试采取一些步骤来调试导致问题的部分。 我会做的是:

  • 首先删除所有复杂功能。只需使用默认着色器绘制一个普通三角形。如果您没有看到设置错误或相机没有看到您正在绘制三角形的位置。

  • 如果您看到三角形,请尝试启用着色器。如果三角形消失,那么着色器代码中出现问题。

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

如果您设法找出问题所在,您可以更新问题并获得更好的答案(或提出其他问题)。