Files
firestorm/Gameleap/code/mw4/Libraries/mlr/MLRPrimitiveBase.hpp
T
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

655 lines
16 KiB
C++

#pragma once
#define MLR_MLRPRIMITIVEBASE_HPP
#include <MLR\MLR.hpp>
#include <MLR\GOSVertexPool.hpp>
namespace MidLevelRenderer {
struct ClipPolygon2;
struct DataStorage {
Stuff::DynamicArrayOf<BYTE> index;
Stuff::DynamicArrayOf<BYTE> lengths;
Stuff::DynamicArrayOf<Stuff::Point3D> coords;
Stuff::DynamicArrayOf<Vector2DScalar> texCoords;
Stuff::DynamicArrayOf<ColorType> colors;
Stuff::DynamicArrayOf<Stuff::Vector3D> normals;
};
class MLRPrimitiveBase__ClassData;
class MLRTexture;
class MLRLight;
class MLRClippingState;
extern Stuff::ReadOnlyArrayOf<BYTE> temp_lengths;
//##########################################################################
//#################### MLRPrimitiveBase ##############################
//##########################################################################
// this is the abstract base class for all geometry. it has contains geometry
// with one and only one renderer state !!!
class _declspec(novtable) MLRPrimitiveBase:
public Stuff::RegisteredClass
{
friend class MLRShape;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void
InitializeClass();
static void
TerminateClass();
typedef MLRPrimitiveBase__ClassData ClassData;
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
MLRPrimitiveBase(
ClassData *class_data,
Stuff::MemoryStream *stream,
int version
);
~MLRPrimitiveBase();
public:
MLRPrimitiveBase(ClassData *class_data);
typedef MLRPrimitiveBase*
(*Factory)(
Stuff::MemoryStream *stream,
int version
);
static MLRPrimitiveBase*
Make(
Stuff::MemoryStream *stream,
int version
);
virtual void
Save(Stuff::MemoryStream *stream);
// Subprimitves are units in which this geometry is split off
// ie. nr of polygons in a polygon mesh or number of tripstrips
// in a tristriped mesh, every of this subprimitves has another
// number which is type specific
// ie. number of vertices in a polygon or number of vertices in
// a tristrip
// the data for the coord/color/texcoord/normal or index
// ARE IN THIS ORDER
virtual int
GetNumPrimitives() = 0;
virtual void
SetSubprimitiveLengths(
const BYTE *length_array,
int subprimitive_count,
bool setFace=true
) = 0;
// returns the number of subprimitives
virtual void
GetSubprimitiveLengths(const BYTE **length_array, int*) = 0;
// ==============================================================
virtual void SetReferenceState(const MLRState& _state, int=0)
{ Check_Object(this); referenceState = _state; };
virtual const MLRState&
GetReferenceState(int=0) const
{ Check_Object(this); return referenceState; };
virtual const MLRStateBase&
GetCurrentState(int=0) const
{ Check_Object(this); return state; };
virtual void
CombineStates (const MLRState& master)
{ Check_Object(this); state.CombineIntoBase(master, referenceState); };
int
GetNumVertices()
{ Check_Object(this); return coords.GetLength(); }
virtual void
SetCoordData(
const Stuff::Point3D *array,
int point_count
);
virtual void
GetCoordData(
const Stuff::Point3D **array,
int *point_count
);
virtual void
SetTexCoordData(
const Vector2DScalar *array,
int point_count
);
virtual void
GetTexCoordData(
const Vector2DScalar **array,
int *point_count
);
// is to call befor clipping, parameter: camera point
virtual int FindBackFace(const Stuff::Point3D&, const Stuff::Normal3D&) = 0;
virtual void Lighting(MLRLight* const*, int nrLights, BYTE=3) = 0;
virtual DWORD CenterLighting(MLRLight* const*, int nrLights, BYTE=3) = 0;
static void InitializeDraw();
virtual void InitializeDrawPrimitive(BYTE, int=0);
virtual int GetVisible ()
{ Check_Object(this); return visible; }
virtual GOSVertex*
GetGOSVertices(int=0)
{ Check_Object(this); return gos_vertices; }
int
GetNumGOSVertices()
{ Check_Object(this); return numGOSVertices; }
virtual GOSVertex2UV*
GetGOSVertices2UV(int=0)
{ Check_Object(this); return NULL; }
virtual GOSVertex3UV*
GetGOSVertices3UV(int=0)
{ Check_Object(this); return NULL; }
virtual DWORD
GetTexture2()
{ Check_Object(this); return 0; }
virtual DWORD
GetTexture3()
{ Check_Object(this); return 0; }
int
GetSortDataMode()
{ Check_Object(this); return drawMode; }
virtual bool
CastRay(
Stuff::Line3D *line,
Stuff::Normal3D *normal
);
virtual void
PaintMe(const ColorType *paintMe) = 0;
virtual int
TransformAndClip(Stuff::Matrix4D*, MLRClippingState, GOSVertexPool*, FogData*, DWORD=0xffffffff, bool=false) = 0;
virtual void
TransformNoClip(Stuff::Matrix4D*, GOSVertexPool*, FogData*, DWORD=0xffffffff, bool=false) = 0;
virtual int
GetNumPasses()
{ Check_Object(this); return passes; }
virtual void
CleanMe()
{ Check_Object(this); }
virtual void
HurtMe(const Stuff::LinearMatrix4D&, Stuff::Scalar radius)
{ Check_Object(this); }
virtual MLRPrimitiveBase*
HurtMe(const Stuff::LinearMatrix4D&, Stuff::Scalar radius, MLRTexture*)
{ Check_Object(this); return NULL; }
virtual void
DrawMyShadow(const Stuff::LinearMatrix4D&, Stuff::UnitVector3D&, Stuff::Scalar, DWORD=0xff800000)
{ Check_Object(this); return; }
virtual bool
FogMesh(const Stuff::LinearMatrix4D *worldToShape, const Stuff::Point3D *cameraPos, FogData *fogData)
{ Check_Object(this); return false; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This functions using the static buffers
//
void
SetClipCoord(const Stuff::Point3D &point, int index)
{
Check_Object(this); Verify(clipExtraCoords->GetLength() > index);
(*clipExtraCoords)[index].x = point.x;
(*clipExtraCoords)[index].y = point.y;
(*clipExtraCoords)[index].z = point.z;
}
void
FlashClipCoords(int num)
{
Check_Object(this); Verify(clipExtraCoords->GetLength() > num);
dataStore->coords.SetLength(num);
Stuff::Point3D *c = dataStore->coords.GetData();
for(int i=0;i<num;i++)
{
c[i].x = (*clipExtraCoords)[i].x;
c[i].y = (*clipExtraCoords)[i].y;
c[i].z = (*clipExtraCoords)[i].z;
}
SetCoordData(dataStore->coords.GetData(), num);
}
void
SetClipTexCoord(const Vector2DScalar &uvs, int index)
{
Check_Object(this); Verify(clipExtraTexCoords->GetLength() > index);
(*clipExtraTexCoords)[index] = uvs;
}
void
FlashClipTexCoords(int num)
{
Check_Object(this); Verify(clipExtraTexCoords->GetLength() > num);
dataStore->texCoords.SetLength(num);
Mem_Copy(dataStore->texCoords.GetData(), clipExtraTexCoords->GetData(), sizeof(Vector2DScalar)*num, sizeof(Vector2DScalar)*num);
SetTexCoordData(dataStore->texCoords.GetData(), num);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// extra channel enum
//
enum ExtraChannel {
FogChannel = 0,
SpecularRedChannel,
MaxNumberOfExtraChannel
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Reference counting
//
public:
void
AttachReference()
{Check_Object(this); ++referenceCount;}
void
DetachReference()
{
Check_Object(this); Verify(referenceCount > 0);
if ((--referenceCount) == 0)
{
Unregister_Object(this);
delete this;
}
}
int
GetReferenceCount()
{return referenceCount;}
protected:
WORD
referenceCount;
WORD
numGOSVertices;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const;
void
GetExtend(Stuff::ExtentBox *box);
DataStorage *dataStore;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Fog data
//
public:
static void
SetFogTableEntry(int entry, Stuff::Scalar fogNearClip, Stuff::Scalar fogFarClip, Stuff::Scalar fogDensity);
static void
GetFogTableEntry(int entry, Stuff::Scalar * pfogNearClip, Stuff::Scalar * pfogFarClip, Stuff::Scalar * pfogDensity);
static Stuff::Scalar
fogTable[Limits::Max_Number_Of_FogStates][4];
protected:
virtual void
Transform(Stuff::Matrix4D*);
static ClipPolygon2 *clipBuffer;
BYTE visible; // primitive visibilty per frame
BYTE passes;
BYTE drawMode;
BYTE channelUse;
// int numPrimitives; // Number of primitives, e.g. - num quads
// Replaced by GetNumPrimitives
// int numVertices; // number of verts for stats and vert arrays
// Replaced by GetNumVertices
Stuff::ReadOnlyArrayOf<Stuff::Point3D> coords; // Base address of coordinate list
Stuff::ReadOnlyArrayOf<Vector2DScalar> texCoords; // Base address of texture coordinate list
static Stuff::DynamicArrayOf<Stuff::Vector4D> *transformedCoords;
static Stuff::DynamicArrayOf<ColorType> *clipExtraColors; // , Max_Number_Vertices_Per_Mesh
static Stuff::DynamicArrayOf<MLRClippingState> *clipPerVertex; // , Max_Number_Vertices_Per_Mesh
static Stuff::DynamicArrayOf<Stuff::Vector4D> *clipExtraCoords; // , Max_Number_Vertices_Per_Mesh
static Stuff::DynamicArrayOf<Vector2DScalar> *clipExtraTexCoords; // , Max_Number_Vertices_Per_Mesh
static Stuff::DynamicArrayOf<WORD> *clipExtraLength; // , Max_Number_Primitives_Per_Frame
MLRStateBase state;
MLRState referenceState;
GOSVertex *gos_vertices;
// WORD
// numGOSVertices; moved up for alignment reasons
static Stuff::DynamicArrayOf<BYTE> *extraChannels[2*MaxNumberOfExtraChannel];
};
struct IcoInfo {
int type;
int depth;
bool indexed;
Stuff::Scalar radius;
Stuff::Scalar all;
bool onOff;
const char *GetTypeName();
};
MLRShape*
CreateIndexedIcosahedron(
IcoInfo&,
Stuff::DynamicArrayOf<MLRState>*
);
//##########################################################################
//################### MLRPrimitiveBase__ClassData ####################
//##########################################################################
class MLRPrimitiveBase__ClassData:
public Stuff::RegisteredClass::ClassData
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
public:
MLRPrimitiveBase__ClassData(
Stuff::RegisteredClass::ClassID class_id,
const char* class_name,
Stuff::RegisteredClass::ClassData *parent_class,
MLRPrimitiveBase::Factory primitive_factory
):
RegisteredClass__ClassData(class_id, class_name, parent_class),
primitiveFactory(primitive_factory)
{}
MLRPrimitiveBase::Factory
primitiveFactory;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
public:
void
TestInstance();
};
struct ClipData2
{
Stuff::Vector4D *coords;
Stuff::RGBAColor *colors;
Vector2DScalar *texCoords;
MLRClippingState *clipPerVertex;
BYTE *extraChannel[MLRPrimitiveBase::MaxNumberOfExtraChannel];
WORD length;
};
struct ClipPolygon2
{
void Init(int);
void Destroy();
Stuff::DynamicArrayOf<Stuff::Vector4D> coords; // [Max_Number_Vertices_Per_Polygon]
Stuff::DynamicArrayOf<Stuff::RGBAColor> colors; //[Max_Number_Vertices_Per_Polygon];
Stuff::DynamicArrayOf<Vector2DScalar> texCoords; //[2*Max_Number_Vertices_Per_Polygon];
Stuff::DynamicArrayOf<MLRClippingState> clipPerVertex; //[Max_Number_Vertices_Per_Polygon];
Stuff::DynamicArrayOf<BYTE> extraChannel[MLRPrimitiveBase::MaxNumberOfExtraChannel]; //[Max_Number_Vertices_Per_Polygon];
};
#if 0 // still defined in "MLRPrimitive.hpp"
inline Stuff::Scalar
GetBC(int nr, const Stuff::Vector4D& v4d)
{
switch(nr)
{
case 0:
return (v4d.w - v4d.y);
case 1:
return v4d.y;
case 2:
return (v4d.w - v4d.x);
case 3:
return v4d.x;
case 4:
return v4d.z;
case 5:
return (v4d.w - v4d.z);
}
return 0.0f;
}
inline void
GetDoubleBC
(
int nr,
Stuff::Scalar& result1,
Stuff::Scalar& result2,
const Stuff::Vector4D& v4d1,
const Stuff::Vector4D& v4d2
)
{
switch(nr)
{
case 0:
result1 = (v4d1.w - v4d1.y);
result2 = (v4d2.w - v4d2.y);
break;
case 1:
result1 = v4d1.y;
result2 = v4d2.y;
break;
case 2:
result1 = (v4d1.w - v4d1.x);
result2 = (v4d2.w - v4d2.x);
break;
case 3:
result1 = v4d1.x;
result2 = v4d2.x;
break;
case 4:
result1 = v4d1.z;
result2 = v4d2.z;
break;
case 5:
result1 = (v4d1.w - v4d1.z);
result2 = (v4d2.w - v4d2.z);
break;
}
}
inline Stuff::Scalar
GetLerpFactor
(
int nr,
const Stuff::Vector4D& v4d1,
const Stuff::Vector4D& v4d2
)
{
Stuff::Scalar result1, result2;
switch(nr)
{
case 0:
result1 = (v4d1.w - v4d1.y);
result2 = (v4d2.w - v4d2.y);
break;
case 1:
result1 = v4d1.y;
result2 = v4d2.y;
break;
case 2:
result1 = (v4d1.w - v4d1.x);
result2 = (v4d2.w - v4d2.x);
break;
case 3:
result1 = v4d1.x;
result2 = v4d2.x;
break;
case 4:
result1 = v4d1.z;
result2 = v4d2.z;
break;
case 5:
result1 = (v4d1.w - v4d1.z);
result2 = (v4d2.w - v4d2.z);
break;
default:
result1 = 0.0f;
result2 = 0.0f;
Abort_Program("Invalid plane number used !");
break;
}
Verify(!Stuff::Close_Enough(result1, result2));
return result1 / (result1 - result2);
}
#endif
inline Stuff::Scalar
GetBC(int nr, const Stuff::Vector4D& v4d)
{
switch(nr)
{
case 0:
return (v4d.w - v4d.y);
case 1:
return v4d.y;
case 2:
return (v4d.w - v4d.x);
case 3:
return v4d.x;
case 4:
return v4d.z;
case 5:
return (v4d.w - v4d.z);
}
return 0.0f;
}
inline void
GetDoubleBC
(
int nr,
Stuff::Scalar& result1,
Stuff::Scalar& result2,
const Stuff::Vector4D& v4d1,
const Stuff::Vector4D& v4d2
)
{
switch(nr)
{
case 0:
result1 = (v4d1.w - v4d1.y);
result2 = (v4d2.w - v4d2.y);
break;
case 1:
result1 = v4d1.y;
result2 = v4d2.y;
break;
case 2:
result1 = (v4d1.w - v4d1.x);
result2 = (v4d2.w - v4d2.x);
break;
case 3:
result1 = v4d1.x;
result2 = v4d2.x;
break;
case 4:
result1 = v4d1.z;
result2 = v4d2.z;
break;
case 5:
result1 = (v4d1.w - v4d1.z);
result2 = (v4d2.w - v4d2.z);
break;
}
}
inline Stuff::Scalar
GetLerpFactor
(
int nr,
const Stuff::Vector4D& v4d1,
const Stuff::Vector4D& v4d2
)
{
Stuff::Scalar result1, result2;
switch(nr)
{
case 0:
result1 = (v4d1.w - v4d1.y);
result2 = (v4d2.w - v4d2.y);
break;
case 1:
result1 = v4d1.y;
result2 = v4d2.y;
break;
case 2:
result1 = (v4d1.w - v4d1.x);
result2 = (v4d2.w - v4d2.x);
break;
case 3:
result1 = v4d1.x;
result2 = v4d2.x;
break;
case 4:
result1 = v4d1.z;
result2 = v4d2.z;
break;
case 5:
result1 = (v4d1.w - v4d1.z);
result2 = (v4d2.w - v4d2.z);
break;
default:
result1 = 0.0f;
result2 = 0.0f;
STOP(("Invalid plane number used !"));
break;
}
if(result1 == 0.0f)
{
return 0.0f;
}
Verify(!Stuff::Close_Enough(result1, result2, Stuff::SMALL*0.1f));
return result1 / (result1 - result2);
}
}