Example #1
0
HRESULT D3DXMeshTransformation( LPD3DXMESH pMesh, const D3DXMATRIX* pMatrix
							   , VisitorForD3DXVECTOR3* pPointFilter)
{
	KG_PROCESS_ERROR(NULL != pMesh && NULL != pMatrix);

	{
		DWORD fvf = pMesh->GetFVF();
		KG_PROCESS_ERROR(fvf | D3DFVF_XYZ);

		DWORD dwNumBytePerVertex = pMesh->GetNumBytesPerVertex();
		_ASSERTE(dwNumBytePerVertex >= sizeof(D3DXVECTOR3));

		DWORD dwNumVertex = pMesh->GetNumVertices();

		BYTE* pBufferStart = NULL;
		_ASSERTE(sizeof(BYTE) == 1);
		

		if(NULL == pPointFilter)
		{
			HRESULT hr = pMesh->LockVertexBuffer(0, (LPVOID*)&pBufferStart);
			KG_COM_PROCESS_ERROR(hr);
			D3DXVec3TransformCoordArray((D3DXVECTOR3*)(pBufferStart), dwNumBytePerVertex
				, (D3DXVECTOR3*)pBufferStart, dwNumBytePerVertex, pMatrix, dwNumVertex);
			pMesh->UnlockVertexBuffer();
		}
		else
		{
			//加了Filter之后性能下降是当然的,但是这不是给实时用的,所以没有关系,控制
			//调用次数和调用时机就好了
			D3DXMeshVertexEnumer vertexEnumer;
			HRESULT hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer);
			KG_COM_PROCESS_ERROR(hr);
			_ASSERTE(vertexEnumer.IsValid());
			HRESULT hrForVisitor = E_FAIL;
			for (UINT i = 0; i < vertexEnumer.GetVertexCount(); ++i)
			{
				const D3DXVECTOR3& vTemp = vertexEnumer.GetPos(i);
				hrForVisitor = pPointFilter->Accept(vTemp);
				if (FAILED(hr))
				{
					continue;
				}

				D3DXVECTOR3 vTransformed;
				D3DXVec3TransformCoord(&vTransformed, &vTemp, pMatrix);
				vertexEnumer.SetPos(i, vTransformed);
			}
		}

		
	}		

	return S_OK;
Exit0:
	return E_FAIL;
}
//------------------------------------------------------------------------------------------------
// Name:  CopyYRotatedGeometry
// Desc:  Copies geometry from one location to another, and rotates it about the Y-axis.  This
//        method returns a pointer to the the next empty vertex in destGeometry
//------------------------------------------------------------------------------------------------
GeometryVertex* CopyYRotatedGeometry(GeometryVertex* destGeometry, const GeometryVertex* sourceGeometry, int vertices, float angle)
{
    // Copy all of the geometry
    memcpy(destGeometry, sourceGeometry, sizeof(GeometryVertex) * vertices);

    // Create the transformation matrix
    D3DXMATRIXA16 matrix;
    D3DXMatrixRotationY(&matrix, -angle); // this has to be negative for it to work

    // Transform this geometry in place
    D3DXVec3TransformCoordArray((D3DXVECTOR3*)destGeometry, sizeof(GeometryVertex),
                           (const D3DXVECTOR3*)destGeometry, sizeof(GeometryVertex), &matrix, vertices);

    for (int i = 0; i < vertices; ++i) {
      destGeometry[i].nx =  0.0f;
      destGeometry[i].ny =  1.0f;
      destGeometry[i].nz =  0.0f;
    }

    // Return an empty area of the destination geometry pointer
    return destGeometry + vertices;
}
Example #3
0
static HRESULT WINAPI ID3DXSpriteImpl_Flush(ID3DXSprite *iface)
{
    ID3DXSpriteImpl *This = impl_from_ID3DXSprite(iface);
    SPRITEVERTEX *vertices;
    int i, count=0, start;
    TRACE("(%p)->(): relay\n", This);

    if(!This->ready) return D3DERR_INVALIDCALL;
    if(!This->sprite_count) return D3D_OK;

    /* TODO: use of a vertex buffer here */
    vertices=HeapAlloc(GetProcessHeap(), 0, sizeof(SPRITEVERTEX)*6*This->sprite_count);

    for(start=0; start<This->sprite_count; start+=count,count=0) {
        i=start;
        while(i<This->sprite_count &&
                (count==0 || This->sprites[i].texture==This->sprites[i-1].texture)) {
            float spritewidth=(float)This->sprites[i].rect.right-(float)This->sprites[i].rect.left;
            float spriteheight=(float)This->sprites[i].rect.bottom-(float)This->sprites[i].rect.top;

            vertices[6*i  ].pos.x = This->sprites[i].pos.x - This->sprites[i].center.x;
            vertices[6*i  ].pos.y = This->sprites[i].pos.y - This->sprites[i].center.y;
            vertices[6*i  ].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z;
            vertices[6*i+1].pos.x = spritewidth + This->sprites[i].pos.x - This->sprites[i].center.x;
            vertices[6*i+1].pos.y = This->sprites[i].pos.y - This->sprites[i].center.y;
            vertices[6*i+1].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z;
            vertices[6*i+2].pos.x = spritewidth + This->sprites[i].pos.x - This->sprites[i].center.x;
            vertices[6*i+2].pos.y = spriteheight + This->sprites[i].pos.y - This->sprites[i].center.y;
            vertices[6*i+2].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z;
            vertices[6*i+3].pos.x = This->sprites[i].pos.x - This->sprites[i].center.x;
            vertices[6*i+3].pos.y = spriteheight + This->sprites[i].pos.y - This->sprites[i].center.y;
            vertices[6*i+3].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z;
            vertices[6*i  ].col   = This->sprites[i].color;
            vertices[6*i+1].col   = This->sprites[i].color;
            vertices[6*i+2].col   = This->sprites[i].color;
            vertices[6*i+3].col   = This->sprites[i].color;
            vertices[6*i  ].tex.x = (float)This->sprites[i].rect.left / (float)This->sprites[i].texw;
            vertices[6*i  ].tex.y = (float)This->sprites[i].rect.top / (float)This->sprites[i].texh;
            vertices[6*i+1].tex.x = (float)This->sprites[i].rect.right / (float)This->sprites[i].texw;
            vertices[6*i+1].tex.y = (float)This->sprites[i].rect.top / (float)This->sprites[i].texh;
            vertices[6*i+2].tex.x = (float)This->sprites[i].rect.right / (float)This->sprites[i].texw;
            vertices[6*i+2].tex.y = (float)This->sprites[i].rect.bottom / (float)This->sprites[i].texh;
            vertices[6*i+3].tex.x = (float)This->sprites[i].rect.left / (float)This->sprites[i].texw;
            vertices[6*i+3].tex.y = (float)This->sprites[i].rect.bottom / (float)This->sprites[i].texh;

            vertices[6*i+4]=vertices[6*i];
            vertices[6*i+5]=vertices[6*i+2];

            D3DXVec3TransformCoordArray(&vertices[6*i].pos, sizeof(SPRITEVERTEX),
                                        &vertices[6*i].pos, sizeof(SPRITEVERTEX),
                                        &This->sprites[i].transform, 6);
            count++;
            i++;
        }

        IDirect3DDevice9_SetTexture(This->device, 0, (struct IDirect3DBaseTexture9 *)This->sprites[start].texture);
        IDirect3DDevice9_SetVertexDeclaration(This->device, This->vdecl);

        IDirect3DDevice9_DrawPrimitiveUP(This->device, D3DPT_TRIANGLELIST, 2*count, vertices+6*start, sizeof(SPRITEVERTEX));
    }
    HeapFree(GetProcessHeap(), 0, vertices);

    if(!(This->flags & D3DXSPRITE_DO_NOT_ADDREF_TEXTURE))
        for(i=0; i<This->sprite_count; i++)
            IDirect3DTexture9_Release(This->sprites[i].texture);

    This->sprite_count=0;

    /* Flush may be called more than once, so we don't reset This->ready here */

    return D3D_OK;
}
Example #4
0
static void CalculateLisPSM( const CCameraEntity& cam, Light& light )
{
	CalculateOrthoShadow( cam, light );

	const SVector3& lightDir = light.mWorldMat.getAxisZ();
	const SVector3& viewDir = cam.mWorldMat.getAxisZ();
	double dotProd = lightDir.dot( viewDir );
	if( fabs(dotProd) >= 0.999 )
	{
		// degenerates to uniform shadow map
		return;
	}

	// calculate the hull of body B in world space
	HullFace bodyB;
	SMatrix4x4 invCamVP;
	D3DXMatrixInverse( &invCamVP, NULL, &cam.mWorldMat );
	invCamVP *= cam.getProjectionMatrix();
	D3DXMatrixInverse( &invCamVP, NULL, &invCamVP );

	CalculateFocusedLightHull( invCamVP, lightDir, gCasterBounds, bodyB );
	int zzz = bodyB.v.size();

	int i, j;
	/*
	Frustum camFrustum( cam.getProjectionMatrix() );
	std::vector<SVector3>	bodyB;
	bodyB.reserve( gSceneCasters.size()*8 + 8 );
	for( i = 0; i < 8; ++i )
		bodyB.push_back( camFrustum.pntList[i] );
	int ncasters = gSceneCasters.size();
	for( i = 0; i < ncasters; ++i )
	{
		const CAABox& aabb = gSceneCasters[i].aabb;
		for( j = 0; j < 8; ++j )
		{
			SVector3 p;
			p.x = (j&1) ? aabb.getMin().x : aabb.getMax().x;
			p.y = (j&2) ? aabb.getMin().y : aabb.getMax().y;
			p.z = (j&4) ? aabb.getMin().z : aabb.getMax().z;
			bodyB.push_back( p );
		}
	}
	*/
	
	// calculate basis of light space projection
	SVector3 ly = -lightDir;
	SVector3 lx = ly.cross( viewDir ).getNormalized();
	SVector3 lz = lx.cross( ly );
	SMatrix4x4 lightW;
	lightW.identify();
	lightW.getAxisX() = lx;
	lightW.getAxisY() = ly;
	lightW.getAxisZ() = lz;

	SMatrix4x4 lightV;
	D3DXMatrixInverse( &lightV, NULL, &lightW );

	// rotate bound body points from world into light projection space and calculate AABB there
	D3DXVec3TransformCoordArray( &bodyB.v[0], sizeof(SVector3), &bodyB.v[0], sizeof(SVector3), &lightV, bodyB.v.size() );
	CAABox bodyLBounds;
	bodyLBounds.setNull();
	for( i = 0; i < bodyB.v.size(); ++i )
		bodyLBounds.extend( bodyB.v[i] );

	float zextent = cam.getZFar() - cam.getZNear();
	float zLextent = bodyLBounds.getMax().z - bodyLBounds.getMin().z;
	if( zLextent < zextent )
		zextent = zLextent;
	
	// calculate free parameter N
	double sinGamma = sqrt( 1.0-dotProd*dotProd );
	const double n = ( cam.getZNear() + sqrt(cam.getZNear() * (cam.getZNear() + zextent)) ) / sinGamma;

	// origin in this light space: looking at center of bounds, from distance n
	SVector3 lightSpaceO = bodyLBounds.getCenter();
	lightSpaceO.z = bodyLBounds.getMin().z - n;

	// go through bound points in light space, and compute projected bound
	float maxx = 0.0f, maxy = 0.0f, maxz = 0.0f;
	for( i = 0; i < bodyB.v.size(); ++i )
	{
		SVector3 tmp = bodyB.v[i] - lightSpaceO;
		assert( tmp.z > 0.0f );
		maxx = max( maxx, fabsf(tmp.x / tmp.z) );
		maxy = max( maxy, fabsf(tmp.y / tmp.z) );
		maxz = max( maxz, tmp.z );
	}

	SVector3 lpos;
	D3DXVec3TransformCoord( &lpos, &lightSpaceO, &lightW );
	lightW.getOrigin() = lpos;

	SMatrix4x4 lightProj;
	D3DXMatrixPerspectiveLH( &lightProj, 2.0f*maxx*n, 2.0f*maxy*n, n, maxz );

	SMatrix4x4 lsPermute, lsOrtho;
	lsPermute._11 = 1.f; lsPermute._12 = 0.f; lsPermute._13 = 0.f; lsPermute._14 = 0.f;
	lsPermute._21 = 0.f; lsPermute._22 = 0.f; lsPermute._23 =-1.f; lsPermute._24 = 0.f;
	lsPermute._31 = 0.f; lsPermute._32 = 1.f; lsPermute._33 = 0.f; lsPermute._34 = 0.f;
	lsPermute._41 = 0.f; lsPermute._42 = -0.5f; lsPermute._43 = 1.5f; lsPermute._44 = 1.f;

	D3DXMatrixOrthoLH( &lsOrtho, 2.f, 1.f, 0.5f, 2.5f );
	lsPermute *= lsOrtho;
	lightProj *= lsPermute;

	G_RENDERCTX->getCamera().setCameraMatrix( lightW );

	SMatrix4x4 lightFinal = G_RENDERCTX->getCamera().getViewMatrix() * lightProj;

	// unit cube clipping
	/*
	{
		// receiver hull
		std::vector<SVector3> receiverPts;
		receiverPts.reserve( gSceneReceivers.size() * 8 );
		int nreceivers = gSceneReceivers.size();
		for( i = 0; i < nreceivers; ++i )
		{
			const CAABox& aabb = gSceneReceivers[i].aabb;
			for( j = 0; j < 8; ++j )
			{
				SVector3 p;
				p.x = (j&1) ? aabb.getMin().x : aabb.getMax().x;
				p.y = (j&2) ? aabb.getMin().y : aabb.getMax().y;
				p.z = (j&4) ? aabb.getMin().z : aabb.getMax().z;
				receiverPts.push_back( p );
			}
		}

		// transform to light post-perspective space
		D3DXVec3TransformCoordArray( &receiverPts[0], sizeof(SVector3), &receiverPts[0], sizeof(SVector3), &lightFinal, receiverPts.size() );
		CAABox recvBounds;
		recvBounds.setNull();
		for( i = 0; i < receiverPts.size(); ++i )
			recvBounds.extend( receiverPts[i] );
		
		recvBounds.getMax().x = min( 1.f, recvBounds.getMax().x );
		recvBounds.getMin().x = max(-1.f, recvBounds.getMin().x );
		recvBounds.getMax().y = min( 1.f, recvBounds.getMax().y );
		recvBounds.getMin().y = max(-1.f, recvBounds.getMin().y );
		float boxWidth = recvBounds.getMax().x - recvBounds.getMin().x;
		float boxHeight = recvBounds.getMax().y - recvBounds.getMin().y;

		if( !FLT_ALMOST_ZERO(boxWidth) && !FLT_ALMOST_ZERO(boxHeight) )
		{
			float boxX = ( recvBounds.getMax().x + recvBounds.getMin().x ) * 0.5f;
			float boxY = ( recvBounds.getMax().y + recvBounds.getMin().y ) * 0.5f;

			SMatrix4x4 clipMatrix(
				2.f/boxWidth,  0.f, 0.f, 0.f,
				0.f, 2.f/boxHeight, 0.f, 0.f,
				0.f,           0.f, 1.f, 0.f,
				-2.f*boxX/boxWidth, -2.f*boxY/boxHeight, 0.f, 1.f );
			lightProj *= clipMatrix;
		}
	}
	*/

	G_RENDERCTX->getCamera().setProjectionMatrix( lightProj );
}