#include "MLRHeaders.hpp" Stuff::ReadOnlyArrayOf MidLevelRenderer::temp_lengths; int clipTrick[6][2] = { { 1, 1}, { 1, 0}, { 0, 1}, { 0, 0}, { 2, 0}, { 2, 1} }; //############################################################################# //######################### ClipPolygon2 ############################ //############################################################################# void ClipPolygon2::Init(int passes) { Verify(gos_GetCurrentHeap() == StaticHeap); coords.SetLength(Limits::Max_Number_Vertices_Per_Polygon); colors.SetLength(Limits::Max_Number_Vertices_Per_Polygon); texCoords.SetLength(passes*Limits::Max_Number_Vertices_Per_Polygon); clipPerVertex.SetLength(Limits::Max_Number_Vertices_Per_Polygon); for(int i=0;i *MLRPrimitiveBase::transformedCoords; DynamicArrayOf *MLRPrimitiveBase::clipPerVertex; DynamicArrayOf *MLRPrimitiveBase::clipExtraCoords; DynamicArrayOf *MLRPrimitiveBase::clipExtraTexCoords; DynamicArrayOf MLR_I_C_PMesh::clipExtraColors; DynamicArrayOf *MLRPrimitiveBase::clipExtraLength; ClipPolygon2 *MLRPrimitiveBase::clipBuffer; DynamicArrayOf *MLRPrimitiveBase::extraChannels[2*MaxNumberOfExtraChannel]; Scalar MLRPrimitiveBase::fogTable[Limits::Max_Number_Of_FogStates][4]; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLRPrimitiveBaseClassID, "MidLevelRenderer::MLRPrimitiveBase", RegisteredClass::DefaultData, NULL ); Register_Object(DefaultData); transformedCoords = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Mesh); Register_Object(transformedCoords); clipPerVertex = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Mesh); Register_Object(clipPerVertex); clipExtraCoords = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Mesh); Register_Object(clipExtraCoords); clipExtraTexCoords = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Mesh); Register_Object(clipExtraTexCoords); // start - fix for bug #5367 // array overwrite - extra channels only was set to Max_Number_Vertices_Per_Mesh, I doubled this number // my buddy: Paul Tozour clipExtraColors = new DynamicArrayOf(2*Limits::Max_Number_Vertices_Per_Mesh); Register_Object(clipExtraColors); clipExtraLength = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Mesh); Register_Object(clipExtraLength); clipBuffer = new ClipPolygon2 [2]; Register_Pointer(clipBuffer); clipBuffer[0].Init(Limits::Max_Number_Of_Multitextures); clipBuffer[1].Init(Limits::Max_Number_Of_Multitextures); for(int i=0;i<2*MLRPrimitiveBase::MaxNumberOfExtraChannel;i++) { extraChannels[i] = new DynamicArrayOf (2*Limits::Max_Number_Vertices_Per_Mesh); Register_Pointer(extraChannels[i]); } // end - fix for bug #5367 } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::TerminateClass() { for(int i=0;i<2*MLRPrimitiveBase::MaxNumberOfExtraChannel;i++) { Unregister_Object(extraChannels[i]); delete extraChannels[i]; } clipBuffer[1].Destroy(); clipBuffer[0].Destroy(); Unregister_Pointer(clipBuffer); delete [] clipBuffer; Unregister_Object(transformedCoords); delete transformedCoords; Unregister_Object(clipPerVertex); delete clipPerVertex; Unregister_Object(clipExtraCoords); delete clipExtraCoords; Unregister_Object(clipExtraTexCoords); delete clipExtraTexCoords; Unregister_Object(clipExtraColors); delete clipExtraColors; Unregister_Object(clipExtraLength); delete clipExtraLength; Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRPrimitiveBase::MLRPrimitiveBase( ClassData *class_data, MemoryStream *stream, int version ): RegisteredClass(class_data) { Check_Pointer(this); Check_Object(stream); dataStore = NULL; switch(version) { case 1: case 2: { STOP(("This class got created only after version 2 !")); } break; default: { bool too_big = false; MemoryStreamIO_Read(stream, &coords); MemoryStreamIO_Read(stream, &texCoords); if (coords.GetLength()>Limits::Max_Number_Vertices_Per_Mesh) { too_big = true; coords.AssignData(coords.GetData(), Limits::Max_Number_Vertices_Per_Mesh); texCoords.AssignData(texCoords.GetData(), Limits::Max_Number_Vertices_Per_Mesh); } if(version<15) { MemoryStreamIO_Read(stream, &temp_lengths); int dMode; *stream >> dMode; drawMode = static_cast(dMode); } else { *stream >> drawMode; temp_lengths.AssignData(NULL, 0); } gos_PushCurrentHeap(StatesHeap); referenceState.Load(stream, version); gos_PopCurrentHeap(); #if defined (_DEBUG) && 0 if(too_big == true) { MLRTexture *tex = (*MLRTexturePool::Instance)[&referenceState]; const char *tex_name = NULL; if(tex!=NULL) { tex_name = tex->GetTextureName(); } if(tex_name!=NULL) { PAUSE(("Mesh with texture \"%s\" currently loaded has more than %d vertices", tex_name, Limits::Max_Number_Vertices_Per_Mesh)); } else { PAUSE(("Mesh currently loaded has more than %d vertices", Limits::Max_Number_Vertices_Per_Mesh)); } } #endif } break; } passes = 1; referenceCount = 1; channelUse = 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::Save(MemoryStream *stream) { Check_Object(this); Check_Object(stream); *stream << GetClassID(); MemoryStreamIO_Write(stream, &coords); MemoryStreamIO_Write(stream, &texCoords); *stream << drawMode; referenceState.Save(stream); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRPrimitiveBase::MLRPrimitiveBase(ClassData *class_data): RegisteredClass(class_data) { referenceState = 0; state = 0; passes = 1; referenceCount = 1; dataStore = new DataStorage; channelUse = 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRPrimitiveBase::~MLRPrimitiveBase() { Verify(referenceCount==0); if (dataStore) delete dataStore; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::InitializeDraw() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::InitializeDrawPrimitive(BYTE vis, int) { gos_vertices = NULL; numGOSVertices = -1; visible = vis; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::SetCoordData( const Point3D *data, int dataSize ) { Check_Object(this); Check_Pointer(data); Verify(texCoords.GetLength() == 0 || dataSize == texCoords.GetLength()); #if defined (MAX_NUMBER_VERTICES) Verify(dataSize <= MAX_NUMBER_VERTICES); #endif coords.AssignData(data, dataSize); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::GetCoordData( const Point3D **data, int *dataSize ) { Check_Object(this); *data = coords.GetData(); *dataSize = coords.GetLength(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::SetTexCoordData( const Vector2DScalar *data, int dataSize ) { Check_Object(this); Check_Pointer(data); Verify(coords.GetLength() == 0 || dataSize == coords.GetLength()); texCoords.AssignData((Vector2DScalar *)data, dataSize); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::GetTexCoordData( const Vector2DScalar **data, int *dataSize ) { Check_Object(this); *data = texCoords.GetData(); *dataSize = texCoords.GetLength(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::Transform(Matrix4D *mat) { Check_Object(this); MLR_RENDER("Transform::MLRPrimitiveBase"); Start_Timer(Transform_Time); int i, len = coords.GetLength(); for(i=0;ifogNearClip); Verify(entry>0 && entry<=Limits::Max_Number_Of_FogStates); #if FOG_HACK GOSVertex::SetFogTableEntry(entry, fogNearClip, fogFarClip, fogDensity); #endif entry--; Verify(entry>=0); fogTable[entry][0] = fogNearClip; fogTable[entry][1] = fogFarClip; fogTable[entry][2] = fogDensity; if(Close_Enough(fogFarClip, fogNearClip)) { #if defined(LAB_ONLY) PAUSE((0, "FogNearClip: %f and FogFarClip: %f too close to each other!", fogNearClip, fogFarClip)); #endif fogTable[entry][3] = 1.0f/500.0f; } else { fogTable[entry][3] = 1.0f/(fogFarClip-fogNearClip); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::GetFogTableEntry(int entry, Stuff::Scalar * pfogNearClip, Stuff::Scalar * pfogFarClip, Stuff::Scalar * pfogDensity) { Verify(entry>0 && entry<=Limits::Max_Number_Of_FogStates); entry--; *pfogNearClip = fogTable[entry][0]; *pfogFarClip = fogTable[entry][1]; *pfogDensity = fogTable[entry][2]; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRPrimitiveBase::GetExtend(Stuff::ExtentBox *box) { Check_Object(this); Check_Object(box); if(coords.GetLength()==0) { return; } box->minX = box->maxX = coords[0].x; box->minY = box->maxY = coords[0].y; box->minZ = box->maxZ = coords[0].z; for(int i=0;iminX) { box->minX = coords[i].x; } if(coords[i].y < box->minY) { box->minY = coords[i].y; } if(coords[i].z < box->minZ) { box->minZ = coords[i].z; } if(coords[i].x > box->maxX) { box->maxX = coords[i].x; } if(coords[i].y > box->maxY) { box->maxY = coords[i].y; } if(coords[i].z > box->maxZ) { box->maxZ = coords[i].z; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MLRPrimitiveBase::CastRay( Line3D *line, Normal3D *normal ) { Check_Object(this); Check_Object(line); Check_Pointer(normal); STOP(("Not implemented")); return false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRShape* MidLevelRenderer::CreateIndexedIcosahedron(IcoInfo& icoInfo, Stuff::DynamicArrayOf *states) { switch(icoInfo.type) { case MLR_I_PMeshClassID: return CreateIndexedIcosahedron_NoColor_NoLit(icoInfo, &(*states)[0]); break; case MLR_I_C_PMeshClassID: return CreateIndexedIcosahedron_Color_NoLit(icoInfo, &(*states)[0]); break; case MLR_I_L_PMeshClassID: return CreateIndexedIcosahedron_Color_Lit(icoInfo, &(*states)[0]); break; case MLR_I_DT_PMeshClassID: return CreateIndexedIcosahedron_NoColor_NoLit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_C_DT_PMeshClassID: return CreateIndexedIcosahedron_Color_NoLit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_L_DT_PMeshClassID: return CreateIndexedIcosahedron_Color_Lit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_DeT_PMeshClassID: return CreateIndexedIcosahedron_NoColor_NoLit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_C_DeT_PMeshClassID: return CreateIndexedIcosahedron_Color_NoLit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_L_DeT_PMeshClassID: return CreateIndexedIcosahedron_Color_Lit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_TMeshClassID: return CreateIndexedTriIcosahedron_NoColor_NoLit(icoInfo, &(*states)[0]); break; case MLR_I_C_TMeshClassID: return CreateIndexedTriIcosahedron_Color_NoLit(icoInfo, &(*states)[0]); break; case MLR_I_L_TMeshClassID: return CreateIndexedTriIcosahedron_Color_Lit(icoInfo, &(*states)[0]); break; case MLR_I_DeT_TMeshClassID: return CreateIndexedTriIcosahedron_NoColor_NoLit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_C_DeT_TMeshClassID: return CreateIndexedTriIcosahedron_Color_NoLit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_L_DeT_TMeshClassID: return CreateIndexedTriIcosahedron_Color_Lit_DetTex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_DT_TMeshClassID: return CreateIndexedTriIcosahedron_NoColor_NoLit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_C_DT_TMeshClassID: return CreateIndexedTriIcosahedron_Color_NoLit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; case MLR_I_L_DT_TMeshClassID: return CreateIndexedTriIcosahedron_Color_Lit_2Tex(icoInfo, &(*states)[0], &(*states)[1]); break; } return NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // const char * MidLevelRenderer::IcoInfo::GetTypeName() { switch(type) { case MLR_I_PMeshClassID: return "not colored, unlit mesh"; break; case MLR_I_C_PMeshClassID: return "colored, unlit mesh"; break; case MLR_I_L_PMeshClassID: return "colored, lit mesh"; break; case MLR_I_DT_PMeshClassID: return "not colored, unlit mesh w/ 2 Tex"; break; case MLR_I_C_DT_PMeshClassID: return "colored, unlit mesh w/ 2 Tex"; break; case MLR_I_L_DT_PMeshClassID: return "colored, lit mesh w/ 2 Tex"; break; case MLR_I_MT_PMeshClassID: return "not colored, unlit mesh w/ 4 Tex"; break; case MLR_I_DeT_PMeshClassID: return "not colored, unlit mesh w/ DetTex"; break; case MLR_I_C_DeT_PMeshClassID: return "colored, unlit mesh w/ DetTex"; break; case MLR_I_L_DeT_PMeshClassID: return "colored, lit mesh w/ DetTex"; break; case MLR_I_TMeshClassID: return "not colored, unlit tri. mesh"; break; case MLR_I_C_TMeshClassID: return "colored, unlit tri. mesh"; break; case MLR_I_L_TMeshClassID: return "colored, lit tri. mesh"; break; case MLR_I_DeT_TMeshClassID: return "not colored, unlit tri. mesh w/ DetTex"; break; case MLR_I_C_DeT_TMeshClassID: return "colored, unlit tri. mesh w/ DetTex"; break; case MLR_I_L_DeT_TMeshClassID: return "colored, lit tri. mesh w/ DetTex"; break; case MLR_I_DT_TMeshClassID: return "not colored, unlit tri. mesh w/ 2 Tex"; break; case MLR_I_C_DT_TMeshClassID: return "colored, unlit tri. mesh w/ 2 Tex"; break; case MLR_I_L_DT_TMeshClassID: return "colored, lit tri. mesh w/ 2 Tex"; break; } return "mesh"; } //############################################################################# //##################### MLRPrimitiveBase__ClassData ##################### //############################################################################# void MLRPrimitiveBase__ClassData::TestInstance() { Verify(IsDerivedFrom(MLRPrimitiveBase::DefaultData)); }