⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlrlightmap.cpp

📁 机甲指挥官2源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//===========================================================================//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//

#include "MLRHeaders.hpp"

#if !defined(MLR_MLRCLIPTRICK_HPP)
	#include <MLR\MLRClipTrick.hpp>
#endif

//#############################################################################
//###########################    MLRLightMap    ###############################
//#############################################################################

MLRLightMap::ClassData*
	MLRLightMap::DefaultData = NULL;
Stuff::MemoryStream
	*MLRLightMap::stream;
GOSVertexPool*
	MLRLightMap::vertexPool;

DynamicArrayOf<Stuff::Vector4D>
	*transformedCoords, *clipExtraCoords;
DynamicArrayOf<RGBAColor>
	*clipExtraColors;
DynamicArrayOf<Vector2DScalar>
	*clipExtraTexCoords;
DynamicArrayOf<MLRClippingState>
	*clippingStates;
ClipPolygon2
	*MLRLightMap::clipBuffer;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRLightMap::InitializeClass()
{
	Verify(!DefaultData);
	Verify(gos_GetCurrentHeap() == StaticHeap);
	DefaultData =
		new ClassData(
			MLRLightMapClassID,
			"MidLevelRenderer::MLRLightMap",
			RegisteredClass::DefaultData
		);
	Register_Object(DefaultData);

	unsigned char *ptr = new unsigned char [Limits::Max_Size_Of_LightMap_MemoryStream];
	Register_Pointer(ptr);

	stream = new MemoryStream(ptr, Limits::Max_Size_Of_LightMap_MemoryStream);
	Register_Object(stream);

	transformedCoords = new DynamicArrayOf<Stuff::Vector4D> (Limits::Max_Number_Vertices_Per_Polygon);
	Register_Object(transformedCoords);
	clipExtraCoords = new DynamicArrayOf<Stuff::Vector4D> (2*Limits::Max_Number_Vertices_Per_Polygon);
	Register_Object(clipExtraCoords);
	clipExtraColors = new DynamicArrayOf<RGBAColor> (2*Limits::Max_Number_Vertices_Per_Polygon);
	Register_Object(clipExtraColors);
	clipExtraTexCoords = new DynamicArrayOf<Vector2DScalar> (2*Limits::Max_Number_Vertices_Per_Polygon);
	Register_Object(clipExtraTexCoords);
	clippingStates = new DynamicArrayOf<MLRClippingState> (Limits::Max_Number_Vertices_Per_Polygon);
	Register_Object(clippingStates);

	clipBuffer = new ClipPolygon2 [2];
	Register_Pointer(clipBuffer);

	clipBuffer[0].Init(Limits::Max_Number_Of_Multitextures);
	clipBuffer[1].Init(Limits::Max_Number_Of_Multitextures);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRLightMap::TerminateClass()
{
	clipBuffer[1].Destroy();
	clipBuffer[0].Destroy();
	Unregister_Pointer(clipBuffer);
	delete [] clipBuffer;

	Unregister_Object(transformedCoords);
	delete transformedCoords;
	Unregister_Object(clipExtraCoords);
	delete clipExtraCoords;
	Unregister_Object(clipExtraColors);
	delete clipExtraColors;
	Unregister_Object(clipExtraTexCoords);
	delete clipExtraTexCoords;
	Unregister_Object(clippingStates);
	delete clippingStates;

	stream->Rewind();
	unsigned char *ptr = (unsigned char *)stream->GetPointer();

	Unregister_Object(stream);
	delete stream;
	stream = NULL;

	Unregister_Pointer(ptr);
	delete [] ptr;

	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRLightMap::MLRLightMap(MLRTexture *tex) :
	RegisteredClass(DefaultData)
{
	Verify(gos_GetCurrentHeap() == Heap);
	state.SetTextureHandle(tex->GetTextureHandle());
	state.SetRenderDeltaMask(MLRState::TextureMask);

//	state.SetFogData(0xffffffff, 0.0f, 1.0f, 100.0f);
#ifdef OLDFOG
	state.SetFogMode(MLRState::DisableFogMode);
#else
	state.SetFogMode(0);
#endif

	state.SetZBufferCompareOn();
	state.SetZBufferWriteOff();
	state.SetBackFaceOn();
	state.SetAlphaMode(MLRState::OneOneMode);

	state.SetFilterMode(MLRState::BiLinearFilterMode);
	state.SetTextureWrapMode(MLRState::TextureClamp);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRLightMap::~MLRLightMap()
{
	Check_Object(this);
	Check_Object(stream);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRLightMap::SetDrawData
		(
			GOSVertexPool *vp,
			Stuff::Matrix4D *mat,
			MLRClippingState& clippingState,
			MLRState& _state
		)
{
	vertexPool = vp;

	stream->Rewind();

	*stream << (int)Matrix4D;
	*stream << reinterpret_cast<int>(mat);

	*stream << (int)ClippingState;
	clippingState.Save(stream);

	*stream << (int)MasterRenderState;
	_state.Save(stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRLightMap::TestInstance()
{
	Verify(IsDerivedFrom(DefaultData));
	Check_Object(stream);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRLightMap::DrawLightMaps(MLRSorter *sorter)
{
	Check_Object(stream);

	void *ptr, *end = stream->GetPointer();

	Stuff::Matrix4D *currentMatrix=NULL;
	MLRClippingState currentClippingState;
	
	MLRState currentState, masterState;

	unsigned short stride;

	int i, pointerValue;
	Stuff::Point3D *coords = NULL;
	Stuff::RGBAColor color;
	Stuff::RGBAColor *colors = NULL;
	Vector2DScalar *texCoords = NULL;
	DWORD argb = 0xffffffff;

	Check_Object(vertexPool);
	GOSVertex* gos_vertices = vertexPool->GetActualVertexPool();
	int numGOSVertices = 0;

	int msd;
	MemoryStreamData type;

	stream->Rewind();

	ptr = stream->GetPointer();

	while(ptr < end)
	{
		*stream >> msd;

		type = static_cast<MemoryStreamData>(msd);

		switch(msd)
		{
			case Matrix4D:
				*stream >> pointerValue;
				currentMatrix = reinterpret_cast<Stuff::Matrix4D*>(pointerValue);
			break;
			case ClippingState:
				currentClippingState.Load(stream);
			break;
			case MasterRenderState:
				masterState.Load(stream, Current_MLR_Version);
			break;
			case LightMapRenderState:
			{
				MLRState lightmapState;
				lightmapState.Load(stream, Current_MLR_Version);

				lightmapState.Combine(masterState, lightmapState);

				if(numGOSVertices && (lightmapState != currentState))
				{
					vertexPool->Increase(numGOSVertices);

					SortData *sd = sorter->SetRawData
						(
							gos_vertices, 
							numGOSVertices,
							currentState,
							SortData::TriList
						);

					if(currentState.GetDrawNowMode()==MLRState::DrawNowOnMode)

					{
						SortData::DrawFunc drawFunc = sd->Draw[sd->type];
						(sd->*drawFunc)();
					}
					else
					{

						sorter->AddSortRawData(sd);
					}
					gos_vertices = vertexPool->GetActualVertexPool();
					numGOSVertices = 0;

				}
				currentState = lightmapState;
			}
			break;
			case Polygon:
			{
				*stream >> stride;
				Verify(stride<=Limits::Max_Number_Vertices_Per_Polygon);

				*stream >> color;

				argb = GOSCopyColor(&color);

				coords = (Stuff::Point3D *)stream->GetPointer();
				stream->AdvancePointer(stride*sizeof(Stuff::Point3D));
				texCoords = (Vector2DScalar *)stream->GetPointer();
				stream->AdvancePointer(stride*sizeof(Vector2DScalar));

				MLRClippingState theAnd(0x3f), theOr(0);
				MLRClippingState *cs = clippingStates->GetData();
				Vector4D *v4d = transformedCoords->GetData();
				for(i=0;i<stride;i++,v4d++,cs++)
				{
					v4d->Multiply(coords[i], *currentMatrix);

					if(currentClippingState!=0)
					{
						cs->Clip4dVertex(v4d);

						theAnd &= *cs;

						theOr |= *cs;
					}
#if defined(_ARMOR)
					else
					{
						Verify((*transformedCoords)[i].x >= 0.0f && (*transformedCoords)[i].x <= (*transformedCoords)[i].w );
						Verify((*transformedCoords)[i].y >= 0.0f && (*transformedCoords)[i].y <= (*transformedCoords)[i].w );
						Verify((*transformedCoords)[i].z >= 0.0f && (*transformedCoords)[i].z <= (*transformedCoords)[i].w );
					}
#endif
				}

				if(theOr == 0)
				{
					for(i=1;i<stride-1;i++)
					{
						Verify((vertexPool->GetLast() + 3 + numGOSVertices) < vertexPool->GetLength());

						GOSCopyTriangleData(
							&gos_vertices[numGOSVertices],
							transformedCoords->GetData(),
							texCoords,
							0, i + 1, i
						);

						gos_vertices[numGOSVertices].argb = argb;
						gos_vertices[numGOSVertices+1].argb = argb;
						gos_vertices[numGOSVertices+2].argb = argb;

						numGOSVertices+=3;
					}
				}
				else
				{
					if(theAnd != 0)
					{
						break;
					}
					else
					{
						int k, k0, k1, l, mask, ct = 0;
						Scalar a = 0.0f;

						int numberVerticesPerPolygon = 0;

						//
						//---------------------------------------------------------------
						// Handle the case of a single clipping plane by stepping through
						// the vertices and finding the edge it originates
						//---------------------------------------------------------------
						//
						bool firstIsIn;
						MLRClippingState theTest;

						if (theOr.GetNumberOfSetBits() == 1)
						{
#ifdef LAB_ONLY
							Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
#endif
							for(k=0;k<stride;k++)
							{
								int clipped_index = numberVerticesPerPolygon;

								k0 = k;
								k1 = (k+1) < stride ? k+1 : 0;

								//
								//----------------------------------------------------
								// If this vertex is inside the viewing space, copy it
								// directly to the clipping buffer
								//----------------------------------------------------
								//
								theTest = (*clippingStates)[k0];

								if(theTest == 0)
								{
									firstIsIn = true;
									(*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
									Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
									Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
									Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
									(*clipExtraTexCoords)[clipped_index] = texCoords[k0];

									numberVerticesPerPolygon++;
									clipped_index++;

									//
									//-------------------------------------------------------
									// We don't need to clip this edge if the next vertex is
									// also in the viewing space, so just move on to the next
									// vertex
									//-------------------------------------------------------
									//
									if((*clippingStates)[k1] == 0)
									{
										continue;
									}
								}

								//
								//---------------------------------------------------------
								// This vertex is outside the viewing space, so if the next
								// vertex is also outside the viewing space, no clipping is
								// needed and we throw this vertex away.  Since only one
								// clipping plane is involved, it must be in the same space
								// as the first vertex
								//---------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -