#include "MLRHeaders.hpp" #include extern DWORD gShowBirdView, gEnableDetailTexture, gEnableMultiTexture, gEnableLightMaps, gEnableCulturals; DrawShapeInformation::DrawShapeInformation() { shape = NULL; state = NULL; shapeToWorld = NULL; worldToShape = NULL; activeLights = NULL; nrOfActiveLights = 0; clippingFlags.SetClippingState(0); paintMeColor = NULL; }; DrawScalableShapeInformation::DrawScalableShapeInformation() : DrawShapeInformation() { scaling = NULL; } DrawEffectInformation::DrawEffectInformation() { effect = NULL; state = NULL; effectToWorld = NULL; #if 0 activeLights = NULL; nrOfActiveLights = 0; #endif clippingFlags.SetClippingState(0); }; DrawScreenQuadsInformation::DrawScreenQuadsInformation() { coords = NULL; colors = NULL; texCoords = NULL; onOrOff = NULL; nrOfQuads = 0; }; int tCounter = 0; //############################################################################# //########################### MLRClipper ################################ //############################################################################# MLRClipper::ClassData* MLRClipper::DefaultData = NULL; bool Immediate_Draw = false; static bool __stdcall CheckImmediateDraw() { return Immediate_Draw; } static void __stdcall EnableImmediateDraw() { Immediate_Draw=!Immediate_Draw; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLRClipperClassID, "MidLevelRenderer::MLRClipper", RegisteredClass::DefaultData ); Register_Object(DefaultData); AddDebuggerMenuItem("Libraries\\MLR\\Immediate Draw", CheckImmediateDraw, EnableImmediateDraw, NULL ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRClipper::MLRClipper(AndyDisplay *ad, MLRSorter *s): RegisteredClass(DefaultData), display(ad) { Verify(gos_GetCurrentHeap() == ClipperHeap); frameRate = 0; usedTime = 0.0f; nowTime = 0.0f; sorter = s; // camMatrix; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRClipper::~MLRClipper() { if(sorter) { Unregister_Object(sorter); delete sorter; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::UpdateClipperCameraData( const LinearMatrix4D &camera_to_world, const Matrix4D &cameraToClip ) { Check_Object(this); Check_Object(&cameraToClip); cameraToClipMatrix = cameraToClip; cameraToWorldMatrix = camera_to_world; worldToCameraMatrix.Invert(cameraToWorldMatrix); worldToClipMatrix.Multiply(worldToCameraMatrix, cameraToClip); cameraPosition = cameraToWorldMatrix; UnitVector3D v; cameraToWorldMatrix.GetLocalForwardInWorld(&v); cameraDirection.Normalize(v); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::StartDraw ( const LinearMatrix4D &camera_to_world, const Matrix4D &cameraToClip, const RGBAColor &, const RGBAColor *background_color, const MLRState &default_state, const Scalar *z_value, float top, float left, float bottom, float right ) { Check_Object(this); Check_Object(&cameraToClip); cameraToClipMatrix = cameraToClip; // // No detail under software rasterizer // if(Environment.Renderer == 3) { gEnableDetailTexture = 0; } MLRState::SetAGPAvailable(0(gos_GetMachineInformation(gos_Info_GetMaximumUVSize, 256))); MLRState::SetCurrentTextureSize(256); if(MLRState::GetHasMaxUVs() && MLRState::GetMaxUV() < 32.0f) { gEnableLightMaps = 0; } MLRState::SetCanBumpEnvMap(05000) { tCounter = 0; } // // Make viewport the whole screen // gos_PushCurrentHeap(ClipperHeap); Scalar z = 1.0f; DWORD back_color = 0; bool fill = false, clear = false; if (z_value) { Check_Pointer(z_value); z = *z_value; fill = true; } if (background_color) { Check_Pointer(background_color); back_color = GOSCopyColor(background_color); clear = true; MLRState::fogColor = back_color; } SetViewportScalars(top, left, bottom, right); gos_SetupViewport( fill, z, clear, back_color, top, left, bottom, right ); SetDefaultRenderStates(); if(cameraToClip(3, 2)>SMALL || cameraToClip(3, 2)<-SMALL) { sorter->SetFarClipReciprocal((1.0f-cameraToClip(2, 2))/cameraToClip(3, 2)); } sorter->StartDraw(default_state); cameraToWorldMatrix = camera_to_world; worldToCameraMatrix.Invert(cameraToWorldMatrix); // reset the CulturalShape containers MLRCulturShape::lastUsedMesh = 0; MLRCulturShape::lastUsedVertex = 0; #ifdef LAB_ONLY if(gShowBirdView && Matrix4D::Identity != cameraToClip) { static YawPitchRange Camera_Direction(-Pi_Over_6, 0.0f, 15.0f); static Vector2DOf Camera_Shift(0.0f, 0.0f); static LinearMatrix4D birdsEye = LinearMatrix4D::Identity; // //--------------- // Read the mouse //--------------- // int x_delta, y_delta; DWORD buttons; gos_GetMouseInfo(NULL, NULL, &x_delta, &y_delta, NULL, &buttons); Scalar x_speed = x_delta * 0.01f, y_speed = y_delta * 0.01f; // //------------------------------------------------------ // If the left Ctrl button is held down, move the camera //------------------------------------------------------ // gosEnum_KeyStatus status = gos_GetKeyStatus(KEY_LCONTROL); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Direction.pitch += y_speed; Camera_Direction.yaw -= x_speed; } // //------------------------------------------------------ // If the left Shift button is held down, pan the camera //------------------------------------------------------ // status = gos_GetKeyStatus(KEY_LSHIFT); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Shift.x += x_speed; Camera_Shift.y += y_speed; } // //---------------------------------------------------------------- // If the left Alt button is held down, zoom the camera in and out //---------------------------------------------------------------- // status = gos_GetKeyStatus(KEY_LMENU); if (status != KEY_FREE && status != KEY_RELEASED) { Camera_Direction.range *= 1.0f + 3.0f*y_speed; Camera_Direction.range = Camera_Direction.range > 0.0f ? Camera_Direction.range : 0.0f; } // //---------------------- // Set the camera matrix //---------------------- // birdsEye.BuildRotation( EulerAngles(Camera_Direction.pitch, Camera_Direction.yaw, 0.0f) ); UnitVector3D world_left, world_up; birdsEye.GetLocalLeftInWorld(&world_left); birdsEye.GetLocalUpInWorld(&world_up); Point3D translation(Camera_Direction); translation.AddScaled(translation, world_left, Camera_Shift.x); translation.AddScaled(translation, world_up, Camera_Shift.y); birdsEye.BuildTranslation(translation); LinearMatrix4D worldToBird = LinearMatrix4D::Identity; worldToBird.Multiply(worldToCameraMatrix, birdsEye); worldToCameraMatrix = worldToBird; // push the far clip out Scalar near_clip, far_clip, left_clip, right_clip, top_clip, bottom_clip; Matrix4D birdToClip; cameraToClip.GetPerspective(&near_clip, &far_clip, &left_clip, &right_clip, &top_clip, &bottom_clip); birdToClip.SetPerspective( near_clip, far_clip+2*Camera_Direction.range, left_clip, right_clip, top_clip, bottom_clip ); worldToClipMatrix.Multiply(worldToCameraMatrix, birdToClip); } else #endif worldToClipMatrix.Multiply(worldToCameraMatrix, cameraToClip); cameraPosition = cameraToWorldMatrix; UnitVector3D v; cameraToWorldMatrix.GetLocalForwardInWorld(&v); cameraDirection.Normalize(v); // Tell_Value(cameraPosition); MLRPrimitiveBase::InitializeDraw(); sorter->Reset(); allVerticesToDraw.Reset(); #ifdef CalDraw ToBeDrawnPrimitive::allVerticesToDraw = &allVerticesToDraw; #endif #ifdef LAB_ONLY if(gShowBirdView && Matrix4D::Identity != cameraToClip) { DrawShapeInformation drawShapeInfo; Scalar near_clip, far_clip, left_clip, right_clip, top_clip, bottom_clip; RGBAColor fruCol(0.0f, 0.5f, 0.0f, 0.5f); MLRState fruState; cameraToClip.GetPerspective(&near_clip, &far_clip, &left_clip, &right_clip, &top_clip, &bottom_clip); gos_PushCurrentHeap(ShapeHeap); drawShapeInfo.shape = new MLRShape(1); gos_PopCurrentHeap(); Register_Object(drawShapeInfo.shape); fruState.SetTextureHandle(0); fruState.SetRenderDeltaMask(MLRState::TextureMask); #ifdef OLDFOG fruState.SetFogMode(MLRState::DisableFogMode); #else fruState.SetFogMode(0); #endif fruState.SetZBufferCompareOn(); fruState.SetZBufferWriteOn(); fruState.SetBackFaceOff(); fruState.SetWireFrameMode(MLRState::WireFrameAddMode); fruState.SetFilterMode(MLRState::BiLinearFilterMode); fruState.SetAlphaMode(MLRState::AlphaInvAlphaMode); fruState.SetPriority(MLRState::PriorityCount-1); MLRPrimitiveBase *primitive = CreateIndexedViewFrustrum_Color_NoLit( &fruState, near_clip, far_clip, left_clip, right_clip, top_clip, bottom_clip, #if COLOR_AS_DWORD>0 GOSCopyColor(&fruCol) #else fruCol #endif ); drawShapeInfo.shape->Add(primitive); drawShapeInfo.clippingFlags.SetClippingState(0x3f); drawShapeInfo.shapeToWorld = &cameraToWorldMatrix; drawShapeInfo.worldToShape = &worldToCameraMatrix; DrawShape(&drawShapeInfo); drawShapeInfo.shape->DetachReference(); gos_SetRenderState( gos_State_Fog, 0); } #endif gos_PopCurrentHeap(); // // End timing function // } static AffineMatrix4D scaledShapeToWorld; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::DrawShape (DrawShapeInformation *dInfo) { Check_Object(this); // // Statistic timing function // MLR_RENDER("DrawShape"); Start_Timer(Shape_Setup_Time); gos_PushCurrentHeap(ClipperHeap); MLRShape *shape = dInfo->shape; Check_Object(shape); MLRPrimitiveBase *primitive = NULL; Matrix4D shapeToClipMatrix; shapeToClipMatrix = Matrix4D::Identity; if(shape->IsDerivedFrom(MLRCulturShape::DefaultData)) { if(MLRCulturShape::culturalRevolution!=NULL && gEnableCulturals!=0) { if(MLRCulturShape::lastUsedMesh >= MLRCulturShape::nrOfNaturalMeshes) { gos_PopCurrentHeap(); return; } MLRCulturShape *culturShape = Cast_Object(MLRCulturShape*, shape); shapeToClipMatrix.Multiply(*dInfo->shapeToWorld, worldToClipMatrix); dInfo->state.SetFogMode(0); dInfo->state.SetPriority(1); dInfo->state.SetAlphaMode(MLRState::AlphaInvAlphaMode); dInfo->state.SetRenderPermissionMask(dInfo->state.GetRenderPermissionMask() & ~MLRState::AlphaMask); culturShape->culturalRevolution->InitializePrimitives(true, dInfo->state); int i; Point3D sp; Normal3D np; Vector3D v; sp.x = culturShape->centerInWorldX; sp.y = cameraPosition.y; sp.z = culturShape->centerInWorldZ; v.Subtract(sp, cameraPosition); v.y = 0.0; sp.Multiply(cameraPosition, *dInfo->worldToShape); if( (culturShape->fadeOutEnd+culturShape->radius) * (culturShape->fadeOutEnd+culturShape->radius) > v.GetLengthSquared() ) // if( (culturShape->fadeOutEnd-culturShape->radius) * (culturShape->fadeOutEnd-culturShape->radius) < v.GetLengthSquared() ) { v.Multiply(cameraDirection, *dInfo->worldToShape); np.Normalize(v); // gos_GetViewport( &ViewportScalars::MulX, &ViewportScalars::MulY, &ViewportScalars::AddX, &ViewportScalars::AddY ); #ifdef LAB_ONLY if(gShowBirdView) { dInfo->clippingFlags = 0x3f; #ifdef OLDFOG dInfo->state.SetFogMode(MLRState::DisableFogMode); #else dInfo->state.SetFogMode(0); #endif dInfo->state.SetRenderPermissionMask ( dInfo->state.GetRenderPermissionMask() & ~MLRState::FogMask ); } #endif paintMeColorDW = GOSCopyColor(MLRCulturShape::isDayTime ? &MLRCulturShape::dayColor : &MLRCulturShape::nightColor); #if !COLOR_AS_DWORD paintMeColorF = MLRCulturShape::isDayTime ? MLRCulturShape::dayColor : MLRCulturShape::nightColor; #endif Stop_Timer(Shape_Setup_Time); i = 0; while(iculturals.GetLength()) { if(MLRCulturShape::lastUsedMesh >= MLRCulturShape::nrOfNaturalMeshes) { gos_PopCurrentHeap(); return; } int usedVertices = 0; for(;iculturals.GetLength();i++) { v.Subtract(culturShape->culturals[i].loc, sp); v.y = 0.0f; Scalar dist = v.GetLengthSquared(); if(dist > culturShape->fadeOutEnd*culturShape->fadeOutEnd) { continue; } Scalar scale = 1.0f; if(dist > culturShape->fadeOutStart*culturShape->fadeOutStart) { dist = Sqrt(dist) - culturShape->fadeOutStart; scale = 1.0f - dist/(culturShape->fadeOutEnd-culturShape->fadeOutStart); } RGBAColor fade = MLRCulturShape::isDayTime ? MLRCulturShape::dayColor : MLRCulturShape::nightColor; fade.alpha = scale; primitive = culturShape->culturalRevolution->allPrimitives[culturShape->culturals[i].type]; Check_Object(primitive); const Point3D *points = NULL; const Vector2DScalar *texCoords = NULL; int nrOfPoints, nrOfTexCoords; primitive->GetCoordData(&points, &nrOfPoints); primitive->GetTexCoordData(&texCoords, &nrOfTexCoords); Verify(nrOfPoints==nrOfTexCoords); if( MLRCulturShape::lastUsedVertex + usedVertices + nrOfPoints >= MLRCulturShape::nrOfNaturalMeshes*Limits::Max_Number_Vertices_Per_Mesh) { i = culturShape->culturals.GetLength(); break; } if(usedVertices + nrOfPoints > Limits::Max_Number_Vertices_Per_Mesh) { break; } LinearMatrix4D myOwnLittleWorld; myOwnLittleWorld = culturShape->culturals[i].loc; if(culturShape->culturals[i].yaw == 0xff) { v.y = 0.0f; v.Negate(v); myOwnLittleWorld.AlignLocalAxisToWorldVector(v, Z_Axis, Y_Axis, -1); } else { myOwnLittleWorld.BuildRotation(YawPitchRoll(2.0f*culturShape->culturals[i].yaw*Radians_Per_Degree, 0.0f, 0.0f)); } // myOwnLittleWorld(0,0) = scale; // myOwnLittleWorld(1,1) = scale; // myOwnLittleWorld(2,2) = scale; LinearMatrix4D myOwnLittleShape; Point3D *coords = MLRCulturShape::theNaturalCoords->GetData() + MLRCulturShape::lastUsedVertex + usedVertices; Vector2DScalar *nTexCoords = MLRCulturShape::theNaturalTexCoords->GetData() + MLRCulturShape::lastUsedVertex + usedVertices; BYTE *indices = MLRCulturShape::theNaturalIndicies->GetData() + MLRCulturShape::lastUsedVertex + usedVertices; ColorType *colors = MLRCulturShape::theNaturalColors->GetData() + MLRCulturShape::lastUsedVertex + usedVertices; #if COLOR_AS_DWORD >0 DWORD color = GOSCopyColor(&fade); #endif for(int j=0;j(usedVertices+j); #if COLOR_AS_DWORD >0 colors[j] = color; #else colors[j] = fade; #endif } usedVertices += nrOfPoints; // myOwnLittleShape.Invert(myOwnLittleWorld); } MLR_I_C_TMesh *activeMesh = NULL; if(usedVertices==0) { gos_PopCurrentHeap(); return; } else { activeMesh = (*MLRCulturShape::theNaturals)[MLRCulturShape::lastUsedMesh++]; } activeMesh->SetCoordData(MLRCulturShape::theNaturalCoords->GetData() + MLRCulturShape::lastUsedVertex, usedVertices); activeMesh->SetTexCoordData(MLRCulturShape::theNaturalTexCoords->GetData() + MLRCulturShape::lastUsedVertex, usedVertices); activeMesh->SetIndexData(MLRCulturShape::theNaturalIndicies->GetData() + MLRCulturShape::lastUsedVertex, usedVertices); activeMesh->SetColorData(MLRCulturShape::theNaturalColors->GetData() + MLRCulturShape::lastUsedVertex, usedVertices); activeMesh->SetSubprimitiveLengths(NULL, (int)(usedVertices*0.33333333333333333333333333333334f), false); activeMesh->SetReferenceState(culturShape->culturalRevolution->allPrimitives[0]->GetReferenceState()); activeMesh->CombineStates(dInfo->state); MLRCulturShape::lastUsedVertex += usedVertices; if(activeMesh->GetReferenceState().GetDrawNowMode()==MLRState::DrawNowOffMode && !Immediate_Draw) { Start_Timer(Shape_Setup_Time); ToBeDrawnPrimitive *tbdp = sorter->GetCurrentTBDP(); if(tbdp==NULL) { gos_PopCurrentHeap(); return; } Check_Pointer(tbdp); tbdp->type = 1; tbdp->primitive = activeMesh; Verify(activeMesh->GetNumPasses() < 2); tbdp->state = activeMesh->GetCurrentState(); // tbdp->cameraPosition.Multiply(sp, myOwnLittleShape); // tbdp->cameraDirection.Multiply(np, myOwnLittleShape); tbdp->cameraPosition = cameraPosition; tbdp->cameraDirection = cameraDirection; tbdp->clippingFlags = dInfo->clippingFlags; Check_Object(&tbdp->shapeToClipMatrix); // tbdp->shapeToClipMatrix.Multiply(myOwnLittleWorld, shapeToClipMatrix); tbdp->shapeToClipMatrix = shapeToClipMatrix; tbdp->worldToShape = *dInfo->worldToShape; #if COLOR_AS_DWORD >0 // tbdp->paintMeColor = GOSCopyColor(&fade); tbdp->paintMeColor = GOSCopyColor(dInfo->paintMeColor); #else // tbdp->paintMeColor = fade; tbdp->paintMeColor = dInfo->paintMeColor; #endif tbdp->nrOfActiveLights = 0; sorter->IncreaseTBDPCounter(); Stop_Timer(Shape_Setup_Time); } else { #ifdef LAB_ONLY const BYTE *length_array; const Point3D *coord_array; int vcount, icount; activeMesh->GetSubprimitiveLengths(&length_array, &icount); activeMesh->GetCoordData(&coord_array, &vcount); if(icount==0) { icount = 3 * activeMesh->GetNumPrimitives() * activeMesh->GetNumPasses(); } else { if(length_array != NULL) { int j=0; for(int i=0;iGetNumPasses(); } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLast() + vcount) { SPEWALWAYS((0, "Not drawing ScreenQuads. Too many vertices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLastIndex() + icount) { SPEWALWAYS((0, "Not drawing MLR-mesh. Too many indices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } #endif // Matrix4D myOwnLittleClipMatrix; // myOwnLittleClipMatrix.Multiply(myOwnLittleWorld, shapeToClipMatrix); if(activeMesh->TransformAndClip( &shapeToClipMatrix, dInfo->clippingFlags, &allVerticesToDraw, NULL, paintMeColorDW )) { if(activeMesh->GetVisible()) { Verify(activeMesh->GetNumPasses() < 2); sorter->DrawPrimitive(activeMesh); } } #ifdef LAB_ONLY Set_Statistic(Number_Of_Primitives, Number_Of_Primitives+1); if(activeMesh->IsDerivedFrom(MLRIndexedPrimitiveBase::DefaultData)) { const Point3D *coords; const BYTE *indices; int nr; (Cast_Pointer(MLRIndexedPrimitiveBase*, activeMesh))->GetIndexData(&indices, &nr); NumAllIndices += nr; activeMesh->GetCoordData(&coords, &nr); NumAllVertices += nr; Set_Statistic(Index_Over_Vertex_Ratio, (Scalar)NumAllIndices/(Scalar)NumAllVertices); } #endif } } } } } else { if(dInfo->nrOfActiveLights > Limits::Max_Number_Of_Lights_Per_Primitive) { dInfo->nrOfActiveLights = Limits::Max_Number_Of_Lights_Per_Primitive; } shapeToClipMatrix.Multiply(*dInfo->shapeToWorld, worldToClipMatrix); shape->InitializePrimitives(true, dInfo->state); int i, j; Point3D sp; Normal3D np; Vector3D v; int nrOfLightMaps = 0; sp.Multiply(cameraPosition, *dInfo->worldToShape); v.Multiply(cameraDirection, *dInfo->worldToShape); np.Normalize(v); for(i=0;inrOfActiveLights;i++) { dInfo->activeLights[i]->SetLightToShapeMatrix(*dInfo->worldToShape); nrOfLightMaps += (dInfo->activeLights[i]->GetLightMap()) ? 1 : 0; } if(!gEnableLightMaps) { nrOfLightMaps = 0; } // gos_GetViewport( &ViewportScalars::MulX, &ViewportScalars::MulY, &ViewportScalars::AddX, &ViewportScalars::AddY ); #ifdef LAB_ONLY if(gShowBirdView) { dInfo->clippingFlags = 0x3f; #ifdef OLDFOG dInfo->state.SetFogMode(MLRState::DisableFogMode); #else dInfo->state.SetFogMode(0); #endif dInfo->state.SetRenderPermissionMask ( dInfo->state.GetRenderPermissionMask() & ~MLRState::FogMask ); } #endif if(dInfo->paintMeColor!=NULL) { #if COLOR_AS_DWORD paintMeColorDW = GOSCopyColor(dInfo->paintMeColor); #else paintMeColorF = *dInfo->paintMeColor; paintMeColorDW = GOSCopyColor(dInfo->paintMeColor); #endif } Stop_Timer(Shape_Setup_Time); for(i=0;inumPrimitives;i++) { primitive = shape->allPrimitives[i]; Check_Object(primitive); if(primitive->GetCurrentState().GetDrawNowMode()==MLRState::DrawNowOffMode && !Immediate_Draw) { Start_Timer(Shape_Setup_Time); ToBeDrawnPrimitive *tbdp = sorter->GetCurrentTBDP(); if(tbdp==NULL) { gos_PopCurrentHeap(); return; } Check_Pointer(tbdp); tbdp->type = 0; tbdp->primitive = primitive; tbdp->state = primitive->GetCurrentState(); tbdp->cameraPosition = sp; tbdp->cameraDirection = np; tbdp->clippingFlags = dInfo->clippingFlags; Check_Object(&tbdp->shapeToClipMatrix); tbdp->shapeToClipMatrix = shapeToClipMatrix; tbdp->worldToShape = *dInfo->worldToShape; #if COLOR_AS_DWORD==0 Check_Object(dInfo->paintMeColor); #endif if(dInfo->paintMeColor) { tbdp->paintMeColor = GOSCopyColor(dInfo->paintMeColor); } else { #if COLOR_AS_DWORD>0 tbdp->paintMeColor = 0xffffffff; #else tbdp->paintMeColor = RGBAColor::White; #endif } Verify(dInfo->nrOfActiveLights <= Limits::Max_Number_Of_Lights_Per_Primitive); tbdp->nrOfActiveLights = dInfo->nrOfActiveLights; for(j=0;jnrOfActiveLights;j++) { Check_Object(dInfo->activeLights[j]); tbdp->activeLights[j] = dInfo->activeLights[j]; } sorter->IncreaseTBDPCounter(); Stop_Timer(Shape_Setup_Time); } else { #ifdef LAB_ONLY const BYTE *length_array; const Point3D *coord_array; int vcount, icount; primitive->GetSubprimitiveLengths(&length_array, &icount); primitive->GetCoordData(&coord_array, &vcount); if(icount==0) { icount = 3 * primitive->GetNumPrimitives() * primitive->GetNumPasses(); } else { if(length_array != NULL) { int j=0; for(int i=0;iGetNumPasses(); } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLast() + vcount) { SPEWALWAYS((0, "Not drawing ScreenQuads. Too many vertices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLastIndex() + icount) { SPEWALWAYS((0, "Not drawing MLR-mesh. Too many indices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } #endif if(nrOfLightMaps) { MLRLightMap::SetDrawData ( &allVerticesToDraw, &shapeToClipMatrix, dInfo->clippingFlags, dInfo->state ); } if(primitive->FindBackFace(sp, np)) { primitive->Lighting(dInfo->activeLights, dInfo->nrOfActiveLights); FogData fogData; bool fog = primitive->FogMesh(dInfo->worldToShape, &sp, &fogData); if(dInfo->clippingFlags.GetClippingState() != 0) { if(primitive->TransformAndClip( &shapeToClipMatrix, dInfo->clippingFlags, &allVerticesToDraw, fog ? &fogData : NULL, paintMeColorDW ) ) { if(primitive->GetVisible()) { for(j=0;jGetNumPasses();j++) { sorter->DrawPrimitive(primitive, j); } } } } else { primitive->TransformNoClip( &shapeToClipMatrix, &allVerticesToDraw, fog ? &fogData : NULL, paintMeColorDW ); for(j=0;jGetNumPasses();j++) { sorter->DrawPrimitive(primitive, j); } } #ifdef LAB_ONLY Set_Statistic(Number_Of_Primitives, Number_Of_Primitives+1); if(primitive->IsDerivedFrom(MLRIndexedPrimitiveBase::DefaultData)) { const Point3D *coords; const BYTE *indices; int nr; (Cast_Pointer(MLRIndexedPrimitiveBase*, primitive))->GetIndexData(&indices, &nr); NumAllIndices += nr; primitive->GetCoordData(&coords, &nr); NumAllVertices += nr; Set_Statistic(Index_Over_Vertex_Ratio, (Scalar)NumAllIndices/(Scalar)NumAllVertices); } #endif if(nrOfLightMaps) { MLRLightMap::DrawLightMaps(sorter, false); } } } } } // // End timing function // gos_PopCurrentHeap(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::DrawScalableShape (DrawScalableShapeInformation *dInfo) { Check_Object(this); // // Statistic timing function // MLR_RENDER("DrawScalableShape"); Start_Timer(Shape_Setup_Time); MLRShape *shape = dInfo->shape; MLRPrimitiveBase *primitive = NULL; Matrix4D shapeToClipMatrix; shapeToClipMatrix.Multiply(*dInfo->shapeToWorld, worldToClipMatrix); shape->InitializePrimitives(true, dInfo->state, 1); if(dInfo->scaling != NULL) { LinearMatrix4D scale = LinearMatrix4D::Identity; scale(0,0) = dInfo->scaling->x; scale(1,1) = dInfo->scaling->y; scale(2,2) = dInfo->scaling->z; scaledShapeToWorld.Multiply(scale, *dInfo->shapeToWorld); shapeToClipMatrix.Multiply(scaledShapeToWorld, worldToClipMatrix); } else { shapeToClipMatrix.Multiply(*dInfo->shapeToWorld, worldToClipMatrix); } int i, j; #ifdef LAB_ONLY if(gShowBirdView) { dInfo->clippingFlags = 0x3f; } #endif Stop_Timer(Shape_Setup_Time); for(i=0;inumPrimitives;i++) { primitive = shape->allPrimitives[i]; Check_Object(primitive); #ifdef LAB_ONLY Set_Statistic(Number_Of_Primitives, Number_Of_Primitives+1); #endif if(primitive->GetCurrentState().GetDrawNowMode()==MLRState::DrawNowOffMode && !Immediate_Draw) { Start_Timer(Shape_Setup_Time); for(int k=0;kGetNumPasses();k++) { ToBeDrawnPrimitive *tbdp = sorter->GetCurrentTBDP(); if(tbdp==NULL) { return; } Check_Pointer(tbdp); tbdp->type = 1; tbdp->primitive = primitive; tbdp->state = primitive->GetCurrentState(); tbdp->cameraPosition = Point3D::Identity; tbdp->cameraDirection = UnitVector3D(1.0f, 0.0f, 0.0f); tbdp->clippingFlags = dInfo->clippingFlags; Check_Object(&tbdp->shapeToClipMatrix); tbdp->shapeToClipMatrix = shapeToClipMatrix; tbdp->worldToShape = LinearMatrix4D::Identity; #if COLOR_AS_DWORD==0 Check_Object(dInfo->paintMeColor); #endif if(dInfo->paintMeColor) { tbdp->paintMeColor = GOSCopyColor(dInfo->paintMeColor); } else { #if COLOR_AS_DWORD>0 tbdp->paintMeColor = 0xffffffff; #else tbdp->paintMeColor = RGBAColor::White; #endif } Verify(dInfo->nrOfActiveLights <= Limits::Max_Number_Of_Lights_Per_Primitive); tbdp->nrOfActiveLights = dInfo->nrOfActiveLights; for(j=0;jnrOfActiveLights;j++) { Check_Object(dInfo->activeLights[j]); tbdp->activeLights[j] = dInfo->activeLights[j]; } sorter->IncreaseTBDPCounter(); } Stop_Timer(Shape_Setup_Time); } else { #ifdef LAB_ONLY const BYTE *length_array; const Point3D *coord_array; int vcount, icount; primitive->GetSubprimitiveLengths(&length_array, &icount); primitive->GetCoordData(&coord_array, &vcount); if(icount==0) { icount = 3 * primitive->GetNumPrimitives() * primitive->GetNumPasses(); } else { if(length_array != NULL) { int j=0; for(int i=0;iGetNumPasses(); } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLast() + vcount) { SPEWALWAYS((0, "Not drawing ScreenQuads. Too many vertices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw.GetLastIndex() + icount) { SPEWALWAYS((0, "Not drawing MLR-mesh. Too many indices! Raid a bug to Art!")); gos_PopCurrentHeap(); return; } #endif #if COLOR_AS_DWORD==0 Check_Object(dInfo->paintMeColor); #endif if(dInfo->clippingFlags.GetClippingState() != 0) { if(primitive->TransformAndClip(&shapeToClipMatrix, dInfo->clippingFlags, &allVerticesToDraw, NULL, paintMeColorDW)) { if(primitive->GetVisible()) { for(j=0;jGetNumPasses();j++) { sorter->DrawPrimitive(primitive, j); } } } } else { primitive->TransformNoClip(&shapeToClipMatrix, &allVerticesToDraw, NULL, paintMeColorDW); for(j=0;jGetNumPasses();j++) { sorter->DrawPrimitive(primitive, j); } } } } // // End timing function // } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::DrawEffect (DrawEffectInformation *dInfo) { // // Statistic timing function // Check_Object(this); Check_Object(dInfo); Check_Object(dInfo->effect); #ifdef LAB_ONLY if(gShowBirdView) { dInfo->clippingFlags = 0x3f; } #endif if(dInfo->state.GetDrawNowMode()==MLRState::DrawNowOffMode && !Immediate_Draw) { ToBeDrawnPrimitive *tbdp = sorter->GetCurrentTBDP(); if(tbdp==NULL) { return; } Check_Pointer(tbdp); tbdp->type = 2; Check_Object(dInfo->effect); tbdp->primitive = dInfo->effect; tbdp->state = dInfo->state; tbdp->cameraPosition; tbdp->cameraDirection; tbdp->clippingFlags = dInfo->clippingFlags; tbdp->shapeToClipMatrix.Multiply(*dInfo->effectToWorld, worldToClipMatrix); tbdp->worldToShape = LinearMatrix4D::Identity; tbdp->allVerticesToDraw = &allVerticesToDraw; tbdp->nrOfActiveLights = 0; #if COLOR_AS_DWORD>0 tbdp->paintMeColor = 0xffffffff; #else tbdp->paintMeColor = RGBAColor::White; #endif sorter->IncreaseTBDPCounter(); } else { dInfo->effect->SetEffectToClipMatrix(dInfo->effectToWorld, &worldToClipMatrix); dInfo->effect->Draw(dInfo, &allVerticesToDraw, sorter); } // // End timing function // } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::DrawScreenQuads (DrawScreenQuadsInformation *dInfo) { // // Statistic timing function // Check_Object(this); Check_Object(dInfo); #ifdef LAB_ONLY if(Limits::Max_Number_Vertices_Per_Frame + 4*Limits::Max_Number_ScreenQuads_Per_Frame < allVerticesToDraw.GetLast() + dInfo->nrOfQuads * 4) { SPEWALWAYS((0, "Not drawing ScreenQuads. Too many vertices! Raid a bug to Art!")); return; } #endif // gos_GetViewport( &ViewportScalars::MulX, &ViewportScalars::MulY, &ViewportScalars::AddX, &ViewportScalars::AddY ); GOSVertex *vertices = allVerticesToDraw.GetActualVertexPool(); int i, j; dInfo->currentNrOfQuads = 0; for(i=0,j=0;inrOfQuads;i++) { if(dInfo->onOrOff[i] == true) { dInfo->currentNrOfQuads += 4; for(;jcurrentNrOfQuads;j++) { int offset = (i<<2) + (j&3); Verify(dInfo->coords[offset].x >= 0.0f && dInfo->coords[offset].x <= dInfo->coords[offset].w ); Verify(dInfo->coords[offset].y >= 0.0f && dInfo->coords[offset].y <= dInfo->coords[offset].w ); Verify(dInfo->coords[offset].z >= 0.0f && dInfo->coords[offset].z <= dInfo->coords[offset].w ); vertices[j].x = (1.0f-dInfo->coords[offset].x)*ViewportScalars::MulX + ViewportScalars::AddX; vertices[j].y = (1.0f-dInfo->coords[offset].y)*ViewportScalars::MulY + ViewportScalars::AddY; vertices[j].z = dInfo->coords[offset].z; vertices[j].rhw = dInfo->coords[offset].w; vertices[j].argb = GOSCopyColor(dInfo->colors + offset); vertices[j].u = dInfo->texCoords[offset][0]; vertices[j].v = dInfo->texCoords[offset][1]; } } } if(j>0) { allVerticesToDraw.Increase(j); sorter->AddScreenQuads(vertices, dInfo); } // // End timing function // } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRClipper::Clear (unsigned int flags) { Check_Object(this); }