Sign in to follow this  
Medo Mex

Rendering .obj Model in DirectX 11

Recommended Posts

Aardvajk    13207
What is it you think is going to happen here? Do you think someone is going to download your project, set it up on their system, investigate and fix the issue then send back the fixed project, all from the goodness of their hearts?

What have you tried? What isn't working? Specific questions will get answers.

Share this post


Link to post
Share on other sites
Medo Mex    891

@Aardvajk: The problem is: I don't see the model on the screen even I'm loading the vertices and setting up the vertex and index buffer

 

So, the best thing here is to post the code that I'm using.

 

FYI: This is just a simple project and it won't take 5 minutes to look it up.

 

Do you think someone is going to download your project, set it up on their system, investigate and fix the issue then send back the fixed project, all from the goodness of their hearts?

 

 

Yes, I'm expecting people here will help.

Edited by Medo3337

Share this post


Link to post
Share on other sites
Brain    18906

If you would like someone to help you need to list what you've tried already, and what you think the problem might be. Narrow down the code shared to just the part where you think the problem is, and maybe try isolating problem parts in a stand alone test case.

 

Finally, voting down people for stating the brutally honest truth is a bit low, i wouldn't do it if I were you because the mods can see it...

Edited by braindigitalis

Share this post


Link to post
Share on other sites
Medo Mex    891

@braindigitalis: What If I don't know where the problem is?

 

The only thing I see is that dev->CreateBuffer() is returning false when creating vertex or index buffer even both buffers was created successfully.

 

However, I'm not sure if the box is drawn or not (I see nothing on the screening)

int indexCount = vertexCount;
// Create vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.ByteWidth = vertexCount * sizeof(VertexType);
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bool r = dev->CreateBuffer(&bd, NULL, &pVertexBuffer);

D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(pVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, 0, &ms);
memcpy(ms.pData, &vertices, sizeof(vertices));
devcon->Unmap(pVertexBuffer, NULL);

// Create index buffer
D3D11_BUFFER_DESC indexBufferDESC;
//ZeroMemory(&indexBufferDESC, sizeof(indexBufferDESC));
indexBufferDESC.Usage = D3D11_USAGE_DEFAULT;
indexBufferDESC.ByteWidth = sizeof(unsigned long) * indexCount;
indexBufferDESC.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDESC.CPUAccessFlags = 0;
indexBufferDESC.MiscFlags = 0;
indexBufferDESC.StructureByteStride = 0;


D3D11_SUBRESOURCE_DATA indexData;
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;

// Create the index buffer
result = dev->CreateBuffer(&indexBufferDESC, &indexData, &pIndexBuffer);
Edited by Medo3337

Share this post


Link to post
Share on other sites
Zaoshi Kaba    8434

You removed most of temp files from your project, I'll give you that. Usually people are unable to do even that.

 

I am unable to compile your project because I don't have D3DX, but there is something I have noticed:

  1. you aren't doing any transformations in your vertex shader, meaning it's not being transformed into the screen;
  2. your box is relatively far from (0, 0, 0) point, it won't be visible with 'default' camera transform.

Share this post


Link to post
Share on other sites
Medo Mex    891

@Zaoshi Kaba: I tried to create a small box in 3Ds Max and set its position to 0.0, 0.0, 0.0

 

I still see nothing, how do I debug to find out if the box is being drawn or not?

Share this post


Link to post
Share on other sites
Medo Mex    891

@Zaoshi Kaba: I tried to setup world, view and projection matrices.

 

When I render a triangle as the following, it works perfectly:

VERTEX vertices[] =
{
{0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
{0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)},
{-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)}
};

However, if I changed the vertices to the vertices of the box that I loaded from the .obj file, I don't see anything rendered on the screen

 

I even tried to move the camera around, but still I don't see anything.

Share this post


Link to post
Share on other sites
Medo Mex    891

After trying to solve the problem for awhile, I can now see the mesh, however I see 2 triangles instead of a box (incomplete box)

 

I guess the problem is with the indices, I have 8 vertices, how do I calculate the indices for the box?

Share this post


Link to post
Share on other sites
Buckeye    10747


how do I calculate the indices for the box?

 

First, the obj file format supports indices for each face. Does your file already contain face definitions? If so, import and use them.

 

If you're given 8 vertices without indices provided, you have to hard code the indices, rather than calculate them.

 

A box is comprised of 6 faces, each face defined by 4 vertices at the corners. Each face is comprised of 2 triangles, each triangle defined by 3 of the 4 face vertices.

 

Assuming you're rendering with a DrawIndexed call, and using a primitive topology type of TRIANGLELIST, there will be 12 triangles ( 2 tris for each of 6 faces ), and, therefore 36 indices, 3 for each triangle.

 

Examine the list of vertices in the order they will be placed in the vertex buffer, and determine which 3 vertices by index number (zero-based) are used in each triangle. Add 3 indices for each triangle to the list of indices. Those 3 indices must be added in the correct winding order for the topology used, commonly clockwise.

Share this post


Link to post
Share on other sites
Zaoshi Kaba    8434

After trying to solve the problem for awhile, I can now see the mesh, however I see 2 triangles instead of a box (incomplete box)

 

I guess the problem is with the indices, I have 8 vertices, how do I calculate the indices for the box?

 

Inside ModelLoader.cpp you have:

// Read in the faces.
if(input == 'f') 
{
	fin.get(input);
	if(input == ' ')
	{
		// Read the face data in backwards to convert it to a left hand system from right hand system.
		fin >> faces[faceIndex].vIndex3 >> input2 >> faces[faceIndex].tIndex3 >> input2 >> faces[faceIndex].nIndex3
			>> faces[faceIndex].vIndex2 >> input2 >> faces[faceIndex].tIndex2 >> input2 >> faces[faceIndex].nIndex2
			>> faces[faceIndex].vIndex1 >> input2 >> faces[faceIndex].tIndex1 >> input2 >> faces[faceIndex].nIndex1;
		faceIndex++;
	}
}

Which assumes 3 vertices per face, aka. triangle, however in your .obj file:

g Box001
usemtl Material__26
s 2
f 1/1/1 2/2/1 3/3/1 4/4/1 
s 4
f 5/4/2 6/1/2 7/2/2 8/3/2 
s 8
f 1/4/3 4/1/3 6/2/3 5/3/3 
s 16
f 4/4/4 3/1/4 7/2/4 6/3/4 
s 32
f 3/4/5 2/1/5 8/2/5 7/3/5 
s 64
f 2/4/6 1/1/6 5/2/6 8/3/6 
# 6 polygons

each face (polygon) contains 4 vertices.

 

You have 2 choices here:

  1. load correct number of vertices for each face / polygon and triangulate them;
  2. when you export .obj file there should be an option to triangulate meshes / faces / polygons, use it to generate triangles instead of arbitrary polygons.

Share this post


Link to post
Share on other sites
Medo Mex    891

@Zaoshi Kaba: I have changed the faces property to "Triangles" instead of Quads, now I'm getting the following .obj contents:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 15.01.2015 19:32:59

mtllib box_obj.mtl

#
# object Box001
#

v  -3.9184 -2.6713 3.3765
v  -3.9184 -2.6713 -3.3765
v  3.9184 -2.6713 -3.3765
v  3.9184 -2.6713 3.3765
v  -3.9184 2.6713 3.3765
v  3.9184 2.6713 3.3765
v  3.9184 2.6713 -3.3765
v  -3.9184 2.6713 -3.3765
# 8 vertices

vn 0.0000 -1.0000 -0.0000
vn 0.0000 1.0000 -0.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 -0.0000
# 6 vertex normals

vt 1.0000 0.0000 0.0000
vt 1.0000 1.0000 0.0000
vt 0.0000 1.0000 0.0000
vt 0.0000 0.0000 0.0000
# 4 texture coords

g Box001
usemtl wire_228214153
s 2
f 1/1/1 2/2/1 3/3/1 
f 3/3/1 4/4/1 1/1/1 
s 4
f 5/4/2 6/1/2 7/2/2 
f 7/2/2 8/3/2 5/4/2 
s 8
f 1/4/3 4/1/3 6/2/3 
f 6/2/3 5/3/3 1/4/3 
s 16
f 4/4/4 3/1/4 7/2/4 
f 7/2/4 6/3/4 4/4/4 
s 32
f 3/4/5 2/1/5 8/2/5 
f 8/2/5 7/3/5 3/4/5 
s 64
f 2/4/6 1/1/6 5/2/6 
f 5/2/6 8/3/6 2/4/6 
# 12 faces

Here is how I'm creating the index buffer:

indexCount = 36;

D3D11_BUFFER_DESC indexBufferDESC;
ZeroMemory(&indexBufferDESC, sizeof(D3D11_BUFFER_DESC));
indexBufferDESC.Usage = D3D11_USAGE_DEFAULT;
indexBufferDESC.ByteWidth = sizeof(FaceType) * 3 * 12;
indexBufferDESC.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDESC.CPUAccessFlags = 0;
indexBufferDESC.MiscFlags = 0;
indexBufferDESC.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA indexData;
indexData.pSysMem = faces;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;

// Create the index buffer
hr = dev->CreateBuffer(&indexBufferDESC, &indexData, &pIndexBuffer);
assert(SUCCEEDED(result));

For Drawing:

// ...
// ...
// ...
UINT stride = sizeof(VertexType);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->DrawIndexed(indexCount, 0, 0);

swapchain->Present(0, 0);
 

Now, I'm getting weird results, here is what I'm getting on the screen:

[attachment=25505:box.png]

Share this post


Link to post
Share on other sites
Zaoshi Kaba    8434

Most likely indices are incorrect.

Are you sure you loaded them correctly?

 

Your box (first 4 faces):

s 2
f 1/1/1 2/2/1 3/3/1 
f 3/3/1 4/4/1 1/1/1 
s 4
f 5/4/2 6/1/2 7/2/2 
f 7/2/2 8/3/2 5/4/2 

should have these indices:

1, 2, 3

3, 4, 1

5, 6, 7

7, 8, 5

 

But array will be indexed from 0, so you need to subtract 1 from each of them:

0, 1, 2

2, 3, 0

4, 5, 6

6, 7, 4

 

But this is assuming you don't need normals and/or texture coordinates.

Share this post


Link to post
Share on other sites
Norman Barrows    7179

indices are definitely wrong. from the image above, you can see that the triangle in the foreground is actually the lower left triangle of the front face of the cube, except that its bottom left vertex has been moved to the back corner of the cube. other tri's aren't showing due to back face culling - very common when indices are wrong. draw a 3d sketch of a cube on paper and number the corners (zero based). that will tell you what tri uses which indices.

Share this post


Link to post
Share on other sites
Medo Mex    891

@Zaoshi Kaba: Here is how the indices look like:

[attachment=25508:faces.png]

 

And here is how I'm filling the variable 'faces': 

// Read in the faces.
if(input == 'f') 
{
fin.get(input);
if(input == ' ')
{
// Read the face data in backwards to convert it to a left hand system from right hand system.
fin >> faces[faceIndex].vIndex3 >> input2 >> faces[faceIndex].tIndex3 >> input2 >> faces[faceIndex].nIndex3
   >> faces[faceIndex].vIndex2 >> input2 >> faces[faceIndex].tIndex2 >> input2 >> faces[faceIndex].nIndex2
   >> faces[faceIndex].vIndex1 >> input2 >> faces[faceIndex].tIndex1 >> input2 >> faces[faceIndex].nIndex1;
faceIndex++;
}
}

 

Share this post


Link to post
Share on other sites
phil_t    8084


@Zaoshi Kaba: Here is how the indices look like:

 


But array will be indexed from 0, so you need to subtract 1 from each of them:

 

Doesn't look like you're doing that.

Share this post


Link to post
Share on other sites
Medo Mex    891

@phil_t: I changed the code to:

// Read in the faces.
if(input == 'f') 
{
fin.get(input);
if(input == ' ')
{
// Read the face data in backwards to convert it to a left hand system from right hand system.
fin >> faces[faceIndex].vIndex3 >> input2 >> faces[faceIndex].tIndex3 >> input2 >> faces[faceIndex].nIndex3
   >> faces[faceIndex].vIndex2 >> input2 >> faces[faceIndex].tIndex2 >> input2 >> faces[faceIndex].nIndex2
   >> faces[faceIndex].vIndex1 >> input2 >> faces[faceIndex].tIndex1 >> input2 >> faces[faceIndex].nIndex1;
faces[faceIndex].vIndex3 -= 1;
faces[faceIndex].vIndex2 -= 1;
faces[faceIndex].vIndex1 -= 1;
faces[faceIndex].tIndex3 -= 1;
faces[faceIndex].tIndex2 -= 1;
faces[faceIndex].tIndex1 -= 1;
faces[faceIndex].nIndex3 -= 1;
faces[faceIndex].nIndex2 -= 1;
faces[faceIndex].nIndex1 -= 1;

faceIndex++;
}
}

Now, I don't see anything on the screen.

Share this post


Link to post
Share on other sites
Zaoshi Kaba    8434

That's not how index buffer works.

Not sure if I'll be able to explain this correctly though.

 

Currently your buffer contains indexes for position, normal, texture coordinate separately, but all these are properties of vertex and they're impossible to index separately.

 

If you wish to include color your vertex structure might look like this:

struct Vertex {
    float x, y, z; // position
    float nx, ny, nz; // normal
    float tx, ty; // texture coordinates
    float r, g, b, a; // color
};

Now Vertex* vertices = new Vertex[countVertex]; should contain all unique combinations of position/normal/texcoord/color.

 

In cube case there will be 24 unique combinations.

It appears you have 8 different vertices, but no, you have 8 different positions.

Lets take front top right vertex - it'll have same position for all 3 walls (top, right, front), but these walls have different normal vector, which results in these combinations:

(position1, normal1)
(position1, normal2)
(position1, normal3)

And that is 3 vertices in your vertex buffer. If you do same for 7 other vertices you'll have 24 unique vertex combinations. Adding color and texture coordinate won't increase number of vertices in this case.

 

So when you load file:

s 2
f 1/1/1 2/2/1 3/3/1 
f 3/3/1 4/4/1 1/1/1 
s 4
f 5/4/2 6/1/2 7/2/2 
f 7/2/2 8/3/2 5/4/2 

you need to track all unique combinations of faces, generate vertices from position, normal, texcoord indexes, and generate index buffer from these combinations.

Ex.: combination (1/1/1) will have index 0 ( vertices[0] ), which mean you add to your index buffer value 0. If later on you encounter (1/1/1) again, you'll be adding value 0 again.

 

Hopefully I managed to explain it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this