X file meshes with more then 1 subset turning into polygon soup
I have been trying to render X files loaded with D3DXCreateMeshFromX manualy without using DrawSubset, and my meathod works fine for meshes with only 1 subset, but for meshes with more then one, it doesnt seem to be indexing properly. Basicly I have been doing it like this:
Loading:
1: Use D3DXCreateMeshFromX to load a mesh in the normal way.
2: Use OptimiseInPlace with the D3DXMESHOPT_ATTRSORT flag to create an attribute table
3: Store attribute table in my own data structure for latter use (My structure has Material and texture information bound with it making rendering more convieniant then keeping on using the attribute table)
Rendering:
4: Arange all mesh subsets into the most efficent (least render state changes) way possibe. This is done with *all* meshes so that different meshes with the same texture can be rendered without a call to SetTexture in between.
5: Use DrawIndexedPrimitive with the appropriate information from my data structure to render each subset.
But for some reason, the result always looks somthing like the mesh in the middle of this screenshot. (What it should look like is in the top right curtisy of the DX Mesh Viewer)
Note that the tiger mesh that only has 1 subset renders fine. I have checked with the debugger, the calls made to Draw Indexed Primitive and all the numbers are the same as those given by the attribute table.
I am really at a loss as to what could be causing the problem.
Post your mesh loading code and your render code so that we can see if there is anything out of the ordinary happening in there.
neneboricua
neneboricua
For what it''s worth, I''ve sometimes found that switching vertex buffers, or switching model views, is as expensive as switching textures.
Switching textures was expensive back when the cards had to suck textures in from main RAM. That''s not the case anymore, and hasn''t been for a while...
Switching SHADERS is expensive, though.
Switching textures was expensive back when the cards had to suck textures in from main RAM. That''s not the case anymore, and hasn''t been for a while...
Switching SHADERS is expensive, though.
quote:Original post by hplus0603
For what it''s worth, I''ve sometimes found that switching vertex buffers, or switching model views, is as expensive as switching textures.
Switching textures was expensive back when the cards had to suck textures in from main RAM. That''s not the case anymore, and hasn''t been for a while...
Switching SHADERS is expensive, though.
so you''re implying that the d3dx effect rendering model is the worst possible way you can do things, if you''ve got multiple passes with different shaders in them?
attribute sorting rearranges your vertices, so you might want to make sure that you''re using the *new* set of indices, rather than the ones loaded from the .x file..
Okay, well I am getting the indices directly from the I3DXMESH object each frame, so the indices should be the optimised ones.
Here is the code to load the models:
Okay, dont kill me becuase the code is probably crap.
And here is the rendering code. BTW it should be noted that the call to render somthing is stored in a structure called a RenderRequest which has the IndexBuffer pointer, the MeshSubset structure and position information in it
I know there is somthing really bad going with the seleting of the vertex format, but ah well. It also might be a bit confusing out of context.
Here is the code to load the models:
bool Object3dMesh::CreateMesh(string MeshFilename, LPDIRECT3DDEVICE8& D3DDevice){ g_Log.Out(string("Loading mesh: ") + MeshFilename, LOG_TO_CONSOLE); LPD3DXBUFFER pD3DXMtrlBuffer; LPD3DXBUFFER pD3DXAdjBuffer; DWORD NumMaterial = 0L; if(FAILED(D3DXLoadMeshFromX((char*)MeshFilename.c_str(), D3DXMESH_MANAGED, D3DDevice, &pD3DXAdjBuffer, &pD3DXMtrlBuffer, &NumMaterial, &m_Mesh))) { g_Log.Out(string("Failed to load mesh: ") + MeshFilename); pD3DXMtrlBuffer->Release(); pD3DXAdjBuffer->Release(); return false; } D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); for( DWORD i=0; i<NumMaterial; i++ ) { D3DMATERIAL8 MaterialToCreate; // Copy the material MaterialToCreate = d3dxMaterials[i].MatD3D; MaterialToCreate.Ambient = MaterialToCreate.Diffuse; LPDIRECT3DTEXTURE8 TextureToCreate = NULL; if(d3dxMaterials[i].pTextureFilename != NULL) { TextureToCreate = g_Engine->LoadTexture(d3dxMaterials[i].pTextureFilename); if(!TextureToCreate) { g_Log.Out(string("Failed to Load Texture for Mesh: ") + MeshFilename); } } //This creates the data structure to store a subset in MeshSubset NewSubset;//This function registers the material of the mesh with the material system NewSubset.m_Material = g_Engine->CreateMaterial(TextureToCreate, MaterialToCreate, m_Mesh->GetFVF()); m_Subsets.push_back(NewSubset); } //Optimise to create the attribute table if(FAILED(m_Mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL))) { g_Log.Out(string("Optimise failed for Mesh: ") + MeshFilename); pD3DXMtrlBuffer->Release(); pD3DXAdjBuffer->Release(); return false; } //We have finished with the buffers pD3DXMtrlBuffer->Release(); pD3DXAdjBuffer->Release(); //Now fill all the rendering information in the subset from the attribute table DWORD NumberOfAttributes = 0; m_Mesh->GetAttributeTable(NULL, &NumberOfAttributes); D3DXATTRIBUTERANGE* AttributeTable = new D3DXATTRIBUTERANGE[NumberOfAttributes]; m_Mesh->GetAttributeTable(AttributeTable, &NumberOfAttributes); D3DXATTRIBUTERANGE* It = AttributeTable; vector<MeshSubset>::iterator ListIt = m_Subsets.begin(); for(int i = 0; i < (int)NumberOfAttributes; i++ ) { (*ListIt).IndexCount = It->FaceCount; (*ListIt).IndexStart = It->FaceStart; (*ListIt).VertexCount = It->VertexCount; (*ListIt).VertexStart = It->VertexStart; It++; ListIt++; } delete[] AttributeTable; g_Log.Out(string("Mesh Loaded: ") + MeshFilename, LOG_TO_CONSOLE); return true;}
Okay, dont kill me becuase the code is probably crap.
And here is the rendering code. BTW it should be noted that the call to render somthing is stored in a structure called a RenderRequest which has the IndexBuffer pointer, the MeshSubset structure and position information in it
{ //Create a material to start with MeshMaterial CurrentMaterial; LPDIRECT3DVERTEXBUFFER8 CurrentVertexBuffer = NULL; RenderRequest CurrentRequest; multiset<RenderRequest>::iterator it; for(it = m_RenderRequestManager->m_RenderRequests.begin(); it != m_RenderRequestManager->m_RenderRequests.end(); it++) { CurrentRequest = (*it); //Check to see if the current material is the same as the fetched one if(!(CurrentMaterial == (*(CurrentRequest.IndexSubset.m_Material)))) { //If it is not, then change the texture and material settings m_D3DDevice->SetTexture(0, CurrentRequest.IndexSubset.m_Material->m_Texture); m_D3DDevice->SetMaterial( &(CurrentRequest.IndexSubset.m_Material->m_Material)); if(CurrentRequest.IndexSubset.m_Material->m_FVF != CurrentMaterial.m_FVF) m_D3DDevice->SetVertexShader( CurrentRequest.IndexSubset.m_Material->m_FVF); CurrentMaterial = (*CurrentRequest.IndexSubset.m_Material); } //Set current position m_D3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), &(CurrentRequest.Position)); //Set the vertex Stream if different if(CurrentVertexBuffer != CurrentRequest.Vertices) { //There are three posible different types of vertex stream if( CurrentRequest.IndexSubset.m_Material->m_FVF == 258 ) m_D3DDevice->SetStreamSource(0, CurrentRequest.Vertices, sizeof(Vertex3dTextured)); else if( CurrentRequest.IndexSubset.m_Material->m_FVF == 18 ) m_D3DDevice->SetStreamSource(0, CurrentRequest.Vertices, sizeof(Vertex3dNormal)); else if( CurrentRequest.IndexSubset.m_Material->m_FVF == 274 ) m_D3DDevice->SetStreamSource(0, CurrentRequest.Vertices, sizeof(Vertex3dTexturedNormal)); else { m_D3DDevice->EndScene(); g_Log.Out("Error: Unknown FVF Encountered: Exiting"); return false; } } m_D3DDevice->SetIndices(CurrentRequest.Indices, 0); //Now render the actual object m_D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, CurrentRequest.IndexSubset.VertexStart, CurrentRequest.IndexSubset.VertexCount, CurrentRequest.IndexSubset.IndexStart, CurrentRequest.IndexSubset.IndexCount); } m_RenderRequestManager->m_RenderRequests.clear(); return true;}
I know there is somthing really bad going with the seleting of the vertex format, but ah well. It also might be a bit confusing out of context.
Hi,
I have a very simmilar problem I am able to draw first subset without problems,but others are bad...
Have you ever solved it? Could You help me pls?
I think that problem could be in wrong DrawIndexedPrimitive parameters , but i'm not sure
[edited by - AlexanderCZ on March 25, 2004 8:09:42 AM]
I have a very simmilar problem I am able to draw first subset without problems,but others are bad...
Have you ever solved it? Could You help me pls?
I think that problem could be in wrong DrawIndexedPrimitive parameters , but i'm not sure
[edited by - AlexanderCZ on March 25, 2004 8:09:42 AM]
I ran into a similar problem as well when I was working on my octree. My octree worked fine if the polygon soup used one skin but went bonkers when I used more than 1 skin. Finally I ended up breaking the surface into multiple ID3DXMesh(s) and everything has been working pretty well ever since.
-Richard ''vajuras'' Osborne
-Richard ''vajuras'' Osborne
What primitive type are you specifying to DIP()? It needs to be triangle list, not triangle strip.
I like pie.
I like pie.
I already fixed it.it was in bad params of DIP()...
It seems that my english is bad,because when i was reading DX Documentation I didn''t noticed that MinIndex does mean StartVertex
It seems that my english is bad,because when i was reading DX Documentation I didn''t noticed that MinIndex does mean StartVertex
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement