コード例 #1
0
ファイル: DXUTMesh.cpp プロジェクト: n-n-n/Flow2D
//-----------------------------------------------------------------------------
// Convert the mesh to the format specified by the given vertex declarations.
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl, 
                                  bool bAutoComputeNormals, bool bAutoComputeTangents, 
                                  bool bSplitVertexForOptimalTangents )
{
    LPD3DXMESH pTempMesh = NULL;

    if( m_pMesh )
    {
        if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl,
                                        pd3dDevice, &pTempMesh ) ) )
        {
            SAFE_RELEASE( pTempMesh );
            return E_FAIL;
        }
    }


    // Check if the old declaration contains a normal.
    bool bHadNormal = false;
    bool bHadTangent = false;
    D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE];
    if( m_pMesh && SUCCEEDED( m_pMesh->GetDeclaration( aOldDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
        {
            if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHadNormal = true;
            }
            if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT )
            {
                bHadTangent = true;
            }
        }
    }

    // Check if the new declaration contains a normal.
    bool bHaveNormalNow = false;
    bool bHaveTangentNow = false;
    D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
    if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
        {
            if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHaveNormalNow = true;
            }
            if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT )
            {
                bHaveTangentNow = true;
            }
        }
    }

    SAFE_RELEASE( m_pMesh );

    if( pTempMesh )
    {
        m_pMesh = pTempMesh;

        if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pMesh, NULL );
        }

        if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents )
        {
            ID3DXMesh* pNewMesh;
            HRESULT hr;

            DWORD *rgdwAdjacency = NULL;
            rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3];
            if( rgdwAdjacency == NULL )
                return E_OUTOFMEMORY;
            V( m_pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );

            float fPartialEdgeThreshold;
            float fSingularPointThreshold;
            float fNormalEdgeThreshold;
            if( bSplitVertexForOptimalTangents )
            {
                fPartialEdgeThreshold = 0.01f;
                fSingularPointThreshold = 0.25f;
                fNormalEdgeThreshold = 0.01f;
            }
            else
            {
                fPartialEdgeThreshold = -1.01f;
                fSingularPointThreshold = 0.01f;
                fNormalEdgeThreshold = -1.01f;
            }

            // Compute tangents, which are required for normal mapping
            hr = D3DXComputeTangentFrameEx( m_pMesh, 
                                            D3DDECLUSAGE_TEXCOORD, 0, 
                                            D3DDECLUSAGE_TANGENT, 0,
                                            D3DX_DEFAULT, 0, 
                                            D3DDECLUSAGE_NORMAL, 0,
                                            0, rgdwAdjacency, 
                                            fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold, 
                                            &pNewMesh, NULL );

            SAFE_DELETE_ARRAY( rgdwAdjacency );
            if( FAILED(hr) )
                return hr;

            SAFE_RELEASE( m_pMesh );
            m_pMesh = pNewMesh;
        }
    }

    return S_OK;
}
コード例 #2
0
void CShowPoints9::SetMesh(LPD3DXMESH pNewMesh, LPD3DXSKININFO pNewSkin)
{
    HRESULT hr = S_OK;

    NumPoints = 0;
    
    UnskinnedVB.resize(0);
    SAFE_RELEASE(SkinnedVB);
    SAFE_RELEASE(Skin);

    if(pNewMesh == NULL)
        return;

    IDirect3DDevice9* device = DXUTGetD3D9Device();

    {//EFFECT
     V( device->CreateVertexDeclaration( Elements, &Declaration ) );

     ID3DXBuffer* pErrors = NULL;
     V( SASCreateEffectFromResource(
             device, 
             NULL, MAKEINTRESOURCE(IDR_SHOWLINES9FX), MAKEINTRESOURCE(RT_RCDATA),
             NULL, 
             NULL, 
             0,
             NULL, 
             &Effect, 
             &pErrors));
    if(pErrors)
         DXVGetApp().OutputA( (const char*)pErrors->GetBufferPointer() );
    SAFE_RELEASE(pErrors);

    }//EFFECT



    D3DVERTEXELEMENT9 declIn[ MAX_FVF_DECL_SIZE ];
    V( pNewMesh->GetDeclaration(declIn) );

    int iPos= -1;
    int iNorm= -1;
    for( int i = 0 ; 
        declIn[i].Stream != 255 && i < MAX_FVF_DECL_SIZE;
        i++)
    {
        if(declIn[i].Usage == D3DDECLUSAGE_POSITION && declIn[i].UsageIndex == 0)
            iPos = i;
        if(declIn[i].Usage == D3DDECLUSAGE_NORMAL && declIn[i].UsageIndex == 0)
            iNorm = i;
    }

    if(iPos == -1 || iNorm == -1)
        return;

    if( (( declIn[iPos].Type & (D3DDECLTYPE_FLOAT3|D3DDECLTYPE_FLOAT4)) == 0  ) ||
        (( declIn[iNorm].Type & (D3DDECLTYPE_FLOAT3|D3DDECLTYPE_FLOAT4)) == 0  ) )
        return;

    NumPoints = pNewMesh->GetNumVertices();

    int MeshStride = pNewMesh->GetNumBytesPerVertex();


    if(pNewSkin)
    {
        V( pNewSkin->Clone( &Skin ) ); 
        V( Skin->SetDeclaration(Elements) );
    }


    //GET VERTEX DATA

    BYTE* pSrcVB= NULL;
    V(  pNewMesh->LockVertexBuffer( D3DLOCK_READONLY, (LPVOID*)&pSrcVB ) );
    UnskinnedVB.resize(pNewMesh->GetNumVertices());
    for( DWORD iVert = 0; iVert < pNewMesh->GetNumVertices(); iVert++)
    {
        Vertex& v0 = UnskinnedVB[iVert];

        v0.Position = *(D3DXVECTOR3*) (pSrcVB+(MeshStride*iVert)+declIn[iPos].Offset);
    }
    V( pNewMesh->UnlockVertexBuffer() );

    V( device->CreateVertexBuffer( NumPoints*Stride , D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &SkinnedVB, NULL) );
    //Fill in with initial values so unskinned meshes do not have to do this every render.
    pSrcVB=(BYTE*)(void*)&UnskinnedVB.front();
    BYTE* pDstVB=NULL;
    V( SkinnedVB->Lock(0, 0, (void**)&pDstVB, 0 ) );
    {
        memcpy( pDstVB, pSrcVB, Stride*pNewMesh->GetNumVertices() );
    }
    V( SkinnedVB->Unlock() );
}
コード例 #3
0
ファイル: DXUTMesh.cpp プロジェクト: Noligz/WaterDrop
//-----------------------------------------------------------------------------
// Name: CDXUTMesh::SetVertexDecl
// Desc: Convert the mesh to the format specified by the given vertex
//       declarations.
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl )
{
    LPD3DXMESH pTempSysMemMesh = NULL;
    LPD3DXMESH pTempLocalMesh  = NULL;

    if( m_pSysMemMesh )
    {
        if( FAILED( m_pSysMemMesh->CloneMesh( m_pSysMemMesh->GetOptions(), pDecl,
                                              pd3dDevice, &pTempSysMemMesh ) ) )
            return E_FAIL;
    }

    if( m_pLocalMesh )
    {
        if( FAILED( m_pLocalMesh->CloneMesh( m_pLocalMesh->GetOptions(), pDecl, pd3dDevice,
                                             &pTempLocalMesh ) ) )
        {
            SAFE_RELEASE( pTempSysMemMesh );
            return E_FAIL;
        }
    }

    // Check if the old declaration contains a normal.
    bool bHadNormal = false;
    D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE];
    if( m_pSysMemMesh && SUCCEEDED( m_pSysMemMesh->GetDeclaration( aOldDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
            if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHadNormal = true;
                break;
            }
    }

    // Check if the new declaration contains a normal.
    bool bHaveNormalNow = false;
    D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
    if( pTempSysMemMesh && SUCCEEDED( pTempSysMemMesh->GetDeclaration( aNewDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
            if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHaveNormalNow = true;
                break;
            }
    }

    SAFE_RELEASE( m_pSysMemMesh );
    SAFE_RELEASE( m_pLocalMesh );

    if( pTempSysMemMesh )
    {
        m_pSysMemMesh = pTempSysMemMesh;

        if( !bHadNormal && bHaveNormalNow )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pSysMemMesh, NULL );
        }
    }

    if( pTempLocalMesh )
    {
        m_pLocalMesh = pTempLocalMesh;

        if( !bHadNormal && bHaveNormalNow )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pLocalMesh, NULL );
        }
    }

    return S_OK;
}
コード例 #4
0
DWORD MeshParameterization::OnGenerateAtlas( DWORD size, void * params )
{
	VERIFY_MESSAGE_SIZE( size, sizeof( GENERATEATLASMESSAGE ) );
	GENERATEATLASMESSAGE * msg = (GENERATEATLASMESSAGE*)params;
	if( !msg )
	{
		return MSG_ERROR;
	}
	bool bUseIncomingTexCoords = msg->useIncomingTexCoords;
	GenerateBounds();
	HRESULT hr;
	//This should be changed to use a new mesh parameterization technique
	DWORD numFaces = (DWORD)m_Faces->size();
	DWORD numVertices = (DWORD)m_CollapsedMesh->size();
	DWORD curError = 0;
	if( !bUseIncomingTexCoords &&
		numFaces > 0 &&
		numVertices > 0 )
	{
		DWORD fvf = D3DFVF_XYZ |  D3DFVF_NORMAL | D3DFVF_TEX1 ;
		DWORD flags =  D3DXMESH_SYSTEMMEM ;//  | D3DXMESH_MANAGED ;// | D3DXMESH_SOFTWAREPROCESSING | D3DXMESH_SYSTEMMEM |;
		
		LPD3DXMESH mesh = NULL;
		hr = D3DXCreateMeshFVF( numFaces, numVertices, flags, fvf, m_pDevice, &mesh );
		if( FAILED( hr ) )
		{
			curError = GetLastError();
			EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in create mesh fvf\n"));
			return MSG_ERROR;
		}
		//now fill with data
		BYTE * vertexData;
		BYTE * indexData;
		hr = mesh->LockVertexBuffer( 0, (LPVOID*)&vertexData );
		hr = mesh->LockIndexBuffer( 0, (LPVOID*)&indexData );
		D3DVERTEXELEMENT9 Decl[ MAX_FVF_DECL_SIZE ];
		mesh->GetDeclaration( Decl );
		
		paramVertex * pVertOriginal = (paramVertex*)vertexData;
		for( int i = 0; i < (int)numVertices; i++ )
		{
			paramVertex * pVert = (paramVertex*)vertexData;
			pVert->x = (*m_CollapsedMesh)[i].originalPosition.x;
			pVert->y = (*m_CollapsedMesh)[i].originalPosition.y;
			pVert->z = (*m_CollapsedMesh)[i].originalPosition.z;
			pVert->nx = -(*m_CollapsedMesh)[i].normal.x;
			pVert->ny = -(*m_CollapsedMesh)[i].normal.y;
			pVert->nz = -(*m_CollapsedMesh)[i].normal.z;
			pVert->u = (*m_CollapsedMesh)[i].generatedU;
			pVert->v = (*m_CollapsedMesh)[i].generatedV;
			NormalizeUV( pVert->u );
			NormalizeUV( pVert->v );

			vertexData += sizeof( paramVertex );
		}
		for( int i = 0; i < (int)numFaces; i++ )
		{
			unsigned short * index = (unsigned short*)indexData;
			index[0] = ( unsigned short )(*m_Faces)[ i ].index[ 0 ];
			index[1] = ( unsigned short )(*m_Faces)[ i ].index[ 1 ];
			index[2] = ( unsigned short )(*m_Faces)[ i ].index[ 2 ];
			indexData += sizeof( unsigned short )*3;//32 bit indices triangles
		}

		LPD3DXBUFFER imt;
		hr = D3DXComputeIMTFromPerVertexSignal( mesh, (const float*)pVertOriginal + 3*sizeof(float), 3, sizeof(paramVertex),
											0L, 0, 0, &imt );		
		mesh->UnlockIndexBuffer();
		mesh->UnlockVertexBuffer();
		//tensors
   		float * tensors = new float[ 3*numFaces ];
   		for( int i = 0; i < 3*(int)numFaces; i += 3 )
   		{
   			tensors[ i ] = 4.f;
   			tensors[ i + 1 ] = 0.f;
   			tensors[ i + 2 ] = 4.f;
   		}
		
		//some checks 
		numVertices = mesh->GetNumVertices();
		numFaces = mesh->GetNumFaces();

		//create adjacency
		DWORD * adjacency = new DWORD[	3*numFaces ];
		memset( adjacency, 0, sizeof(DWORD)*3*numFaces );
		hr = mesh->GenerateAdjacency( 0.001f, adjacency );
		//hr = mesh->ConvertPointRepsToAdjacency( NULL, adjacency );
		if( FAILED( hr ) )
		{
			curError = GetLastError();
			EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in generate adjacency\n"));
			return MSG_ERROR;
		}
		/* save to mesh to check model uvs
		D3DXMATERIAL mat;
		mat.MatD3D.Ambient.r = mat.MatD3D.Ambient.a =mat.MatD3D.Ambient.b =mat.MatD3D.Ambient.g = 0;
		mat.MatD3D.Diffuse.r = mat.MatD3D.Diffuse.a =mat.MatD3D.Diffuse.b =mat.MatD3D.Diffuse.g = 1;
		mat.pTextureFilename = "tex.dds";
		D3DXSaveMeshToX( "mesh.x", mesh, adjacency, &mat, NULL, 0, D3DXF_FILEFORMAT_TEXT );
		*/

		float * imtTensor = tensors;//(float*)imt->GetBufferPointer();

		float stretchout;
		unsigned int charts;
		LPD3DXMESH meshOut = NULL;
		LPD3DXBUFFER remappedData = NULL;
		LPD3DXBUFFER faceData = NULL;

		D3DXATTRIBUTERANGE Attrib;
		memset(&Attrib, 0, sizeof(D3DXATTRIBUTERANGE));
		Attrib.FaceCount = numFaces;
		Attrib.VertexCount = numVertices;
		mesh->SetAttributeTable(&Attrib, 1);
		int gutter = m_TexSize / 32;
		gutter = min( gutter, 6 );
		hr = D3DXUVAtlasCreate( mesh, 0, .5, m_TexSize, m_TexSize, 
								6, //gutter
								0, adjacency, 0,
								imtTensor, (LPD3DXUVATLASCB)UVGenCallback, .0001f, 0,
								//D3DXUVATLAS_GEODESIC_QUALITY ,
								D3DXUVATLAS_GEODESIC_FAST,
								&meshOut, &faceData, &remappedData, 
								&stretchout, &charts );
		if( FAILED( hr ) )
		{
			curError = GetLastError();
			EngineGetToolBox()->Log(LOGERROR, _T("MeshParameterization: Error in uv atlas create\n"));
			return MSG_ERROR;
		}
		/* save to mesh to check model uvs
		hr = meshOut->ConvertPointRepsToAdjacency( NULL, adjacency );
		D3DXSaveMeshToX( "mesh2.x", meshOut, adjacency, &mat, NULL, 0, D3DXF_FILEFORMAT_TEXT );
		*/
		delete [] adjacency;
		delete [] tensors;

		//Generate our lightmap cache data for passing on and saving
		GenerateCache( meshOut, remappedData );
		GenerateTriangleTexelData();
		
		meshOut->Release();
		faceData->Release();
		remappedData->Release();
		mesh->Release();
	}    
	else 
	if( bUseIncomingTexCoords )
	{
		GenerateCache();
		GenerateTriangleTexelData();
	}
	return MSG_HANDLED_STOP;
}