Jump to content

  • Log In with Google      Sign In   
  • Create Account

#Actualbtower

Posted 13 February 2013 - 03:36 PM

It does have to map 1 to 1 with the layout, indeed. But the pSysMem pointer doesn't have to be an array (or pointer) of type SVertex. You can create a byte array and fill it using the same method I used in the aforementioned example. You can use assimp's aiMesh to check if the layout has the position, normal, and so on and add them to the array of bytes in the same order as you did in the input layout.

 

I hope that suits your needs. Here is quick&dirty example (don't use it directly, it's just to show how it would work, I didnt try to compile it):

 

 

HRESULT SMesh::CreateVB(ID3D11DeviceContext* dc, ID3D11Device* device, aiMesh * mesh)
{
 HRESULT hr;
 
 int singleVertexSize = 3*3; // in bytes (x,y,z = 3 floats); always has position, so no need to check that
 if (mesh->HasNormals()) singleVertexSize += 3*3; // x,y,z = 3 floats
 if (mesh->HasTexCoords()) singleVertexSize += 2*3; // u,v = 2 floats
 ZeroMemory( &bufferDesc, sizeof(bufferDesc) );
    bufferDesc.Usage            = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth        = singleVertexSize * mesh->mNumVertices;
    bufferDesc.BindFlags        = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags   = 0;
    bufferDesc.MiscFlags        = 0;
 vertexCount = mesh->mNumVertices;
 char * pmem = new char[singleVertexSize];
 float * fp;
 for (int i = 0; i < mesh->mNumVertices; ++i)
 {
  fp = (float*)pmem;
  *fp = mesh->mVertices[i].x;
  *(fp+1) = mesh->mVertices[i].y;
  *(fp+2) = mesh->mVertices[i].z;
  if (mesh->HasNormals())
  {
   *(fp+3) = mesh->mNormals[i].x;
   *(fp+4) = mesh->mNormals[i].y;
   *(fp+5) = mesh->mNormals[i].z;
  }
  if (mesh->HasTexCoords())
  {
   *(fp+6) = mesh->mTexCoords[i].u;
   *(fp+7) = mesh->mTexCoords[i].v;
  }
  pmem += singleVertexSize;
 }
 
 //ZeroMemory( &InitData, sizeof(InitData) );   not really needed, you fill all members below explicitly..
 InitData.pSysMem = pmem;
 InitData.SysMemPitch = 0;
 InitData.SysMemSlicePitch = 0;
 hr = device->CreateBuffer( &bufferDesc, &InitData, &vertexBuffer[0] );
 delete [] pmem;
 return hr;
}

#2btower

Posted 13 February 2013 - 03:32 PM

It does have to map 1 to 1 with the layout, indeed. But the pSysMem pointer doesn't have to be an array (or pointer) of type SVertex. You can create a byte array and fill it using the same method I used in the aforementioned example. You can use assimp's aiMesh to check if the layout has the position, normal, and so on and add them to the array of bytes in the same order as you did in the input layout.

 

I hope that suits your needs. Here is quick&dirty example:

 

HRESULT SMesh::CreateVB(ID3D11DeviceContext* dc, ID3D11Device* device, aiMesh * mesh)
{
 HRESULT hr;
 
 int singleVertexSize = 3*3; // in bytes (x,y,z = 3 floats); always has position, so no need to check that
 if (mesh->HasNormals()) singleVertexSize += 3*3; // x,y,z = 3 floats
 if (mesh->HasTexCoords()) singleVertexSize += 2*3; // u,v = 2 floats
 ZeroMemory( &bufferDesc, sizeof(bufferDesc) );
    bufferDesc.Usage            = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth        = singleVertexSize * mesh->mNumVertices;
    bufferDesc.BindFlags        = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags   = 0;
    bufferDesc.MiscFlags        = 0;
 vertexCount = mesh->mNumVertices;
 char * pmem = new char[singleVertexSize];
 float * fp;
 for (int i = 0; i < mesh->mNumVertices; ++i)
 {
  fp = (float*)pmem;
  *fp = mesh->mVertices[i].x;
  *(fp+1) = mesh->mVertices[i].y;
  *(fp+2) = mesh->mVertices[i].z;
  if (mesh->HasNormals())
  {
   *(fp+3) = mesh->mNormals[i].x;
   *(fp+4) = mesh->mNormals[i].y;
   *(fp+5) = mesh->mNormals[i].z;
  }
  if (mesh->HasTexCoords())
  {
   *(fp+6) = mesh->mTexCoords[i].u;
   *(fp+7) = mesh->mTexCoords[i].v;
  }
  pmem += singleVertexSize;
 }
 
 //ZeroMemory( &InitData, sizeof(InitData) );   not really needed, you fill all members below explicitly..
 InitData.pSysMem = pmem;
 InitData.SysMemPitch = 0;
 InitData.SysMemSlicePitch = 0;
 hr = device->CreateBuffer( &bufferDesc, &InitData, &vertexBuffer[0] );
 delete [] pmem;
 return hr;
}

#1btower

Posted 13 February 2013 - 03:30 PM

It does have to map 1 to 1 with the layout, indeed. But the pSysMem pointer doesn't have to be an array (or pointer) of type SVertex. You can create a byte array and fill it using the same method I used in the aforementioned example. You can use assimp's aiMesh to check if the layout has the position, normal, and so on and add them to the array of bytes in the same order as you did in the input layout.

 

I hope that suits your needs. Here is quick&dirty example:

 

HRESULT SMesh::CreateVB(ID3D11DeviceContext* dc, ID3D11Device* device, aiMesh * mesh)
{
 HRESULT hr;
 
 int singleVertexSize = 3*3; // in bytes (x,y,z = 3 floats); always has position, so no need to check that
 if (mesh->HasNormals()) singleVertexSize += 3*3; // x,y,z = 3 floats
 if (mesh->HasTexCoords()) singleVertexSize += 2*3; // u,v = 2 floats
 ZeroMemory( &bufferDesc, sizeof(bufferDesc) );
    bufferDesc.Usage            = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth        = singleVertexSize * mesh->mNumVertices;
    bufferDesc.BindFlags        = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags   = 0;
    bufferDesc.MiscFlags        = 0;
 vertexCount = mesh->mNumVertices;
 char * pmem = new char[singleVertexSize];
 for (int i = 0; i < mesh->mNumVertices; ++i)
 {
  *pmem = mesh->mVertices[i].x;
  *(pmem+3) = mesh->mVertices[i].y;
  *(pmem+6) = mesh->mVertices[i].z;
  if (mesh->HasNormals())
  {
   *(pmem+9) = mesh->mNormals[i].x;
   *(pmem+12) = mesh->mNormals[i].y;
   *(pmem+15) = mesh->mNormals[i].z;
  }
  if (mesh->HasTexCoords())
  {
   *(pmem+18) = mesh->mTexCoords[i].u;
   *(pmem+21) = mesh->mTexCoords[i].v;
  }
  pmem += singleVertexSize;
 }
 
 //ZeroMemory( &InitData, sizeof(InitData) );   not really needed, you fill all members below explicitly..
 InitData.pSysMem = pmem;
 InitData.SysMemPitch = 0;
 InitData.SysMemSlicePitch = 0;
 hr = device->CreateBuffer( &bufferDesc, &InitData, &vertexBuffer[0] );
 delete [] pmem;
 return hr;
}

PARTNERS