0

I'm trying to actually RENDER the cloth I created to the screen in DirectX11. I used the PhysX API to create a cloth object and tried to create the vertex and index buffer accordingly. As far as I know the cloth object should be okay.

Here's my code. Please note that this is in a custom engine (from school) so some things might look weird (like the gameContext object for example) but you should be able to comprehend the code.

I used the Introduction to 3D Game Programming with DirectX10 book from Frank D Luna as a reference for the buffers.

// 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);

When this is done I run this code in the "draw" part of the engine:

// 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 ); 
}

I think there's something obviously wrong that I'm just totally missing. (DirectX isn't my strongest part in programming). Every comment or answer is much appreciated.

Dries
  • 995
  • 2
  • 16
  • 45
  • What is the problem? Do you get any errors or are the vertices not displayed correctly? – rashmatash Aug 10 '14 at 23:08
  • Nothing shows up in the actual application. I was thinking it might be a mistake that I forgot something engine specific but I wanted to know if I did everything right in the creation as well – Dries Aug 10 '14 at 23:38
  • You're using `gCloth->getNbParticles()` as the number of indices. That is in general not the case since the number of particles is essentially the number of vertices and is in general not equal to the number of indices. Try to render a single triangle which you create manually to see if it show's up. – rashmatash Aug 11 '14 at 09:53

0 Answers0