-1

i want to display .obj file using by directx11, so i was wrote some code and when i try to build, they said nothing special error but there's nothing displayed without silver context. i can't find what's wrong. here is my whole code. please give me some advise.

these code are based on "Introduction to 3D game progrmming with directx 11 by Frank Luna". d3dApp.h is just create window code.

maybe, you will feel this code is too long, i know. i feel sorry about it, but i was try to reduce which is relationless code at drawing. so please, get some toleration and give me some advise. please.

this is my main code

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));
}

this is my .fx code

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()));
}
};

this is my effect code head

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;
};

body

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("..");
}

this is my vertex code head

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));
}

object head

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);
};

body

//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
  • 2

1 Answers1

0

It's hard to figure out exactly what's wrong from your code. You can try to take some steps to debug that portion of it its causing the problem. What I would do is:

  • Start by removing all complex features. Simply draw an plain triangle with default shaders. If you don't see it either the setup is wrong or the camera doesn't look at where you are drawing the triangle.

  • If you see a triangle try enabling your shader. If the triangle disappears then the problem in in the shader code.

  • If you still see the triangle try loading the object. Dump some data about it like the bounding box (min max values of X, Y, Z). It could be that the scale is off, or the origini is not centered.

If you manage to figure out where the problem is you can update the question and get better answers to it (or ask another question).

Sorin
  • 11,863
  • 22
  • 26