从physx布料对象创建顶点和索引缓冲区的正确方法是什么

时间:2014-08-10 21:23:03

标签: c++ directx physx

我试图在DirectX11中实际渲染我在屏幕上创建的布料。 我使用PhysX API创建一个布料对象,并尝试相应地创建顶点和索引缓冲区。据我所知,布料对象应该没问题。

这是我的代码。请注意,这是在一个自定义引擎(来自学校),所以有些东西可能看起来很奇怪(例如gameContext对象),但你应该能够理解代码。

我使用Frank D Luna的DirectX10 3D游戏编程简介作为缓冲区的参考。

// create regular mesh
PxU32 resolution = 20;
PxU32 numParticles = resolution*resolution;
PxU32 numTriangles = 2*(resolution-1)*(resolution-1);

// create cloth particles
PxClothParticle* particles = new PxClothParticle[numParticles];
PxVec3 center(0.5f, 0.3f, 0.0f);
PxVec3 delta = 1.0f/(resolution-1) * PxVec3(15.0f, 15.0f, 15.0f);
PxClothParticle* pIt = particles;
for(PxU32 i=0; i<resolution; ++i)
{
    for(PxU32 j=0; j<resolution; ++j, ++pIt)
    {
        pIt->invWeight = j+1<resolution ? 1.0f : 0.0f;
        pIt->pos = delta.multiply(PxVec3(PxReal(i), 
            PxReal(j), -PxReal(j))) - center;
    }
}

// create triangles
PxU32* triangles = new PxU32[3*numTriangles];
PxU32* iIt = triangles;
for(PxU32 i=0; i<resolution-1; ++i)
{
    for(PxU32 j=0; j<resolution-1; ++j)
    {
        PxU32 odd = j&1u, even = 1-odd;
        *iIt++ = i*resolution + (j+odd);
        *iIt++ = (i+odd)*resolution + (j+1);
        *iIt++ = (i+1)*resolution + (j+even);
        *iIt++ = (i+1)*resolution + (j+even);
        *iIt++ = (i+even)*resolution + j;
        *iIt++ = i*resolution + (j+odd);
    }
}

// create fabric from mesh
PxClothMeshDesc meshDesc;
meshDesc.points.count = numParticles;
meshDesc.points.stride = sizeof(PxClothParticle);
meshDesc.points.data = particles;

meshDesc.invMasses.count = numParticles;
meshDesc.invMasses.stride = sizeof(PxClothParticle);
meshDesc.invMasses.data = &particles->invWeight;

meshDesc.triangles.count = numTriangles;
meshDesc.triangles.stride = 3*sizeof(PxU32);
meshDesc.triangles.data = triangles;

// cook fabric
PxClothFabric* fabric = PxClothFabricCreate(*PhysxManager::GetInstance()->GetPhysics(), meshDesc, PxVec3(0, 1, 0));

//delete[] triangles;

// create cloth
PxTransform gPose = PxTransform(PxVec3(0,1,0));
gCloth = PhysxManager::GetInstance()->GetPhysics()->createCloth(gPose, *fabric, particles, PxClothFlags(0));

fabric->release();
//delete[] particles;

// 240 iterations per/second (4 per-60hz frame)
gCloth->setSolverFrequency(240.0f);

GetPhysxProxy()->GetPhysxScene()->addActor(*gCloth);

// CREATE VERTEX BUFFER
D3D11_BUFFER_DESC bufferDescriptor = {};
bufferDescriptor.Usage = D3D11_USAGE_DEFAULT;
bufferDescriptor.ByteWidth = sizeof( PxClothParticle* ) * gCloth->getNbParticles();
bufferDescriptor.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDescriptor.CPUAccessFlags = 0;
bufferDescriptor.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA initData = {};
initData.pSysMem = particles;

gameContext.pDevice->CreateBuffer(&bufferDescriptor, &initData, &m_pVertexBuffer);

// BUILD INDEX BUFFER
D3D11_BUFFER_DESC bd = {};
bd.Usage = D3D11_USAGE_IMMUTABLE;
bd.ByteWidth = sizeof(PxU32) * sizeof(triangles);
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initData2 = {};
initData2.pSysMem = triangles;
gameContext.pDevice->CreateBuffer(&bd, &initData2, &m_pIndexBuffer);

完成后,我在&#34; draw&#34;中运行此代码。引擎的一部分:

// Set vertex buffer(s)
UINT offset = 0;
UINT vertexBufferStride = sizeof(PxClothParticle*);
gameContext.pDeviceContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &vertexBufferStride, &offset );

// Set index buffer
gameContext.pDeviceContext->IASetIndexBuffer(m_pIndexBuffer,DXGI_FORMAT_R32_UINT,0);

 // Set primitive topology
gameContext.pDeviceContext->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

auto mat = new DiffuseMaterial();
mat->Initialize(gameContext);
mat->SetDiffuseTexture(L"./Resources/Textures/Chair_Dark.dds");
gameContext.pMaterialManager->AddMaterial(mat, 3);

ID3DX11EffectTechnique* pTechnique = mat->GetDefaultTechnique();

D3DX11_TECHNIQUE_DESC techDesc;
pTechnique->GetDesc( &techDesc );
for( UINT p = 0; p < techDesc.Passes; ++p )
{
    pTechnique->GetPassByIndex(p)->Apply(0, gameContext.pDeviceContext);
    gameContext.pDeviceContext->DrawIndexed(gCloth->getNbParticles(), 0, 0 ); 
}

我认为我完全错过了一些显而易见的错误。 (DirectX不是我编程中最强大的部分)。每个评论或答案都非常感谢。

0 个答案:

没有答案