Пример #1
0
//--------------------------------------------------------------------------------------
// Update the particle VB using UpdateSubresource
//--------------------------------------------------------------------------------------
void SoftParticles::QuickDepthSort(DWORD* indices, float* depths, int lo, int hi)
{
//  lo is the lower index, hi is the upper index
//  of the region of array a that is to be sorted
	int i=lo, j=hi;
	float h;
	int index;
	float x=depths[(lo+hi)/2];

	//  partition
	do
	{    
		while (depths[i] > x) i++; 
		while (depths[j] < x) j--;
		if (i<=j)
		{
			h=depths[i]; depths[i]=depths[j]; depths[j]=h;
			index = indices[i]; indices[i] = indices[j]; indices[j] = index;
			i++; j--;
		}
	} while (i<=j);

	//  recursion
	if (lo<j) QuickDepthSort(indices, depths, lo, j);
	if (i<hi) QuickDepthSort(indices, depths, i, hi);
}
Пример #2
0
//--------------------------------------------------------------------------------------
void SortParticles( D3DXVECTOR3 vEye )
{
    for( UINT i = 0; i < g_NumUsedParticles; i++ )
    {
        g_pParticleIndices[i] = i;
        D3DXVECTOR3 vDelta = vEye - g_pParticleArray[i].vPos;
        g_pParticleDepths[i] = D3DXVec3LengthSq( &vDelta );
    }

    QuickDepthSort( g_pParticleIndices, g_pParticleDepths, 0, g_NumUsedParticles - 1 );
}
Пример #3
0
//--------------------------------------------------------------------------------------
// Sort the particle buffer
//--------------------------------------------------------------------------------------
void SoftParticles::SortParticleBuffer( D3DXVECTOR3 vEye, D3DXVECTOR3 vDir )
{
	if( !g_pParticleDepthArray || !g_pCPUParticleIndices )
		return;

	// assume vDir is normalized
	D3DXVECTOR3 vToParticle;
	//init indices and depths
	for( UINT i=0; i<MAX_PARTICLES; i++ )
	{
		g_pCPUParticleIndices[i] = i;
		vToParticle = g_pCPUParticles[i].Pos - vEye;
		g_pParticleDepthArray[i] = D3DXVec3Dot( &vDir, &vToParticle );
	}

	// Sort
	QuickDepthSort(g_pCPUParticleIndices, g_pParticleDepthArray, 0, MAX_PARTICLES-1);
}
Пример #4
0
//--------------------------------------------------------------------------------------
HRESULT CTerrain::CreateGrass()
{
    HRESULT hr = S_OK;

    float fTileSize = m_fWorldScale / ( float )m_SqrtNumTiles;
    fTileSize /= 2.0f;
    float fGrassWidth = m_fGrassWidth / 2.0f;
    float fGrassHeight = m_fGrassHeight;

    D3DXVECTOR3* pGrassCenters = new D3DXVECTOR3[ m_NumGrassBlades ];
    if( !pGrassCenters )
        return E_OUTOFMEMORY;

    for( UINT i = 0; i < m_NumGrassBlades; i++ )
    {
        pGrassCenters[i].x = RPercent() * fTileSize;
        pGrassCenters[i].y = 0.0f;
        pGrassCenters[i].z = RPercent() * fTileSize;
    }

    GRASS_VERTEX* pVertices = NULL;
    D3D10_BUFFER_DESC BufferDesc;
    if( m_pDev10 )
    {
        BufferDesc.ByteWidth = m_NumGrassBlades * 4 * sizeof( GRASS_VERTEX );
        BufferDesc.Usage = D3D10_USAGE_IMMUTABLE;
        BufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
        BufferDesc.CPUAccessFlags = 0;
        BufferDesc.MiscFlags = 0;

        pVertices = new GRASS_VERTEX[ m_NumGrassBlades * 4 ];
        if( !pVertices )
            return E_OUTOFMEMORY;
    }
    else
    {
        V_RETURN( m_pDev->CreateVertexBuffer( m_NumGrassBlades * 4 * sizeof( GRASS_VERTEX ),
                                              D3DUSAGE_WRITEONLY,
                                              0,
                                              D3DPOOL_DEFAULT,
                                              &m_pGrassVB,
                                              NULL ) );
        V_RETURN( m_pGrassVB->Lock( 0, 0, ( void** )&pVertices, 0 ) );
    }

    UINT vIndex = 0;
    for( UINT i = 0; i < m_NumGrassBlades; i++ )
    {
        D3DXVECTOR3 vRandRight( RPercent(), 0, RPercent() );
        D3DXVec3Normalize( &vRandRight, &vRandRight );

        pVertices[vIndex  ].pos = pGrassCenters[i] - vRandRight * fGrassWidth;
        pVertices[vIndex  ].uv = D3DXVECTOR2( 0, 1 );
        pVertices[vIndex + 1].pos = pGrassCenters[i] + vRandRight * fGrassWidth;
        pVertices[vIndex + 1].uv = D3DXVECTOR2( 1, 1 );
        pVertices[vIndex + 2].pos = pVertices[vIndex + 1].pos + D3DXVECTOR3( 0, fGrassHeight, 0 );
        pVertices[vIndex + 2].uv = D3DXVECTOR2( 1, 0 );
        pVertices[vIndex + 3].pos = pVertices[vIndex  ].pos + D3DXVECTOR3( 0, fGrassHeight, 0 );
        pVertices[vIndex + 3].uv = D3DXVECTOR2( 0, 0 );
        vIndex += 4;
    }
    if( m_pDev10 )
    {
        D3D10_SUBRESOURCE_DATA InitData;
        InitData.pSysMem = pVertices;
        V_RETURN( m_pDev10->CreateBuffer( &BufferDesc, &InitData, &m_pGrassVB10 ) );
        SAFE_DELETE_ARRAY( pVertices );
    }
    else
    {
        m_pGrassVB->Unlock();
    }

    // Alloc indices and distances
    SHORT* pGrassIndices = new SHORT[ m_NumGrassBlades ];
    if( !pGrassIndices )
        return E_OUTOFMEMORY;
    float* pGrassDistances = new float[ m_NumGrassBlades ];
    if( !pGrassDistances )
        return E_OUTOFMEMORY;

    m_NumDirections = 16;

    if( m_pDev10 )
    {
        m_ppGrassIB10 = new ID3D10Buffer*[ m_NumDirections ];
        if( !m_ppGrassIB10 )
            return E_OUTOFMEMORY;
    }
    else
    {
        m_ppGrassIB = new LPDIRECT3DINDEXBUFFER9[ m_NumDirections ];
        if( !m_ppGrassIB )
            return E_OUTOFMEMORY;
    }
    m_pDirections = new D3DXVECTOR3[ m_NumDirections ];
    if( !m_pDirections )
        return E_OUTOFMEMORY;

    D3DXVECTOR3 vStartDir( -1,0,0 );
    float fAngleDelta = ( D3DX_PI * 2.0f ) / ( float )( m_NumDirections );
    for( UINT i = 0; i < m_NumDirections; i++ )
    {
        D3DXMATRIX mRot;
        D3DXMatrixRotationY( &mRot, i * fAngleDelta );
        D3DXVec3TransformNormal( &m_pDirections[i], &vStartDir, &mRot );

        // init indices and distances
        for( UINT g = 0; g < m_NumGrassBlades; g++ )
        {
            pGrassIndices[g] = ( SHORT )g;
            pGrassDistances[g] = -D3DXVec3Dot( &m_pDirections[i], &pGrassCenters[g] );
        }

        // sort indices
        QuickDepthSort( pGrassIndices, pGrassDistances, 0, m_NumGrassBlades - 1 );

        SHORT* pIndices = NULL;
        if( m_pDev10 )
        {
            BufferDesc.ByteWidth = m_NumGrassBlades * 6 * sizeof( SHORT );
            BufferDesc.Usage = D3D10_USAGE_IMMUTABLE;
            BufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
            BufferDesc.CPUAccessFlags = 0;
            BufferDesc.MiscFlags = 0;

            pIndices = new SHORT[ m_NumGrassBlades * 6 ];
            if( !pIndices )
                return E_OUTOFMEMORY;
        }
        else
        {
            V_RETURN( m_pDev->CreateIndexBuffer( m_NumGrassBlades * 6 * sizeof( SHORT ),
                                                 D3DUSAGE_WRITEONLY,
                                                 D3DFMT_INDEX16,
                                                 D3DPOOL_DEFAULT,
                                                 &m_ppGrassIB[i],
                                                 NULL ) );
            V_RETURN( m_ppGrassIB[i]->Lock( 0, 0, ( void** )&pIndices, 0 ) );
        }

        UINT iIndex = 0;
        for( UINT g = 0; g < m_NumGrassBlades; g++ )
        {
            //Starting vert
            SHORT GrassIndex = pGrassIndices[g] * 4;
            //Tri1
            pIndices[iIndex  ] = GrassIndex;
            pIndices[iIndex + 1] = GrassIndex + 3;
            pIndices[iIndex + 2] = GrassIndex + 1;
            //Tri2
            pIndices[iIndex + 3] = GrassIndex + 1;
            pIndices[iIndex + 4] = GrassIndex + 3;
            pIndices[iIndex + 5] = GrassIndex + 2;

            iIndex += 6;
        }
        if( m_pDev10 )
        {
            D3D10_SUBRESOURCE_DATA InitData;
            InitData.pSysMem = pIndices;
            V_RETURN( m_pDev10->CreateBuffer( &BufferDesc, &InitData, &m_ppGrassIB10[i] ) );
            SAFE_DELETE_ARRAY( pIndices );
        }
        else
        {
            m_ppGrassIB[i]->Unlock();
        }
    }									

    SAFE_DELETE_ARRAY( pGrassIndices );
    SAFE_DELETE_ARRAY( pGrassDistances );
    SAFE_DELETE_ARRAY( pGrassCenters );

    return hr;
}