📄 mlrlightmap.cpp
字号:
//===========================================================================//
// 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 + -