#include "MLRHeaders.hpp" #if !defined(MLR_MLRCLIPTRICK_HPP) #include #endif //############################################################################# //########################### MLRLightMap ############################### //############################################################################# MLRLightMap::ClassData* MLRLightMap::DefaultData = NULL; Stuff::MemoryStream *MLRLightMap::stream; bool MLRLightMap::full; GOSVertexPool* MLRLightMap::vertexPool; int MLRLightMap::currentVertex, MLRLightMap::currentIndex; DynamicArrayOf *MLRLightMap::coords; // Base address of coordinate list DynamicArrayOf *MLRLightMap::texCoords; // Base address of texture coordinate list DynamicArrayOf *MLRLightMap::index; // List of color indexes DynamicArrayOf *MLRLightMap::colors; // Base address of color list int MLRLightMap::currentCTMesh; DynamicArrayOf *MLRLightMap::ctmeshs; DynamicArrayOf *transformedCoords, *clipExtraCoords; DynamicArrayOf *clipExtraColors; DynamicArrayOf *clipExtraTexCoords; DynamicArrayOf *clippingStates; ClipPolygon2 *MLRLightMap::clipBuffer; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLightMap::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLRLightMapClassID, "MidLevelRenderer::MLRLightMap", RegisteredClass::DefaultData ); Register_Object(DefaultData); BYTE *ptr = new BYTE [Limits::Max_Size_Of_LightMap_MemoryStream]; Register_Pointer(ptr); stream = new MemoryStream(ptr, Limits::Max_Size_Of_LightMap_MemoryStream); Register_Object(stream); coords = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Mesh); Register_Object(coords); texCoords = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Mesh); Register_Object(texCoords); index = new DynamicArrayOf (Limits::Max_Size_Of_Index_Buffer); Register_Object(index); colors = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Mesh); Register_Object(colors); ctmeshs = new DynamicArrayOf (32); for(int i=0;i<32;i++) { (*ctmeshs)[i] = new MLR_I_C_TMesh; } transformedCoords = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Polygon); Register_Object(transformedCoords); clipExtraCoords = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Polygon); Register_Object(clipExtraCoords); clipExtraColors = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Polygon); Register_Object(clipExtraColors); clipExtraTexCoords = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Polygon); Register_Object(clipExtraTexCoords); clippingStates = new DynamicArrayOf (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; Unregister_Object(coords); delete coords; Unregister_Object(texCoords); delete texCoords; Unregister_Object(index); delete index; Unregister_Object(colors); delete colors; int i; for(i=0;iGetLength();i++) { (*ctmeshs)[i]->DetachReference(); } Unregister_Object(ctmeshs); delete ctmeshs; stream->Rewind(); BYTE *ptr = (BYTE *)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() == LightsHeap); referenceCount = 0; 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.SetBumpMapOff(); state.SetFilterMode(MLRState::BiLinearFilterMode); state.SetTextureWrapMode(MLRState::TextureClamp); full = false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRLightMap::~MLRLightMap() { Check_Object(this); Check_Object(stream); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLightMap::SetDrawData ( GOSVertexPool *vp, Stuff::Matrix4D *mat, MLRClippingState& clippingState, MLRStateBase& _state ) { vertexPool = vp; stream->Rewind(); full = false; Check_Object(mat); *stream << (int)Matrix4D; *stream << reinterpret_cast(mat); *stream << (int)ClippingState; clippingState.Save(stream); *stream << (int)MasterRenderState; *stream << _state.GetRenderStateFlags() << _state.GetProcessStateFlags(); stream->AdvanceToDwordBoundary(); Reset(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLightMap::TestInstance() { Verify(IsDerivedFrom(DefaultData)); Check_Object(stream); } void MLRLightMap::Reset() { currentVertex = 0; currentIndex = 0; } bool MLRLightMap::IsFull(int howMuchMore) { return (howMuchMore > (coords->GetLength() - currentVertex)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLightMap::DrawLightMaps(MLRSorter *sorter, bool db) { Check_Object(stream); void *ptr, *end = stream->GetPointer(); Stuff::Matrix4D *currentMatrix=NULL; MLRClippingState currentClippingState; MLRState currentState, masterState; int pointerValue; Check_Object(vertexPool); int msd; stream->Rewind(); ptr = stream->GetPointer(); currentCTMesh = 0; while(ptr < end) { *stream >> msd; switch(msd) { case Matrix4D: *stream >> pointerValue; currentMatrix = reinterpret_cast(pointerValue); Check_Object(currentMatrix); break; case ClippingState: currentClippingState.Load(stream); break; case MasterRenderState: { DWORD render_state, process_state; *stream >> render_state >> process_state; stream->AdvanceToDwordBoundary(); masterState.SetRenderStateFlags(render_state); masterState.SetProcessStateFlags(process_state); } break; case CTMesh: { MLRState lightmapState; lightmapState.Load(stream, Current_MLR_Version); stream->AdvanceToDwordBoundary(); int startVertex, vertexCount, startIndex, indexCount; *stream >> startVertex >> vertexCount; *stream >> startIndex >> indexCount; if(vertexCount>0 && indexCount>0) { (*ctmeshs)[currentCTMesh]->SetCoordData(&(*coords)[startVertex], vertexCount); (*ctmeshs)[currentCTMesh]->SetTexCoordData(&(*texCoords)[startVertex], vertexCount); (*ctmeshs)[currentCTMesh]->SetColorData(&(*colors)[startVertex], vertexCount); (*ctmeshs)[currentCTMesh]->SetIndexData(&(*index)[startIndex], indexCount); (*ctmeshs)[currentCTMesh]->SetSubprimitiveLengths(NULL, (int)(indexCount*0.33333333333333333333333333333334f), false); (*ctmeshs)[currentCTMesh]->SetReferenceState(lightmapState); (*ctmeshs)[currentCTMesh]->CombineStates(masterState); currentCTMesh++; if(currentCTMesh>=ctmeshs->GetLength()) { ctmeshs->SetLength(2*ctmeshs->GetLength()); } } } break; default: STOP(("Corrupted light map stream !!")); break; } ptr = stream->GetPointer(); } for(int i=0;iInitializeDrawPrimitive(1, 1); (*ctmeshs)[i]->FindVisibleVertices(); if(currentClippingState.GetClippingState() != 0) { (*ctmeshs)[i]->TransformAndClip( currentMatrix, currentClippingState, vertexPool, NULL, #if COLOR_AS_DWORD>0 paintMeColorDW, #else GOSCopyColor(&paintMeColorF), #endif true ); } else { (*ctmeshs)[i]->TransformNoClip( currentMatrix, vertexPool, NULL, #if COLOR_AS_DWORD>0 paintMeColorDW, #else GOSCopyColor(&paintMeColorF), #endif true ); } if((*ctmeshs)[i]->GetVisible()) { sorter->DrawPrimitive((*ctmeshs)[i], 0); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLR_I_C_TMesh* MLRLightMap::CreateLightMapMesh() { Check_Object(stream); gos_PushCurrentHeap(LightsHeap); MLR_I_C_TMesh *ctmesh = NULL; void *ptr, *end = stream->GetPointer(); MLRClippingState currentClippingState; MLRState currentState, masterState; // int stride; int i; // Stuff::Point3D *coords = NULL; // Stuff::RGBAColor color; // Stuff::RGBAColor *colors = NULL; // Vector2DScalar *texCoords = NULL; int msd; MemoryStreamData type; stream->Rewind(); ptr = stream->GetPointer(); int startVertex = -1, vertexCount = -1, startIndex = -1, indexCount = -1; while(ptr < end) { *stream >> msd; type = static_cast(msd); switch(msd) { case Matrix4D: // not this time *stream >> i; break; case ClippingState: // not this time *stream >> i; break; case MasterRenderState: // not this time masterState.Load(stream, Current_MLR_Version); break; case CTMesh: { MLRState lightmapState; lightmapState.Load(stream, Current_MLR_Version); stream->AdvanceToDwordBoundary(); int tstartVertex, tvertexCount, tstartIndex, tindexCount; *stream >> tstartVertex >> tvertexCount; *stream >> tstartIndex >> tindexCount; if(vertexCount>0 && indexCount>0) { if(ctmesh == NULL) { ctmesh = new MLR_I_C_TMesh; startVertex = tstartVertex; vertexCount = tvertexCount; startIndex = tstartIndex; indexCount = tindexCount; ctmesh->SetReferenceState(lightmapState); } else { if(lightmapState == ctmesh->GetReferenceState()) { vertexCount += tvertexCount; indexCount += tindexCount; } else { ctmesh->CombineStates(masterState); if(ctmesh->dataStore == NULL) { ctmesh->dataStore = new DataStorage; } ctmesh->dataStore->coords.AssignData(&(*coords)[startVertex], vertexCount); ctmesh->SetCoordData(ctmesh->dataStore->coords.GetData(), vertexCount); ctmesh->dataStore->texCoords.AssignData(&(*texCoords)[startVertex], vertexCount); ctmesh->SetTexCoordData(ctmesh->dataStore->texCoords.GetData(), vertexCount); ctmesh->dataStore->colors.AssignData(&(*colors)[startVertex], vertexCount); ctmesh->SetColorData(ctmesh->dataStore->colors.GetData(), vertexCount); ctmesh->dataStore->index.AssignData(&(*index)[startVertex], indexCount); ctmesh->SetIndexData(ctmesh->dataStore->index.GetData(), indexCount); ctmesh->SetSubprimitiveLengths(NULL, (int)(indexCount*0.33333333333333333333333333333334f), false); return ctmesh; } } } } break; /* case LightMapRenderState: { MLRState state; state.Load(stream, Current_MLR_Version); if(numGOSVertices && (state != currentState)) { if(ctmesh!=NULL) { ctmesh->SetSubprimitiveLengths(NULL, numGOSVertices/3); ctmesh->FlashClipCoords(numGOSVertices); ctmesh->FlashClipTexCoords(numGOSVertices); ctmesh->FlashClipColors(numGOSVertices); ctmesh->SetReferenceState(currentState); ctmesh->TheIndexer(numGOSVertices); ctmesh->FindFacePlanes(); } } currentState = state; } break; case Polygon: { if(ctmesh == NULL) { ctmesh = new MLR_I_C_TMesh; numGOSVertices = 0; } *stream >> stride; Verify(stride==3); *stream >> color; #if COLOR_AS_DWORD DWORD argb = 0xffffffff; argb = GOSCopyColor(&color); #endif coords = (Stuff::Point3D *)stream->GetPointer(); stream->AdvancePointer(stride*sizeof(Stuff::Point3D)); texCoords = (Vector2DScalar *)stream->GetPointer(); stream->AdvancePointer(stride*sizeof(Vector2DScalar)); for(i=0;iSetClipCoord(coords[i], numGOSVertices); ctmesh->SetClipTexCoord(texCoords[i], numGOSVertices); #if COLOR_AS_DWORD ctmesh->SetClipColor(argb, numGOSVertices); #else ctmesh->SetClipColor(color, numGOSVertices); #endif } } break; case PolygonWithColor: { if(ctmesh == NULL) { ctmesh = new MLR_I_C_TMesh; numGOSVertices = 0; } *stream >> stride; Verify(stride<=Limits::Max_Number_Vertices_Per_Polygon); coords = (Stuff::Point3D *)stream->GetPointer(); stream->AdvancePointer(stride*sizeof(Stuff::Point3D)); colors = (Stuff::RGBAColor *)stream->GetPointer(); stream->AdvancePointer(stride*sizeof(Stuff::RGBAColor)); texCoords = (Vector2DScalar *)stream->GetPointer(); stream->AdvancePointer(stride*sizeof(Vector2DScalar)); for(i=0;iSetClipCoord(coords[i], numGOSVertices); ctmesh->SetClipTexCoord(texCoords[i], numGOSVertices); #if COLOR_AS_DWORD DWORD argb = GOSCopyColor(&colors[i]); ctmesh->SetClipColor(argb, numGOSVertices); #else ctmesh->SetClipColor(colors[i], numGOSVertices); #endif } } break; */ default: STOP(("Corrupted light map stream !!")); break; } ptr = stream->GetPointer(); } if(vertexCount>0 && indexCount>0 && ctmesh!=NULL) { ctmesh->CombineStates(masterState); if(ctmesh->dataStore == NULL) { ctmesh->dataStore = new DataStorage; } ctmesh->dataStore->coords.AssignData(&(*coords)[startVertex], vertexCount); ctmesh->SetCoordData(ctmesh->dataStore->coords.GetData(), vertexCount); ctmesh->dataStore->texCoords.AssignData(&(*texCoords)[startVertex], vertexCount); ctmesh->SetTexCoordData(ctmesh->dataStore->texCoords.GetData(), vertexCount); ctmesh->dataStore->colors.AssignData(&(*colors)[startVertex], vertexCount); ctmesh->SetColorData(ctmesh->dataStore->colors.GetData(), vertexCount); ctmesh->dataStore->index.AssignData(&(*index)[startVertex], indexCount); ctmesh->SetIndexData(ctmesh->dataStore->index.GetData(), indexCount); ctmesh->SetSubprimitiveLengths(NULL, (int)(indexCount*0.33333333333333333333333333333334f), false); } gos_PopCurrentHeap(); return ctmesh; }