Esempio n. 1
0
// Note that we only need one of these.  We don't need to re-create it for every model.
//-----------------------------------------------------------------------------
void CPUTModelDX11::CreateBoundingBoxMesh()
{
    CPUTResult result = CPUT_SUCCESS;

    float3 pVertices[8] = {
        float3(  1.0f,  1.0f,  1.0f ), // 0
        float3(  1.0f,  1.0f, -1.0f ), // 1
        float3( -1.0f,  1.0f,  1.0f ), // 2
        float3( -1.0f,  1.0f, -1.0f ), // 3
        float3(  1.0f, -1.0f,  1.0f ), // 4
        float3(  1.0f, -1.0f, -1.0f ), // 5
        float3( -1.0f, -1.0f,  1.0f ), // 6
        float3( -1.0f, -1.0f, -1.0f )  // 7
    };
    USHORT pIndices[24] = {
       0,1,  1,3,  3,2,  2,0,  // Top
       4,5,  5,7,  7,6,  6,4,  // Bottom
       0,4,  1,5,  2,6,  3,7   // Verticals
    };
    CPUTVertexElementDesc pVertexElements[] = {
        { CPUT_VERTEX_ELEMENT_POSITON, tFLOAT, 12, 0 },
    };

    CPUTMesh *pMesh = mpBoundingBoxMesh = new CPUTMeshDX11();
    pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_LINE_LIST);

    CPUTBufferInfo vertexElementInfo;
    vertexElementInfo.mpSemanticName         = "POSITION";
    vertexElementInfo.mSemanticIndex         = 0;
    vertexElementInfo.mElementType           = CPUT_F32;
    vertexElementInfo.mElementComponentCount = 3;
    vertexElementInfo.mElementSizeInBytes    = 12;
    vertexElementInfo.mElementCount          = 8;
    vertexElementInfo.mOffset                = 0;

    CPUTBufferInfo indexDataInfo;
    indexDataInfo.mElementType           = CPUT_U16;
    indexDataInfo.mElementComponentCount = 1;
    indexDataInfo.mElementSizeInBytes    = sizeof(UINT16);
    indexDataInfo.mElementCount          = 24; // 12 lines, 2 verts each
    indexDataInfo.mOffset                = 0;
    indexDataInfo.mSemanticIndex         = 0;
    indexDataInfo.mpSemanticName         = NULL;

    result = pMesh->CreateNativeResources(
        this, -1,
        1,                    // vertexFormatDesc.mFormatDescriptorCount,
        &vertexElementInfo,
        pVertices,            // (void*)vertexFormatDesc.mpVertices,
        &indexDataInfo,
        pIndices              // &vertexFormatDesc.mpIndices[0]
    );
    ASSERT( CPUTSUCCESS(result), _L("Failed building bounding box mesh") );

    cString modelSuffix = ptoc(this);
    UINT index  = mpSubMaterialCount[0] + CPUT_MATERIAL_INDEX_BOUNDING_BOX;
    CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[0][index]);
    ((CPUTMeshDX11*)pMesh)->BindVertexShaderLayout( pMaterial, &mpInputLayout[0][index] );
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
void CPUTAssetSet::RenderRecursive(CPUTRenderParameters &renderParams, int materialIndex)
{
	if (!IsEnabled)
		return;
    CPUTMaterial* pCurrentMaterial = NULL;
    CPUTRenderStateBlock* pCurrentRenderState = NULL;
    CPUTRenderNode* pCurrent = mpRootNode;
    CPUTInputLayoutCache* pInputLayoutCache = CPUTInputLayoutCache::GetInputLayoutCache();
    while (pCurrent)
    {
        if (pCurrent->GetNodeType() == CPUTRenderNode::CPUT_NODE_MODEL)
        {
            CPUTModel* pModel = (CPUTModel*)pCurrent;
            pModel->UpdateShaderConstants(renderParams);
            int meshCount = pModel->GetMeshCount();
            for (int mesh = 0; mesh < meshCount; mesh++)
            {
                CPUTMaterial* pMaterial = pModel->GetMaterial(mesh, materialIndex);
                if (pMaterial != NULL)
                {
                    CPUTRenderStateBlock* pRenderStateBlock = pMaterial->GetRenderStateBlock();
                    CPUTMesh* pMesh = pModel->GetMesh(mesh);
                    SetMaterialStates(pMaterial, pCurrentMaterial);
                    SetRenderStateBlock(pRenderStateBlock, pCurrentRenderState);
                    pInputLayoutCache->Apply(pMesh, pMaterial);
                    pMesh->Draw();
                    SAFE_RELEASE(pCurrentMaterial);
                    pCurrentMaterial = pMaterial;
                    SAFE_RELEASE(pCurrentRenderState)
                    pCurrentRenderState = pRenderStateBlock;
                }
            }
        }
        CPUTRenderNode* pNext = pCurrent->GetChild();
        if (pNext == NULL)
        {
            pNext = pCurrent->GetSibling();

            if (pNext == NULL)
            {
                pNext = pCurrent->GetParent();
                if (pNext != NULL)
                {
                    pNext = pNext->GetSibling();
                }
            }
        }
        pCurrent = pNext;
    }
    SAFE_RELEASE(pCurrentMaterial);
    SAFE_RELEASE(pCurrentRenderState);
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
CPUTResult CPUTModel::LoadModelPayload(const cString &File)
{
    CPUTResult result = CPUT_SUCCESS;

    std::ifstream file(File.c_str(), std::ios::in | std::ios::binary);
    ASSERT( !file.fail(), _L("CPUTModelDX11::LoadModelPayload() - Could not find binary model file: ") + File );

    // set up for mesh creation loop
    UINT meshIndex = 0;
    while(file.good() && !file.eof())
    {
        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two
        CPUTRawMeshData vertexFormatDesc;
        vertexFormatDesc.Read(file);
        if(file.eof())
        {
            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?
            break;
        }
        ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count"));

        // create the mesh.
        CPUTMesh *pMesh = mpMesh[meshIndex];

        // always a triangle list (at this point)
        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);

        // get number of data blocks in the vertex element (pos,norm,uv,etc)
        // YUCK! TODO: Use fixed-size array of elements
        CPUTBufferInfo *pVertexElementInfo = new CPUTBufferInfo[vertexFormatDesc.mFormatDescriptorCount];
        // pMesh->SetBounds(vertexFormatDesc.mBboxCenter, vertexFormatDesc.mBboxHalf);

        // running count of each type of  element
        int positionStreamCount=0;
        int normalStreamCount=0;
        int texCoordStreamCount=0;
        int tangentStreamCount=0;
        int binormalStreamCount=0;
        int colorStreamCount=0;

        int RunningOffset = 0;
        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)
        {
            // lookup the CPUT data type equivalent
            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[vertexFormatDesc.mpElements[ii].mVertexElementType];
            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error.  This model file has an unknown data type in it's model data."));
            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)
            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];
            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)
            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;
            // store the number of elements (i.e. 3xF32, 3 elements)
            pVertexElementInfo[ii].mElementCount = vertexFormatDesc.mVertexCount;
            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here
            pVertexElementInfo[ii].mOffset = RunningOffset;
            RunningOffset = RunningOffset + pVertexElementInfo[ii].mElementSizeInBytes;

            // extract the name of stream
            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];

            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)
            {
            case CPUT_VERTEX_ELEMENT_POSITON:
                pVertexElementInfo[ii].mpSemanticName = "POSITION";
                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_NORMAL:
                pVertexElementInfo[ii].mpSemanticName = "NORMAL";
                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TEXTURECOORD:
                pVertexElementInfo[ii].mpSemanticName = "TEXCOORD";
                pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_TANGENT:
                pVertexElementInfo[ii].mpSemanticName = "TANGENT";
                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_BINORMAL:
                pVertexElementInfo[ii].mpSemanticName = "BINORMAL";
                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;
                break;
            case CPUT_VERTEX_ELEMENT_VERTEXCOLOR:
                pVertexElementInfo[ii].mpSemanticName = "COLOR";
                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;
                break;
            default:
                cString errorString = _L("Invalid vertex semantic in: '")+File+_L("'\n");
                TRACE(errorString.c_str());
                ASSERT(0, errorString);
            }
        }

        // Index buffer
        CPUTBufferInfo indexDataInfo;
        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == tUINT32) ? CPUT_U32 : CPUT_U16;
        indexDataInfo.mElementComponentCount = 1;
        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == tUINT32) ? sizeof(UINT32) : sizeof(UINT16);
        indexDataInfo.mElementCount          = vertexFormatDesc.mIndexCount;
        indexDataInfo.mOffset                = 0;
        indexDataInfo.mSemanticIndex         = 0;
        indexDataInfo.mpSemanticName         = NULL;

        if( pVertexElementInfo->mElementCount && indexDataInfo.mElementCount )
        {
            result = pMesh->CreateNativeResources(
                this,
                meshIndex,
                vertexFormatDesc.mFormatDescriptorCount,
                pVertexElementInfo,
                (void*)vertexFormatDesc.mpVertices,
                &indexDataInfo,
                &vertexFormatDesc.mpIndices[0]
            );
            if(CPUTFAILED(result))
            {
                return result;
            }

            // CC added
            result = pMesh->ExtractVerticesandIndices();
            if(CPUTFAILED(result))
            {
                return result;  
            }
            // CC added ends
        }
        delete [] pVertexElementInfo;
        pVertexElementInfo = NULL;
        ++meshIndex;
    }
    ASSERT( file.eof(), _L("") );

    // close file
    file.close();

    return result;
}
//-----------------------------------------------------------------------------
CPUTResult CPUTModel::LoadModelPayload(const cString &FileName)
{
    CPUTResult result = CPUT_SUCCESS;

    CPUTFileSystem::CPUTOSifstream file(FileName, std::ios::in | std::ios::binary);

    ASSERT( !file.fail(), _L("CPUTModel::LoadModelPayload() - Could not find binary model file: ") + FileName );

    // set up for mesh creation loop
    UINT meshIndex = 0;
    while(file.good() && !file.eof())
    {
        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two
        CPUTRawMeshData vertexFormatDesc;
        vertexFormatDesc.Read(file);
        if(file.eof())
        {
            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?
            break;
        }
        ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count"));

        // create the mesh.
        CPUTMesh *pMesh = mpMesh[meshIndex];

        // always a triangle list (at this point)
        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);

        // get number of data blocks in the vertex element (pos,norm,uv,etc)
        CPUTBufferElementInfo *pVertexElementInfo = new CPUTBufferElementInfo[vertexFormatDesc.mFormatDescriptorCount];

        // running count of each type of  element
        int positionStreamCount=0;
        int normalStreamCount=0;
        int texCoordStreamCount=0;
        int tangentStreamCount=0;
        int binormalStreamCount=0;
        int colorStreamCount=0;
		int blendWeightStreamCount = 0;
		int blendIndexStreamCount = 0;

        int runningOffset = 0;
        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)
        {
            // lookup the CPUT data type equivalent
            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT(vertexFormatDesc.mpElements[ii].mVertexElementType);
            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error.  This model file has an unknown data type in it's model data."));
            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)
            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];
            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)
            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;
            // store the number of elements (i.e. 3xF32, 3 elements)
            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here
            pVertexElementInfo[ii].mOffset = runningOffset;
            runningOffset = runningOffset + pVertexElementInfo[ii].mElementSizeInBytes;

            // extract the name of stream
            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];

            //TODO: Calculate Opengl semantic index elsewhere
            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)
            {
			//FIXME - this isn't right, and needs to change for DX and OpenGL
			//Probably just need to move semantic bind point into OpenGL, or something.
            //Currently, TEXCOORD is the only semantic with multiples in common use. Adding
            //semantic index works provided addtional attributes (e.g. vertex color) are not
            //present
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_POSITON:
                pVertexElementInfo[ii].mpSemanticName = "POSITION";
                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::POSITION;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_NORMAL:
                pVertexElementInfo[ii].mpSemanticName = "NORMAL";
                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::NORMAL;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TEXTURECOORD:
                pVertexElementInfo[ii].mpSemanticName = "TEXCOORD";
				pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;
                pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TEXCOORD + pVertexElementInfo[ii].mSemanticIndex;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TANGENT:
                pVertexElementInfo[ii].mpSemanticName = "TANGENT";
                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TANGENT;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_BINORMAL:
                pVertexElementInfo[ii].mpSemanticName = "BINORMAL";
                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::BINORMAL;
                break;
            case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_VERTEXCOLOR:
                pVertexElementInfo[ii].mpSemanticName = "COLOR";
                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;
				pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::COLOR;
                break;
            default:
                cString errorString = _L("Invalid vertex semantic in: '")+FileName+_L("'\n");
                TRACE(errorString.c_str());
                ASSERT(0, errorString);
            }
        }

        // Index buffer
        CPUTBufferElementInfo indexDataInfo;
        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? CPUT_U32 : CPUT_U16;
        indexDataInfo.mElementComponentCount = 1;
        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? sizeof(uint32_t) : sizeof(uint16_t);
        indexDataInfo.mOffset                = 0;
        indexDataInfo.mSemanticIndex         = 0;
        indexDataInfo.mpSemanticName         = NULL;

        if( vertexFormatDesc.mVertexCount && vertexFormatDesc.mIndexCount )
        {
            result = pMesh->CreateNativeResources(
                this,
                meshIndex,
                vertexFormatDesc.mFormatDescriptorCount,
                pVertexElementInfo,
                vertexFormatDesc.mVertexCount,
                (void*)vertexFormatDesc.mpVertices,
                &indexDataInfo,
                vertexFormatDesc.mIndexCount,
                vertexFormatDesc.mpIndices
            );
            if(CPUTFAILED(result))
            {
                return result;
            }
        }
        delete [] pVertexElementInfo;
        pVertexElementInfo = NULL;
        ++meshIndex;
    }
    ASSERT( file.eof(), _L("") );

    // close file
    file.close();
    
    return result;
}
void CPUTModel_CPRT::CreateModelLayer(ID3D11Device* pd3dDevice, ID3D11DeviceContext* pImmediateContext, ID3D10Blob* pVertexShaderBlob, LayerInitialization layerType)
{
	CPUTMesh* pMesh = new CPUTMesh();

	float* layer = NULL;
	switch(layerType)
	{
	case NORMAL_LAYER:
		if(normals.size() < 1)
			return;
		normalOverlays.push_back(pMesh);
		layer = normals.front();
		break;
	case TANGENT_LAYER:
		if(tangents.size() < 1)
			return;
		tangentOverlays.push_back(pMesh);
		layer = tangents.front();
		break;
	}
	
	float* vertsToSubmit = new float[vertexCount.front()*3*2];
	float* uvsToSubmit = new float[vertexCount.front()*3*2];

	unsigned int vertIndexToSubmit = 0, uvIndexToSubmit=0;
	for(unsigned int i = 0; i < vertexCount.front()*3; ++i,vertIndexToSubmit+=3,uvIndexToSubmit+=2)//Going to process the vertex/normal information to create a bunch of lines
	{
		vertsToSubmit[vertIndexToSubmit] = vertices.front()[i];
		uvsToSubmit[uvIndexToSubmit] = 0.0f;
		vertsToSubmit[vertIndexToSubmit+3] = vertices.front()[i]+0.2f*layer[i];
		uvsToSubmit[uvIndexToSubmit+2] = 1.0f;
		++i,++vertIndexToSubmit;++uvIndexToSubmit;
		vertsToSubmit[vertIndexToSubmit] = vertices.front()[i];
		uvsToSubmit[uvIndexToSubmit] = 0.0f;
		vertsToSubmit[vertIndexToSubmit+3] = vertices.front()[i]+0.2f*layer[i];
		uvsToSubmit[uvIndexToSubmit+2] = 1.0f;
		++i,++vertIndexToSubmit;++uvIndexToSubmit;
		vertsToSubmit[vertIndexToSubmit] = vertices.front()[i];
		vertsToSubmit[vertIndexToSubmit+3] = vertices.front()[i]+0.2f*layer[i];
		++vertIndexToSubmit;
	}
	delete layer;
	// set the topology
	pMesh->SetMeshTopology( CPUT_TOPOLOGY_LINE_LIST );
	CPUTMeshStreamUniform* meshStream = new CPUTMeshStreamUniform();
	// position stream
	CPUTMeshStreamInfoBlock* infoBlock = new CPUTMeshStreamInfoBlock();
	meshStream->SetName("POSITION");
	meshStream->SetData(vertsToSubmit);
	infoBlock->m_StreamBufferType = CPUT_STREAM_TYPE_VERTEX;
	infoBlock->m_StreamComponentsLayoutType =  CPUT_STREAM_ELEMENT_LAYOUT_UNIFORM;
	infoBlock->m_DataFormatElementType = CPUT_F32;
	infoBlock->m_NumberDataFormatElements = 3;  // 3xF32 
	infoBlock->m_DataElementBlockSize = sizeof(float)*3; // 12 bytes = size of CPUT_F32_F32_F32 element
	infoBlock->m_NumberVerticies = vertexCount.front()*2;
	meshStream->SetStreamInfo(infoBlock);
	pMesh->AddVertexStream(meshStream);

	// UV stream
	meshStream = new CPUTMeshStreamUniform();
	infoBlock = new CPUTMeshStreamInfoBlock();
	meshStream->SetName("TEXCOORD");
	meshStream->SetData(uvsToSubmit);
	infoBlock->m_StreamBufferType = CPUT_STREAM_TYPE_VERTEX;
	infoBlock->m_StreamComponentsLayoutType =  CPUT_STREAM_ELEMENT_LAYOUT_UNIFORM;
	infoBlock->m_DataFormatElementType = CPUT_F32;
	infoBlock->m_NumberDataFormatElements = 2;  // 3xF32 
	infoBlock->m_DataElementBlockSize = sizeof(float)*3; // 12 bytes = size of CPUT_F32_F32_F32 element
	infoBlock->m_NumberVerticies = vertexCount.front()*2;
	meshStream->SetStreamInfo(infoBlock);
	pMesh->AddVertexStream(meshStream);

	CPUTMaterialPhong* pMaterialPhong = new CPUTMaterialPhong();
	switch(layerType)
	{
	case NORMAL_LAYER:
		pMaterialPhong->SetTexture( CPUT_PHONG_MATERIAL_PROPERTY_DIFFUSE_TEXTURE, pd3dDevice, "../media/normals.png" );
		break;
	case TANGENT_LAYER:
		pMaterialPhong->SetTexture( CPUT_PHONG_MATERIAL_PROPERTY_DIFFUSE_TEXTURE, pd3dDevice, "../media/tangents.png" );
		break;
	}
		
	pMesh->SetMaterial((CPUTMaterialBase*)pMaterialPhong);

	int currentNumMeshes = AddMesh(pMesh);

	D3D11_INPUT_ELEMENT_DESC* layout = NULL;
	ID3D11InputLayout*  pVertexLayout = NULL;
	pMesh = (CPUTMesh*) GetMesh(currentNumMeshes-1);
	layerIndices.push_back(currentNumMeshes-1);

	// register each mesh with the current graphics device
	pMesh->Register(pd3dDevice, &layout);
                    
	// Create the input layout (TODO: should this be left to user to do?) 
	int numInputLayoutElements;
	pMesh->GetNumberOfInputLayoutElements(numInputLayoutElements); 

	int numElements = pMesh->GetVertexStreamCount();            
	pd3dDevice->CreateInputLayout( layout, numInputLayoutElements, pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), &pVertexLayout );         
	pMesh->SetDXLayout(pVertexLayout);
	delete vertsToSubmit;
	delete uvsToSubmit;
	
	switch(layerType)
	{
	case NORMAL_LAYER:
		normals.erase(normals.begin());
		break;
	case TANGENT_LAYER:
		tangents.erase(tangents.begin());
		break;
	}
}