//////////////////////////////////////////////////////////// // DrawUnsorted //////////////////////////////////////////////////////////// bool MeshRender::DrawUnsorted(unsigned int iIndex) { ai_assert(iIndex < scene->mNumMeshes); // set vertex and index buffer devices.d3ddev->SetStreamSource(0,apcMeshes[iIndex]->piVB,0, sizeof(Vertex)); devices.d3ddev->SetIndices(apcMeshes[iIndex]->piIB); D3DPRIMITIVETYPE type; switch (scene->mMeshes[iIndex]->mPrimitiveTypes) { case aiPrimitiveType_POINT: type = D3DPT_POINTLIST;break; case aiPrimitiveType_LINE: type = D3DPT_LINELIST;break; case aiPrimitiveType_TRIANGLE: type = D3DPT_TRIANGLELIST;break; } // and draw the mesh devices.d3ddev->DrawIndexedPrimitive(type, 0,0, scene->mMeshes[iIndex]->mNumVertices,0, scene->mMeshes[iIndex]->mNumFaces); return true; } //////////////////////////////////////////////////////////// // DrawSorted //////////////////////////////////////////////////////////// bool MeshRender::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld) { ai_assert(iIndex < scene->mNumMeshes); MeshHelper* pcHelper = apcMeshes[iIndex]; const aiMesh* pcMesh = scene->mMeshes[iIndex]; if (!pcHelper || !pcMesh || !pcHelper->piIB) return false; if (pcMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE || pcMesh->HasBones()) return DrawUnsorted(iIndex); // compute the position of the camera in worldspace aiMatrix4x4 mWorldInverse = mWorld; mWorldInverse.Inverse(); mWorldInverse.Transpose(); const aiVector3D vLocalCamera = mWorldInverse * aiVector3D(0.0f, 0.0f, 15.0f); // well ... this is really funny now. We must compute their distance // from the camera. We take the average distance of a face and add it // to a map which sorts it std::map> smap; for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) { const aiFace* pcFace = &pcMesh->mFaces[iFace]; float fDist = 0.0f; for (unsigned int c = 0; c < 3;++c) { aiVector3D vPos = pcMesh->mVertices[pcFace->mIndices[c]]; vPos -= vLocalCamera; fDist += vPos.SquareLength(); } smap.insert(std::pair(fDist,iFace)); } // now we can lock the index buffer and rebuild it D3DINDEXBUFFER_DESC sDesc; pcHelper->piIB->GetDesc(&sDesc); if (D3DFMT_INDEX16 == sDesc.Format) { uint16_t* aiIndices; pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); for (std::map >::const_iterator i = smap.begin(); i != smap.end();++i) { const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; *aiIndices++ = (uint16_t)pcFace->mIndices[0]; *aiIndices++ = (uint16_t)pcFace->mIndices[1]; *aiIndices++ = (uint16_t)pcFace->mIndices[2]; } } else if (D3DFMT_INDEX32 == sDesc.Format) { uint32_t* aiIndices; pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); for (std::map>::const_iterator i = smap.begin(); i != smap.end();++i) { const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; *aiIndices++ = (uint32_t)pcFace->mIndices[0]; *aiIndices++ = (uint32_t)pcFace->mIndices[1]; *aiIndices++ = (uint32_t)pcFace->mIndices[2]; } } pcHelper->piIB->Unlock(); // set vertex and index buffer devices.d3ddev->SetStreamSource(0,pcHelper->piVB,0,sizeof(Vertex)); // and draw the mesh devices.d3ddev->SetIndices(pcHelper->piIB); devices.d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, pcMesh->mNumVertices,0, pcMesh->mNumFaces); return true; }