'Simple' winding order issue
I have a box with vertices 0,1,2,3 such that my box looks like:
0-----1
| |
3-----2
My indices are listed as:
0,1,2, //first triangle
0,2,3 //second triangle
As you can see both are listed in a clockwise winding order, however, only the first triangle is being drawn and the second is being culled.
Rearranging the second triangle to 2,3,0 works, but I'm curious as to why 0,2,3 doesn't... both are clockwise..
Thanks
[Edited by - Cailen on February 18, 2010 8:05:42 PM]
I'm going to guess you're using a triangle strip, in which case I believe the winding order is reversed for each new triangle added to the strip.
Any other ideas? This is boggling my mind... I am right in assuming that triangle with a clockwise winding order should not be culled in direct3d yes?
Could you post the code you're using to draw them? It might be another issue (Not supplying the last vertex, passing in too few primitive, etc).
Here is my vertex and index list:
And here is my code to draw the square:
AND here is my code to render the scene:
Sorry about the formatting
[source lang=cpp] void TetrisBlock::init(ID3D10Device *device){ md3dDevice = device; mNumVertices = 4; mNumFaces = 2; //create vertex buffer - topleft corner = origin Vertex vertices[] = { {D3DXVECTOR3(0.0f,0.0f,0.0f)}, //top left 0 1 {D3DXVECTOR3(1.0f,0.0f,0.0f)}, //top right {D3DXVECTOR3(1.0f,-1.0f,0.0f)}, //bottom right {D3DXVECTOR3(0.0f,-1.0f,0.0f)} // bottom left 3 2 }; D3D10_BUFFER_DESC VertexBufferDesc; VertexBufferDesc.Usage = D3D10_USAGE_IMMUTABLE; VertexBufferDesc.ByteWidth = sizeof(Vertex)*mNumVertices; VertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER; VertexBufferDesc.CPUAccessFlags = 0; VertexBufferDesc.MiscFlags = 0; D3D10_SUBRESOURCE_DATA VertexInitData; VertexInitData.pSysMem = vertices; HR(md3dDevice->CreateBuffer(&VertexBufferDesc,&VertexInitData,&mVertexBuffer)); //create index buffer DWORD indices[] = { 0,1,2, 2,3,0 }; D3D10_BUFFER_DESC IndexBufferDesc; IndexBufferDesc.Usage = D3D10_USAGE_IMMUTABLE; IndexBufferDesc.ByteWidth = sizeof(DWORD)*mNumFaces*3; IndexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER; IndexBufferDesc.CPUAccessFlags = 0; IndexBufferDesc.MiscFlags = 0; D3D10_SUBRESOURCE_DATA IndexInitData; IndexInitData.pSysMem = indices; HR(md3dDevice->CreateBuffer(&IndexBufferDesc,&IndexInitData,&mIndexBuffer));}
And here is my code to draw the square:
[source lang=cpp]void TetrisBlock::draw(){ UINT stride = sizeof(Vertex); UINT offset = 0; md3dDevice->IASetVertexBuffers(0,1,&mVertexBuffer,&stride,&offset); md3dDevice->IASetIndexBuffer(mIndexBuffer,DXGI_FORMAT_R32_UINT,0); md3dDevice->DrawIndexed((mNumFaces*3),0,0);}
AND here is my code to render the scene:
[source lang=cpp]void Tetris::drawScene(){ D3DApp::drawScene(); md3dDevice->OMSetDepthStencilState(0,0); float BlendFactors[] = {0.0f,0.0f,0.0f,0.0f}; md3dDevice->OMSetBlendState(0,BlendFactors,0xffffffff); md3dDevice->IASetInputLayout(mVertexLayout); md3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); //draw D3D10_TECHNIQUE_DESC TechniqueDesc; mTech->GetDesc(&TechniqueDesc); for (UINT p = 0; p < TechniqueDesc.Passes; p++) { mTech->GetPassByIndex(p)->Apply(0); mTetrisBlock.draw(); } mSwapChain->Present(0,0);}
Sorry about the formatting
I'm not very familiar with d3d10 myself, but it may be that the SetPrimitiveTopology call applies only to Draw() calls and not DrawIndexed.
If you want to specifiy triangles, rather than a trianglestrip, your indices need to be:
0, 1, 2, 0xffffffff,
0, 2, 3
and call DrawIndexed( numFaces*3 + 1, 0, 0 );
DrawIndexed apparently expects a trianglestrip. The 0xffffffff (DWORD max value) is a break that indicates the winding order should be reset after (0,1,2) is drawn.
See Strip Cut Index in this link.
Another possibility, use just the 6 indices (no breaks) and call SetPrimitiveTopology after you bind the vertex and index buffers.
I.e.
SetVertexBuffers()
SetIndexBuffers()
SetPrimitiveTopology()
If you want to specifiy triangles, rather than a trianglestrip, your indices need to be:
0, 1, 2, 0xffffffff,
0, 2, 3
and call DrawIndexed( numFaces*3 + 1, 0, 0 );
DrawIndexed apparently expects a trianglestrip. The 0xffffffff (DWORD max value) is a break that indicates the winding order should be reset after (0,1,2) is drawn.
See Strip Cut Index in this link.
Another possibility, use just the 6 indices (no breaks) and call SetPrimitiveTopology after you bind the vertex and index buffers.
I.e.
SetVertexBuffers()
SetIndexBuffers()
SetPrimitiveTopology()
I don't know anything about DirectX so this might not be a problem, but shouldn't you be using D3D10_BIND_INDEX_BUFFER instead of D3D10_BIND_VERTEX_BUFFER for the bind flags when creating your index buffer?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement