Пример #1
0
//----------------------------------------------------------------------------
void Node::MergeMeshes(MergeArray* pMergeArray)
{
	WIRE_ASSERT(pMergeArray->GetQuantity() > 0);
	if (pMergeArray->GetQuantity() == 1)
	{
		return;
	}

	TPODArray<Transformation*> transformations(pMergeArray->GetQuantity());
	TPODArray<UInt64> keys(pMergeArray->GetQuantity());
	for (UInt i = 0; i < pMergeArray->GetQuantity(); i++)
	{
		UInt64 key = 0;
		enum
		{
			STATESET = 32,
			MATERIAL = 32,
		};

		WIRE_ASSERT((STATESET + MATERIAL) <= sizeof(key) * 8);

		RenderObject* pRenderObject = (*pMergeArray)[i];
		Material* pMaterial = pRenderObject->GetMaterial();
		if (pMaterial)
		{
			key |= pMaterial->ID;
		}

		// If StateSetID is MAX_UINT, it wasn't initialized (call UpdateRS()
		// once or initialize manually)
		key |= static_cast<UInt64>(pRenderObject->GetStateSetID()) << (MATERIAL);

		keys.Append(key);
	}

	Object** pObjects = reinterpret_cast<Object**>(pMergeArray->GetArray());
 	VisibleSet::QuickSort(keys, pObjects, transformations.GetArray(), 0,
		pMergeArray->GetQuantity()-1);

	UInt vtxCount = 0;
	UInt idxCount = 0;
	Mesh* pMesh = NULL;
	for (UInt i = 0; i < pMergeArray->GetQuantity(); i++)
	{
		pMesh = (*pMergeArray)[i]->GetMesh();
		vtxCount += pMesh->GetVertexCount();
		idxCount += pMesh->GetIndexCount();
	}

	const UInt vbCount = pMesh->GetVertexBuffers().GetQuantity();
	Mesh::VertexBuffers vbs(vbCount);
	TArray<Float*> rawDst(vbCount);

	for (UInt j = 0; j < vbCount; j++)
	{
		VertexBuffer* pVB = WIRE_NEW VertexBuffer(pMesh->
			GetVertexBuffer(j)->GetAttributes(), vtxCount);
		vbs.Append(pVB);
		rawDst.Append(pVB->GetData());
	}

	IndexBuffer* pIB = WIRE_NEW IndexBuffer(idxCount);
	UShort* pRawIB = pIB->GetData();
	Int offset = 0;

	for (UInt i = 0; i < pMergeArray->GetQuantity(); i++)
	{
		pMesh = (*pMergeArray)[i]->GetMesh();
		for (UInt j = 0; j < vbCount; j++)
		{
			VertexBuffer* pMVB = pMesh->GetVertexBuffer(j);
			const UInt vtxCount = pMesh->GetVertexCount();
			pMVB->ApplyForward(Transformation::IDENTITY, rawDst[j], vtxCount,
				pMesh->GetStartVertex());
			const UInt vtxSize = pMVB->GetAttributes().GetVertexSize();
			rawDst[j] += (vtxSize / sizeof(Float)) * vtxCount;
		}

		IndexBuffer* pMIB = pMesh->GetIndexBuffer();
		offset -= pMesh->GetStartVertex();
		const UInt startIdx = pMesh->GetStartIndex();
		for (UInt j = startIdx; j < (startIdx + pMesh->GetIndexCount()); j++)
		{
			WIRE_ASSERT((((*pMIB)[j])+offset) < 0x10000);
			*pRawIB++ = static_cast<UShort>((((*pMIB)[j])+offset));
		}

		offset += pMesh->GetVertexCount();
	}

	UInt startIndex = 0;
	for (UInt i = 0; i < pMergeArray->GetQuantity(); i++)
	{
		pMesh = (*pMergeArray)[i]->GetMesh();
		const UInt indexCount = pMesh->GetIndexCount();
		Mesh* pMergedMesh = WIRE_NEW Mesh(vbs, pIB, startIndex, indexCount);
		startIndex += indexCount;
		(*pMergeArray)[i]->SetMesh(pMergedMesh);
	}
}
Пример #2
0
//----------------------------------------------------------------------------
void Node::WarmUpRendering(Renderer* pRenderer)
{
#ifndef WIRE_WII // Wii does not need to warm up by submitting draw calls
	WIRE_ASSERT(pRenderer);
	UpdateGS(0, true, false);

	Vector3F cameraLocation = WorldBound->GetCenter();
	cameraLocation.Z() += WorldBound->GetRadius();
	Vector3F viewDirection = -Vector3F::UNIT_Z;
	Vector3F up = Vector3F::UNIT_Y;
	Vector3F right = viewDirection.Cross(up);
	CameraPtr spCamera = WIRE_NEW Camera;
	spCamera->SetFrame(cameraLocation, viewDirection, up, right);

	Float fieldOfView = 60.0F;
	Float aspectRatio = 2;
	Float nearPlane = 0.1F;
	Float farPlane = WorldBound->GetRadius() * 2.0F;
	spCamera->SetFrustum(fieldOfView, aspectRatio, nearPlane, farPlane);

	CullerSorting culler;
	culler.SetCamera(spCamera);
	culler.ComputeVisibleSet(this);

	pRenderer->PreDraw(spCamera);

	// draw scene to warm up batching buffers
	pRenderer->Draw(culler.GetVisibleSets());

	// collect and draw all materials separately so none will be missed
	// by CULL_ALWAYS or Switch/LOD nodes.
	THashSet<Material*> materials;
	TStack<Node*> scene(1000);
	scene.Push(this);
	while (!scene.IsEmpty())
	{
		Node* pNode = NULL;
		scene.Pop(pNode);
		RenderObject* pRenderObject = pNode->GetRenderObject();
		if (pRenderObject && pRenderObject->GetMaterial())
		{
			materials.Insert(pRenderObject->GetMaterial());
		}

		for (UInt i = 0; i < pNode->GetQuantity(); i++)
		{
			Node* pChild = DynamicCast<Node>(pNode->GetChild(i)); 
			if (pChild)
			{
				scene.Push(pChild);
			}
		}
	}

	RenderObjectPtr spCube = StandardMesh::CreateCube24(4, pRenderer->
		GetMaxTextureStages(), true);
	THashSet<Material*>::Iterator it(&materials);
	Transformation transformation;
	transformation.SetTranslate(cameraLocation - Vector3F(0, 0, 3));
	for (Material** pMaterial = it.GetFirst(); pMaterial; pMaterial = 
		it.GetNext())
	{
		spCube->SetMaterial(*pMaterial);
		pRenderer->Draw(spCube, transformation);
	}

	pRenderer->PostDraw();
#endif
}