Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1382 lines
35 KiB
C++

#include "MLRHeaders.hpp"
#include <MLR\MLRCulturShape.hpp>
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_HasAGPAvailable));
MLRState::SetMaxUV(static_cast<float>(gos_GetMachineInformation(gos_Info_GetMaximumUVSize, 256)));
MLRState::SetCurrentTextureSize(256);
if(MLRState::GetHasMaxUVs() && MLRState::GetMaxUV() < 32.0f)
{
gEnableLightMaps = 0;
}
MLRState::SetCanBumpEnvMap(0<gos_GetMachineInformation(gos_Info_CanBumpEnvMap));
MLRState::SetCanBumpDotMap(0<gos_GetMachineInformation(gos_Info_CanBumpDotMap));
if(gEnableMultiTexture!=0)
{
MLRState::SetMultitextureLightMap(0<gos_GetMachineInformation(gos_Info_CanMultitextureLightMap));
MLRState::SetMultitextureSpecularMap(0<gos_GetMachineInformation(gos_Info_CanMultitextureSpecularMap));
MLRState::SetMultitextureDetailMap(0<gos_GetMachineInformation(gos_Info_CanMultitextureDetail));
}
else
{
MLRState::SetMultitextureLightMap(false);
MLRState::SetMultitextureSpecularMap(false);
MLRState::SetMultitextureDetailMap(false);
}
if(tCounter++>5000)
{
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<Scalar> 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(i<culturShape->culturals.GetLength())
{
if(MLRCulturShape::lastUsedMesh >= MLRCulturShape::nrOfNaturalMeshes)
{
gos_PopCurrentHeap();
return;
}
int usedVertices = 0;
for(;i<culturShape->culturals.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<nrOfPoints;j++)
{
coords[j].Multiply(points[j], myOwnLittleWorld);
nTexCoords[j] = texCoords[j];
indices[j] = static_cast<BYTE>(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;i<icount;i++)
{
j+=length_array[i];
}
icount = j;
}
else
{
icount *= 3;
}
icount *= activeMesh->GetNumPasses();
}
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;i<dInfo->nrOfActiveLights;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;i<shape->numPrimitives;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;j<tbdp->nrOfActiveLights;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;i<icount;i++)
{
j+=length_array[i];
}
icount = j;
}
else
{
icount *= 3;
}
icount *= primitive->GetNumPasses();
}
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;j<primitive->GetNumPasses();j++)
{
sorter->DrawPrimitive(primitive, j);
}
}
}
}
else
{
primitive->TransformNoClip(
&shapeToClipMatrix,
&allVerticesToDraw,
fog ? &fogData : NULL,
paintMeColorDW
);
for(j=0;j<primitive->GetNumPasses();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;i<shape->numPrimitives;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;k<primitive->GetNumPasses();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;j<tbdp->nrOfActiveLights;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;i<icount;i++)
{
j+=length_array[i];
}
icount = j;
}
else
{
icount *= 3;
}
icount *= primitive->GetNumPasses();
}
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;j<primitive->GetNumPasses();j++)
{
sorter->DrawPrimitive(primitive, j);
}
}
}
}
else
{
primitive->TransformNoClip(&shapeToClipMatrix, &allVerticesToDraw, NULL, paintMeColorDW);
for(j=0;j<primitive->GetNumPasses();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;i<dInfo->nrOfQuads;i++)
{
if(dInfo->onOrOff[i] == true)
{
dInfo->currentNrOfQuads += 4;
for(;j<dInfo->currentNrOfQuads;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);
}