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.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,129 @@
The MidLevelRender (MLR)
========================
Its main task is to transform and light the geometry handed to it by a HighLevelRenderer and
to feed this transformed and lit data into a rasterizer. MLR is designed to work with different
HighLevelRender's or Rasterizers.
The MLR project contains several folders:
- Clipping - define a view frustrum and perform clipping into it
- Geometry - store geometry data
- Lighting - lit geometry
- Sorting - define a render state and how to sort after certain parameters
- Texture - define a texture and a pool to handle textures
- Rasterizer - define a proxy for the rasterizer
- Effects - provides an extra API for effects (very special cases of geometry data)
Clipping
--------
The clipper is essentially the camera through which we see the world. Therefor it knows
how to transform the camera into world space and how to transform from world space into
clipping space. Clipping space is defined as a "cube in homogenious space from 0.0f - 1.0f
in x, y and z".
Clipper = class MLRClipper
The clipper works together with the culling routines from the Element renderer and reuses
the culling state. There is defined a MLRClippingState for an efficient way to clip object
with the 6 clipping planes.
The clipper also contains a pool of GOSVertices (see Rasterizer) in which transformed
geometry data ready for rendering is stored.
This is how a frame works:
- first the clipper get initialized with the new camera position
- then the element renderer gives sequentially the geometry data to the clipper.
Therefor the clipper provides 4 interfaces:
The first 3 provide a matrix describing the object location in world space.
Screen quads are allready defined in screen space therefor dont need transformation
or clipping.
- shape (see geometry)
- scalable shape (see effect)
- effect (see effect)
- screen quads
After concatination the matrices together the clipper will call
- the backface culling and mark backfacing geometry
- the lighting function for the shape's primitives
- the transform of the coordinates into clipping space if the object is clipped
- the clip function if clipped. the clip function also fills the GOSVertex pool
- the lightmap function
Geometry
--------
While the ElementRenderer on top of MLR cares about hierarchy MLR stores and manipulates
the geometry data. The basic geometry containing unit is a primitive.
Primitive == abstract class MLRPrimitve.
Any primitive has one render state (see MLRState). Derived from MLRPrimitve is
MLRIndexPrimitve. This abstract class provides an indexed storage of the geometry data.
The index points to a unique vertex which is defined by a unique combination of
coordinates, color, texture coordinates and normals.
The MLRPolyMesh class is a non-indexed case. The geometry data is stored as a chain of
polygones with variable vertex count. MLRIndexedPolyMesh covers the indexed case.
Lighting
--------
MLR supports to types of lighting:
- The so called 'classic lighting' on a per vertex basis using the vertex normals.
For per vertex lighting is available:
- ambient light
- infinite light
- infinite light with falloff
- point light
- spot light
- The so called 'lightmap lighting' in which an extra texture gets applied to an object.
This texture contains radiosity lighting information.
For an object is also the combination of the both lighting types allowed.
MLRPrimitive (see Geometry) has a member function 'Lighting'.
Sorting
-------
Before rendering the geometry data it is useful to sort them after the render state.
All information how to render and how to process a primitive are stored in MLRState.
For easy sorting all render informations are stored in a DWORD including a texture
handle (which points into the texture pool (see Textures)). All informations about
how to process a primitve are also stored in a DWORD. This are informations like
lighting on off, in which render pass to render, use backfacing or not.
The actual sorting takes place in a sorter.
Sorter == abstract class MLRSorter
The sorter gets sequentialy all transformed geoemtry data and stores them recording
to its implemented sorting functions.
MLRSortByOrder for example puts all data into designated buckets in the order it gets
the data handed. So far there are 16 buckets (subject of change) to reflect different
render passes like alpha, non-alpha, light maps, HUD etc. Before drawing the data gets
sorted by render state.
Textures
--------
Definitions:
An "image" is the representation of a picture in memory. Images are differ by names.
The GOSImagePool (see Rasterizer) should take care that every image is loaded only once.
Image == class GOSImage (see Rasterizer).
A "texture" is an instance of an "image". It has also a texture matrix which allows to
move an image relative to the texture coordinates of an object.
Texture == class MLRTexture.
MLRTexture contains a texture handle which is an integer. This integer is stored in the
render state of an object (see MLRState / Sorting). There are 12 bits (2^12 = 4096)
(subject to changes) reserved in the state for the texture handle. The 12 bit information
is divided in 12-X bit for an image handle and X bit for instancing. The handle is provided
by the texture pool. X is defined in the constructor of the texture pool.
The application has access to a global texture pool called "MLRTexturePool::Instance". The
application has to take care of creating this texture pool once. The application can add
textures to the texture pool by name and an integer defining the instance. This integer
has no order purposes. The application also can remove textures from the texture pool by
MLRTexture - pointer.
Rasterizer
----------
This provides a proxy to the underlaying Rasterizer. It connects a GOSVertex, a GOSImage.
It also provides a GOSVertex pool to feed all the render data from one memory block.
It also provides a GOSImagePool to ensure that all textures are loaded only once and
get reused.
@@ -0,0 +1,123 @@
#include "MLRHeaders.hpp"
//#############################################################################
//############################ GOSImage ###############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage::GOSImage( const char* iName ) : Plug (DefaultData)
{
imageName = iName;
flags = 0;
instance = 0;
imageHandle = 0;
ptr.pTexture = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage::GOSImage( DWORD iHandle ) : Plug (DefaultData)
{
char str[20];
sprintf(str, "image%03d", iHandle);
imageName = str;
flags = Loaded;
instance = 0;
imageHandle = iHandle;
ptr.pTexture = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage::GOSImage(gos_TextureFormat format, const char *name, int size, gos_TextureHints hints) : Plug (DefaultData)
{
imageName = name;
flags = Loaded;
instance = 0;
imageHandle = gos_NewEmptyTexture( format, name, size, hints);
ptr.pTexture = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage::~GOSImage()
{
if((flags & Locked) != 0)
{
// gos_UnLockTexture(imageHandle);
}
if((flags & Loaded) != 0)
{
gos_DestroyTexture(imageHandle);
}
flags = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
GOSImage::GetWidth()
{
return ptr.Width;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
GOSImage::GetHeight()
{
return ptr.Height;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GOSImage::LockImage()
{
if(!(flags & Locked))
{
flags |= Locked;
gos_LockTexture(imageHandle, 0, false, &ptr);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GOSImage::UnlockImage()
{
if(flags & Locked)
{
flags &= ~Locked;
MLR_RENDER("Unlock Texture");
Start_Timer(Unlock_Texture_Time);
gos_UnLockTexture(imageHandle);
Stop_Timer(Unlock_Texture_Time);
ptr.pTexture = NULL;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BYTE*
GOSImage::GetImagePtr()
{
return (BYTE *)ptr.pTexture;
}
@@ -0,0 +1,88 @@
#pragma once
#define MLR_GOSIMAGE_HPP
#if !defined(MLR_MLR_HPP)
#include <MLR\MLR.hpp>
#endif
#if !defined(GAMEOS_HPP)
#include <GameOS\GameOS.hpp>
#endif
namespace MidLevelRenderer {
class GOSImage:
public Stuff::Plug
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
public:
GOSImage(const char* imageName);
GOSImage(DWORD imageHandle);
GOSImage(gos_TextureFormat, const char*, int, gos_TextureHints);
~GOSImage();
int
GetWidth();
int
GetHeight();
const char*
GetName()
{ Check_Object(this); return imageName; }
int
Ref()
{ Check_Object(this); instance++; return instance; }
int
DeRef()
{ Check_Object(this); instance--; return instance; }
int
GetRef()
{ Check_Object(this); return instance; }
bool
IsLoaded()
{ Check_Object(this); return ( (flags & Loaded) != 0); }
DWORD
GetHandle()
{ Check_Object(this); return imageHandle; }
enum {
Loaded = 1,
Locked = 2
};
void
LockImage();
void
UnlockImage();
BYTE*
GetImagePtr();
int
GetPitch()
{ return ptr.Pitch; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{}
Stuff::MString imageName;
int instance;
int flags;
DWORD imageHandle;
TEXTUREPTR ptr;
};
}
@@ -0,0 +1,286 @@
#include "MLRHeaders.hpp"
#include <GameOS\ToolOS.hpp>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImagePool::GOSImagePool() :
imageHash(
4099,
NULL,
true
)
{
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
texturePath = *MString::s_Empty;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImagePool::~GOSImagePool()
{
imageHash.DeletePlugs();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage*
GOSImagePool::GetImage(const char* image_name)
{
Check_Object(this);
// MString imageName = image_name;
Verify(strlen(image_name) > 0);
//
//---------------------------
// Get the image for the name
//---------------------------
//
GOSImage *image;
gos_PushCurrentHeap(TexturePoolHeap);
if ((image = imageHash.Find(image_name)) == NULL)
{
image = new GOSImage(image_name);
Register_Object(image);
imageHash.AddValue(image, image->imageName);
}
Check_Object(image);
gos_PopCurrentHeap();
return image;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
GOSImage*
GOSImagePool::GetImage(const char *image_name, gos_TextureFormat format, int size, gos_TextureHints hints)
{
Check_Object(this);
// MString imageName = image_name;
// Verify(imageName.GetLength() > 0);
Verify(strlen(image_name) > 0);
//
//---------------------------
// Get the image for the name
//---------------------------
//
GOSImage *image;
gos_PushCurrentHeap(TexturePoolHeap);
if ((image = imageHash.Find(image_name)) == NULL)
{
image = new GOSImage(format, image_name, size, hints);
Register_Object(image);
imageHash.AddValue(image, image->imageName);
}
#ifdef _ARMOR
else
{
}
#endif
Check_Object(image);
gos_PopCurrentHeap();
return image;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GOSImagePool::RemoveImage(GOSImage *image)
{
Check_Object(this);
Unregister_Object(image);
delete image;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
GOSImagePool::ReadHint(Stuff::Page *page)
{
int hints = 0;
bool flag = false;
const char *string;
if (page->GetEntry("Mipmap", &string))
{
if (!_stricmp(string, "Explicit"))
hints |= gosHint_UserMipMaps;
else if (!_stricmp(string, "None"))
hints |= gosHint_DisableMipmap|gosHint_DontShrink;
}
if (page->GetEntry("Memory", &string))
{
if (!_stricmp(string, "AGP"))
hints |= gosHint_AGPMemory;
else if (!_stricmp(string, "Video"))
hints |= gosHint_VideoMemory;
}
if (page->GetEntry("DontShrink", &flag) && flag)
hints |= gosHint_DontShrink;
if (page->GetEntry("PageOut", &string))
{
if (!_stricmp(string, "Last"))
hints |= gosHint_PageLast;
else if (!_stricmp(string, "First"))
hints |= gosHint_PageFirst;
}
if (page->GetEntry("MipFilter", &string))
{
if (!_stricmp(string, "Box"))
hints |= gosHint_MipmapFilter0;
else if (!_stricmp(string, "Point"))
hints |= gosHint_MipmapFilter1;
}
if (page->GetEntry("PinkIsTransparent", &flag) && flag)
hints |= gosHint_PinkColorKey;
if (page->GetEntry("BlueIsAlpha", &flag) && flag)
hints |= gosHint_ForceAlpha;
if (page->GetEntry("Compression", &string))
{
if (!_stricmp(string, "Some"))
hints |= gosHint_Compress0;
else if (!_stricmp(string, "Very"))
hints |= gosHint_Compress1;
}
return hints;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DWORD
GOSImagePool::SkinThis(
const char* name,
gos_TextureFormat format,
DWORD skin,
DWORD detail
)
{
TEXTUREPTR skin_ptr, detail_ptr, dest_ptr;
gos_LockTexture(skin, 0, true, &skin_ptr);
gos_LockTexture(detail, 0, true, &detail_ptr);
DWORD dest = gos_NewEmptyTexture(format, name, detail_ptr.Height, gosHint_AGPMemory);
gos_LockTexture(dest, 0, false, &dest_ptr);
SkinThis(dest_ptr, skin_ptr, detail_ptr);
gos_UnLockTexture(skin);
gos_UnLockTexture(detail);
gos_UnLockTexture(dest);
return dest;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
GOSImagePool::SkinThis(
TEXTUREPTR dest_ptr,
TEXTUREPTR skin_ptr,
TEXTUREPTR detail_ptr
)
{
Verify(skin_ptr.Height==detail_ptr.Height && skin_ptr.Height==dest_ptr.Height);
Verify(skin_ptr.Width==detail_ptr.Width && skin_ptr.Width==dest_ptr.Width);
int count = detail_ptr.Height*detail_ptr.Width;
BYTE *s = (BYTE*)skin_ptr.pTexture;
BYTE *d = (BYTE*)detail_ptr.pTexture;
BYTE *n = (BYTE*)dest_ptr.pTexture;
for(int i=0;i<count;i++)
{
int alpha = d[3];
if(alpha>0)
{
int col = (*s++)*(0xff-alpha) + (*d++)*alpha;
*n++ = static_cast<unsigned char>(col>>8);
col = (*s++)*(0xff-alpha) + (*d++)*alpha;
*n++ = static_cast<unsigned char>(col>>8);
col = (*s++)*(0xff-alpha) + (*d++)*alpha;
*n++ = static_cast<unsigned char>(col>>8);
d++;
}
else
{
*n++ = *s++;
*n++ = *s++;
*n++ = *s++;
d += 4;
}
n++;
s++;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TGAFilePool::TGAFilePool(
const char* path,
const char* hint_file
)
{
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
texturePath = path;
if (hint_file)
{
MString temp(texturePath);
temp += hint_file;
hintFile = new NotationFile(temp);
}
else
hintFile = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TGAFilePool::~TGAFilePool()
{
if (hintFile)
{
Check_Object(hintFile);
delete hintFile;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
TGAFilePool::LoadImageGOS(GOSImage *image, int hint)
{
if( (image->flags & GOSImage::Loaded) != 0)
return true;
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
MString full_name,file_name = texturePath;
file_name += image->imageName;
full_name =file_name;
full_name +=".png";
if(!gos_DoesFileExist(full_name))
{
full_name=file_name;
full_name += ".tga";
}
if (hintFile)
{
Page *page = hintFile->FindPage(image->imageName);
if (page)
{
Check_Object(page);
hint = ReadHint(page);
}
}
image->imageHandle = gos_NewTextureFromFile(gos_Texture_Detect, full_name, hint);
image->flags |= (image->imageHandle ? GOSImage::Loaded : 0);
return ((image->flags & GOSImage::Loaded) != 0);
}
@@ -0,0 +1,98 @@
#pragma once
#define MLR_GOSIMAGEPOOL_HPP
#include "MLR.hpp"
namespace MidLevelRenderer {
class GOSImage;
class MLRTexture;
class GOSImagePool
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
public:
GOSImagePool();
~GOSImagePool();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Image handling
//
public:
GOSImage*
GetImage(const char* imageName);
GOSImage*
GetImage(const char* imageName, gos_TextureFormat format, int size, gos_TextureHints hints);
virtual bool
LoadImageGOS(GOSImage *image, int=0)=0;
void
RemoveImage(GOSImage *image);
void
GetTexturePath(Stuff::MString* pName) const
{ Check_Object(this); *pName = texturePath; }
static DWORD
SkinThis(
const char* name,
gos_TextureFormat format,
DWORD skin,
DWORD detail
);
static void
SkinThis(
TEXTUREPTR texture_ptr,
TEXTUREPTR skin_ptr,
TEXTUREPTR detail_ptr
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{}
protected:
Stuff::HashOf<GOSImage*, Stuff::MString>
imageHash;
Stuff::MString
texturePath;
static int
ReadHint(Stuff::Page *page);
};
class TGAFilePool:
public GOSImagePool
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
public:
TGAFilePool(
const char* path,
const char* hint_file=NULL
);
~TGAFilePool();
protected:
Stuff::NotationFile
*hintFile;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Image handling
//
public:
bool
LoadImageGOS(GOSImage *image, int=0);
};
}
@@ -0,0 +1,696 @@
#include "MLRHeaders.hpp"
Scalar
GOSVertex::farClipReciprocal;
Scalar
ViewportScalars::MulX,
ViewportScalars::MulY,
ViewportScalars::AddX,
ViewportScalars::AddY;
#if FOG_HACK
BYTE GOSVertex::fogTable[Limits::Max_Number_Of_FogStates][1024];
#endif
void
MidLevelRenderer::SetViewportScalars(Scalar top, Scalar left, Stuff::Scalar bottom, Stuff::Scalar right)
{
ViewportScalars::MulX = (right-left)*Environment.screenWidth;
ViewportScalars::MulY = (bottom-top)*Environment.screenHeight;
ViewportScalars::AddX = left*Environment.screenWidth;
ViewportScalars::AddY = top*Environment.screenHeight;
}
void
MidLevelRenderer::ClearZBuffer()
{
gos_VERTEX pVertices[4];
DWORD Color = 0x00ffffff;
memset( pVertices, 0, sizeof(pVertices) );
pVertices[0].x = ViewportScalars::AddX;
pVertices[0].y = ViewportScalars::AddY;
pVertices[0].z = 1.0f-SMALL;
pVertices[0].rhw = SMALL;
pVertices[0].argb = Color;
pVertices[1].x = ViewportScalars::AddX + ViewportScalars::MulX;
pVertices[1].y = ViewportScalars::AddY;
pVertices[1].z = 1.0f-SMALL;
pVertices[1].rhw = SMALL;
pVertices[1].argb = Color;
pVertices[2].x = ViewportScalars::AddX + ViewportScalars::MulX;
pVertices[2].y = ViewportScalars::AddY + ViewportScalars::MulY;
pVertices[2].z = 1.0f-SMALL;
pVertices[2].rhw = SMALL;
pVertices[2].argb = Color;
pVertices[3].x = ViewportScalars::AddX;
pVertices[3].y = ViewportScalars::AddY + ViewportScalars::MulY;
pVertices[3].z = 1.0f-SMALL;
pVertices[3].rhw = SMALL;
pVertices[3].argb = Color;
gos_SetRenderState( gos_State_Texture, 0 );
gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha );
gos_SetRenderState( gos_State_Clipping, 0 );
gos_SetRenderState( gos_State_ZWrite, 1 );
gos_SetRenderState( gos_State_ZCompare, 0 );
gos_DrawQuads( pVertices, 4 );
}
//#############################################################################
//############################ GOSVertex #################################
//#############################################################################
GOSVertex::GOSVertex()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
rhw = 1.0f;
argb = 0xffffffff;
u = 0.0f;
v = 0.0f;
frgb = 0xffffffff;
}
#if FOG_HACK
void
GOSVertex::SetFogTableEntry(int entry, Scalar nearFog, Scalar farFog, Scalar fogDensity)
{
float Fog;
Verify(farFog > nearFog);
entry--;
GOSVertex::fogTable[entry][0] = 0;
for( int t1=0; t1<1024; t1++ )
{
if( 0.0f == fogDensity )
{
Fog=(farFog-t1)/(farFog-nearFog); // 0.0 = Linear fog table (from Start to End)
}
else
{
if( fogDensity<1.0f )
{
Fog=(float)exp(-fogDensity*t1); // 0.0->1.0 = FOG_EXP
}
else
{
Fog=(float)exp(-((fogDensity-1.0f)*t1)*((fogDensity-1.0f)*t1)); // 1.0->2.0 = FOG_EXP2
}
}
if( Fog<0.0f )
Fog=0.0f;
if( Fog>1.0f )
Fog=1.0f;
GOSVertex::fogTable[entry][t1]=(BYTE)(255.9f*Fog);
}
}
#endif
#if 0
bool
GOSCopyTriangleData
( GOSVertex *gos_vertices,
Vector4D *coords,
RGBAColor *colors,
Vector2DScalar *texCoords,
int offset0,
int offset1,
int offset2)
{
#if USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset0].w;
mov ecx,dword ptr [coords]
fld1
mov edi,dword ptr [offset0]
mov eax,edi
shl eax,4
fdiv dword ptr [eax+ecx+0Ch]
add eax,ecx
mov edx,dword ptr [gos_vertices]
fst dword ptr [edx+0Ch]
; gos_vertices[0].x = coords[offset0].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx]
; gos_vertices[0].y = coords[offset0].y * gos_vertices[0].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+4]
; gos_vertices[0].z = coords[offset0].z * gos_vertices[0].w;
fld dword ptr [eax+8]
; gos_vertices[1].w = 1.0f/coords[offset1].w;
mov eax,dword ptr [offset1]
fmul st,st(1)
shl eax,4
add eax,ecx
fstp dword ptr [edx+8]
fstp st(0)
fld1
fdiv dword ptr [eax+0Ch]
fst dword ptr [edx+2Ch]
; gos_vertices[1].x = coords[offset1].x * gos_vertices[1].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx+20h]
; gos_vertices[1].y = coords[offset1].y * gos_vertices[1].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+24h]
; gos_vertices[1].z = coords[offset1].z * gos_vertices[1].w;
fld dword ptr [eax+8]
; gos_vertices[2].w = 1.0f/coords[offset2].w;
mov eax,dword ptr [offset2]
fmul st,st(1)
shl eax,4
add eax,ecx
fstp dword ptr [edx+28h]
fstp st(0)
fld1
fdiv dword ptr [eax+0Ch]
fst dword ptr [edx+4Ch]
; gos_vertices[2].x = coords[offset2].x * gos_vertices[2].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx+40h]
; gos_vertices[2].y = coords[offset2].y * gos_vertices[2].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+44h]
; gos_vertices[2].z = coords[offset2].z * gos_vertices[2].w;
fld dword ptr [eax+8]
fmul st,st(1)
fstp dword ptr [edx+48h]
fstp st(0)
}
#else
gos_vertices[0].w = 1.0f/coords[offset0].w;
gos_vertices[0].x = coords[offset0].x * gos_vertices[0].w;
gos_vertices[0].y = coords[offset0].y * gos_vertices[0].w;
gos_vertices[0].z = coords[offset0].z * gos_vertices[0].w;
gos_vertices[1].w = 1.0f/coords[offset1].w;
gos_vertices[1].x = coords[offset1].x * gos_vertices[1].w;
gos_vertices[1].y = coords[offset1].y * gos_vertices[1].w;
gos_vertices[1].z = coords[offset1].z * gos_vertices[1].w;
gos_vertices[2].w = 1.0f/coords[offset2].w;
gos_vertices[2].x = coords[offset2].x * gos_vertices[2].w;
gos_vertices[2].y = coords[offset2].y * gos_vertices[2].w;
gos_vertices[2].z = coords[offset2].z * gos_vertices[2].w;
#endif
// gos_vertices[0] = colors[offset0];
// gos_vertices[1] = colors[offset1];
// gos_vertices[2] = colors[offset2];
Scalar f;
#if USE_ASSEMBLER_CODE
int argb;
_asm {
fld float_cheat
mov esi, dword ptr [colors]
mov eax, offset0
shl eax, 4
add esi, eax
fld dword ptr [esi + 0Ch]
mov ecx, dword ptr [esi + 0Ch]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov argb, ebx
fld dword ptr [esi]
mov ecx, dword ptr [esi]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+4]
mov ecx, dword ptr [esi+4]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+8]
mov ecx, dword ptr [esi+8]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
}
gos_vertices[0].argb = argb;
_asm {
mov esi, dword ptr [colors]
mov eax, offset1
shl eax, 4
add esi, eax
fld dword ptr [esi + 0Ch]
mov ecx, dword ptr [esi + 0Ch]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov argb, ebx
fld dword ptr [esi]
mov ecx, dword ptr [esi]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+4]
mov ecx, dword ptr [esi+4]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+8]
mov ecx, dword ptr [esi+8]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
}
gos_vertices[1].argb = argb;
_asm {
mov esi, dword ptr [colors]
mov eax, offset2
shl eax, 4
add esi, eax
fld dword ptr [esi + 0Ch]
mov ecx, dword ptr [esi + 0Ch]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov argb, ebx
fld dword ptr [esi]
mov ecx, dword ptr [esi]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+4]
mov ecx, dword ptr [esi+4]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+8]
mov ecx, dword ptr [esi+8]
faddp st(1), st
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
}
gos_vertices[2].argb = argb;
#else
f = colors[offset0].alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[0].argb = Positive_Float_To_Byte (f);
f = colors[offset0].red * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[0].argb = (gos_vertices[0].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset0].green * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[0].argb = (gos_vertices[0].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset0].blue * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[0].argb = (gos_vertices[0].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset1].alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[1].argb = Positive_Float_To_Byte (f);
f = colors[offset1].red * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[1].argb = (gos_vertices[1].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset1].green * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[1].argb = (gos_vertices[1].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset1].blue * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[1].argb = (gos_vertices[1].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset2].alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[2].argb = Positive_Float_To_Byte (f);
f = colors[offset2].red * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[2].argb = (gos_vertices[2].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset2].green * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[2].argb = (gos_vertices[2].argb << 8) | Positive_Float_To_Byte (f);
f = colors[offset2].blue * 255.99f;
Clamp(f, 0.0f, 255.f);
gos_vertices[2].argb = (gos_vertices[2].argb << 8) | Positive_Float_To_Byte (f);
#endif
gos_vertices[0].u = texCoords[offset0][0];
gos_vertices[0].v = texCoords[offset0][1];
gos_vertices[1].u = texCoords[offset1][0];
gos_vertices[1].v = texCoords[offset1][1];
gos_vertices[2].u = texCoords[offset2][0];
gos_vertices[2].v = texCoords[offset2][1];
return true;
}
#endif
@@ -0,0 +1,637 @@
#pragma once
#define MLR_GOSVERTEX_HPP
#include <MLR\MLR.hpp>
#include <Stuff\Scalar.hpp>
#include <GameOS\GameOS.hpp>
namespace MidLevelRenderer {
//##########################################################################
//#################### GOSVertex ##############################
//##########################################################################
class GOSVertex :
public gos_VERTEX
{
public:
GOSVertex();
static Stuff::Scalar
farClipReciprocal;
inline GOSVertex&
operator=(const GOSVertex& V)
{
Check_Pointer(this);
x = V.x;
y = V.y;
z = V.z;
rhw = V.rhw;
argb = V.argb;
frgb = V.frgb;
u = V.u;
v = V.v;
return *this;
};
inline GOSVertex&
operator=(const Stuff::Vector4D& v)
{
Check_Pointer(this);
Verify(!Stuff::Small_Enough(v.w));
// Tell_Value(v);
rhw = 1.0f / v.w;
x = v.x * rhw;
Verify(x>=0.0f && x<=1.0f);
y = v.y * rhw;
Verify(y>=0.0f && y<=1.0f);
z = v.z * rhw;
Verify(z>=0.0f && z<1.0f);
return *this;
}
inline GOSVertex&
operator=(const Stuff::RGBAColor& c)
{
Check_Pointer(this);
// DEBUG_STREAM << "c = <" << c.alpha << ", " << c.red << ", ";
// DEBUG_STREAM << c.green << ", " << c.blue << ">" << endl;
float f;
f = c.alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = Stuff::Round_Float_To_Byte (f);
f = c.red * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.green * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.blue * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
// DEBUG_STREAM << "0x" << hex << argb << dec << endl;
return *this;
}
inline GOSVertex&
operator=(const DWORD c)
{
Check_Pointer(this);
argb = c;
return *this;
}
inline GOSVertex&
operator=(const Stuff::Vector2DOf<Stuff::Scalar>& uv)
{
Check_Pointer(this);
u = uv[0];
v = uv[1];
return *this;
}
inline void
GOSTransformNoClip(
const Stuff::Point3D &v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv
#if FOG_HACK
, int foggy
#endif
);
inline void
GOSTransformNoClipNoUV(
const Stuff::Point3D &v,
const Stuff::Matrix4D &m
#if FOG_HACK
, int foggy
#endif
);
#if FOG_HACK
static BYTE GOSVertex::fogTable[Limits::Max_Number_Of_FogStates][1024];
static void
SetFogTableEntry(int entry, Stuff::Scalar fogNearClip, Stuff::Scalar fogFarClip, Stuff::Scalar fogDensity);
#endif
protected:
};
struct ViewportScalars
{
static Stuff::Scalar MulX;
static Stuff::Scalar MulY;
static Stuff::Scalar AddX;
static Stuff::Scalar AddY;
};
void SetViewportScalars(Stuff::Scalar top=1.0f, Stuff::Scalar left=1.0f, Stuff::Scalar bottom=0.0f, Stuff::Scalar right=0.0f);
void ClearZBuffer();
const float float_cheat = 12582912.0f/256.0f;
const float One_Over_256 = 1.0f/256.0f;
#pragma warning (disable : 4725)
void
GOSVertex::GOSTransformNoClip(
const Stuff::Point3D &_v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv
#if FOG_HACK>0
, int foggy
#endif
)
{
GOSTransformNoClipNoUV(_v, m
#if FOG_HACK>0
, foggy
#endif
);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (uv[0]<MLRState::GetMaxUV() && uv[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv[1]<MLRState::GetMaxUV() && uv[1]>-MLRState::GetMaxUV()) : 1 );
#endif
u = uv[0];
v = uv[1];
}
void
GOSVertex::GOSTransformNoClipNoUV(
const Stuff::Point3D &_v,
const Stuff::Matrix4D &m
#if FOG_HACK>0
, int foggy
#endif
)
{
Check_Pointer(this);
Check_Object(&_v);
Check_Object(&m);
#if USE_ASSEMBLER_CODE
Stuff::Scalar *f = &x;
_asm {
mov edx, m
mov eax, _v
fld dword ptr [eax] // v.x
fld dword ptr [eax+4] // v.y
fld dword ptr [eax+8] // v.z
mov eax, f
fld dword ptr [edx+34h] // m[1][3]
fmul st, st(2) // v.y
fld dword ptr [edx+38h] // m[2][3]
fmul st, st(2) // v.z
fxch st(1)
fadd dword ptr [edx+3Ch] // m[3][3]
fld dword ptr [edx+30h] // m[0][3]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+14h] // m[1][1]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+18h] // m[2][1]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+0Ch] // w
fadd dword ptr [edx+1Ch] // m[3][1]
fld dword ptr [edx+10h] // m[0][1]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+24h] // m[1][2]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+28h] // m[2][2]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+4] // y
fadd dword ptr [edx+2Ch] // m[3][2]
fld dword ptr [edx+20h] // m[0][2]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+4] // m[1][0]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+8] // m[2][0]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+8] // z
fadd dword ptr [edx+0Ch] // m[3][0]
fld dword ptr [edx] // m[0][0]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
faddp st(1),st
// fld1
// fdivrp st(1),st
// get rid of x, y, z
fstp st(1)
fstp st(1)
fstp st(1)
fstp dword ptr [eax] // x
}
#else
x = v.x*m(0,0) + v.y*m(1,0) + v.z*m(2,0) + m(3,0);
y = v.x*m(0,1) + v.y*m(1,1) + v.z*m(2,1) + m(3,1);
z = v.x*m(0,2) + v.y*m(1,2) + v.z*m(2,2) + m(3,2);
rhw = v.x*m(0,3) + v.y*m(1,3) + v.z*m(2,3) + m(3,3);
#endif
#if 0 //USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset].w;
mov ecx, f
fld1
fdiv dword ptr [ecx+0Ch]
fst dword ptr [ecx+0Ch]
; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [ecx]
fstp dword ptr [ecx]
; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
fld dword ptr [ecx+4]
fmul st,st(1)
fstp dword ptr [ecx+4]
; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
; fld dword ptr [ecx+8]
fmul dword ptr [ecx+8]
fstp dword ptr [ecx+8]
; fstp st(0)
}
#else
#if FOG_HACK
if(foggy)
{
*((BYTE *)&frgb + 3) =
fogTable[foggy-1][Stuff::Truncate_Float_To_Word(rhw)];
}
else
{
*((BYTE *)&frgb + 3) = 0xff;
}
#endif
rhw = 1.0f/rhw;
x = x * rhw;
y = y * rhw;
z = z * rhw;
#endif
Verify(rhw > Stuff::SMALL);
Verify(x >= 0.0f);
Verify(y >= 0.0f);
Verify(z >= 0.0f);
Verify(x <= 1.0f);
Verify(y <= 1.0f);
Verify(z < 1.0f);
x = x*ViewportScalars::MulX + ViewportScalars::AddX;
y = y*ViewportScalars::MulY + ViewportScalars::AddY;
}
// create a dword color out of 4 rgba floats
inline DWORD
GOSCopyColor( const Stuff::RGBAColor *color )
{
Stuff::Scalar f;
#if USE_ASSEMBLER_CODE
DWORD argb;
_asm {
fld float_cheat
mov esi, dword ptr [color]
fld dword ptr [esi + 0Ch]
mov ecx, dword ptr [esi + 0Ch]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov argb, ebx
fld dword ptr [esi]
mov ecx, dword ptr [esi]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
fld dword ptr [esi+4]
mov ecx, dword ptr [esi+4]
fadd st, st(1)
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
; fld dword ptr [esi+8]
mov ecx, dword ptr [esi+8]
fadd dword ptr [esi+8]
rcl ecx, 1
sbb eax, eax
xor eax, -1
fstp f
xor ecx, ecx
mov ebx, f
and ebx, eax
test ebx, 0000ff00h
seta cl
xor eax, eax
sub eax, ecx
or ebx, eax
and ebx, 000000ffh
mov ecx, argb
shl ecx, 8
or ecx, ebx
mov argb, ecx
}
#else
f = color->alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = Stuff::Positive_Float_To_Byte (f);
f = colors->red * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
f = colors->green * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
f = colors->blue * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
#endif
return argb;
}
inline void
DWORD2Color(Stuff::RGBAColor& to, DWORD from)
{
to.blue = (from & 0xff) * One_Over_256;
from = from>>8;
to.green = (from & 0xff) * One_Over_256;
from = from>>8;
to.red = (from & 0xff) * One_Over_256;
from = from>>8;
to.alpha = (from & 0xff) * One_Over_256;
}
inline DWORD
Color_DWORD_Lerp (
DWORD _from,
DWORD _to,
Stuff::Scalar _lerp
)
{
Stuff::RGBAColor from, to, lerp;
from.blue = (_from & 0xff) * One_Over_256;
_from = _from>>8;
from.green = (_from & 0xff) * One_Over_256;
_from = _from>>8;
from.red = (_from & 0xff) * One_Over_256;
_from = _from>>8;
from.alpha = (_from & 0xff) * One_Over_256;
// ====
to.blue = (_to & 0xff) * One_Over_256;
_to = _to>>8;
to.green = (_to & 0xff) * One_Over_256;
_to = _to>>8;
to.red = (_to & 0xff) * One_Over_256;
_to = _to>>8;
to.alpha = (_to & 0xff) * One_Over_256;
lerp.Lerp(from, to, _lerp);
return GOSCopyColor(&lerp);
}
inline BYTE
BYTE_Lerp(
BYTE from,
BYTE to,
Stuff::Scalar lerp
)
{
return Stuff::Round_Float_To_Byte(from + lerp*(to-from));
}
//######################################################################################################################
// the lines below will produce following functions:
//
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, int);
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int);
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int);
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int);
//
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int, int, int);
//#######################################################################################################################
#define I_SAY_YES_TO_COLOR
#define I_SAY_YES_TO_TEXTURE
#define I_SAY_YES_TO_DWORD_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_DWORD_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#define I_SAY_YES_TO_COLOR
#undef I_SAY_YES_TO_TEXTURE
#include <MLR\GOSVertexManipulation.hpp>
#define I_SAY_YES_TO_DWORD_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#define MLR_GOSVERTEXMANIPULATION_HPP
}
@@ -0,0 +1,24 @@
#include "MLRHeaders.hpp"
#include "MLR\GOSVertex2UV.hpp"
//#############################################################################
//########################## GOSVertex2UV ################################
//#############################################################################
GOSVertex2UV::GOSVertex2UV()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
rhw = 1.0f;
argb = 0xffffffff;
u1 = 0.0f;
v1 = 0.0f;
u2 = 0.0f;
v2 = 0.0f;
frgb = 0xffffffff;
}
@@ -0,0 +1,345 @@
#pragma once
#define MLR_GOSVERTEX2UV_HPP
#include <GameOS\GameOS.hpp>
#include <MLR\MLR.hpp>
#include "MLR\GOSVertex.hpp"
namespace MidLevelRenderer {
//##########################################################################
//######################### GOSVertex2UV ##############################
//##########################################################################
class GOSVertex2UV :
public gos_VERTEX_2UV
{
public:
GOSVertex2UV();
inline GOSVertex2UV&
operator=(const GOSVertex2UV& V)
{
Check_Pointer(this);
x = V.x;
y = V.y;
z = V.z;
rhw = V.rhw;
argb = V.argb;
frgb = V.frgb;
u1 = V.u1;
v1 = V.v1;
u2 = V.u2;
v2 = V.v2;
return *this;
};
inline GOSVertex2UV&
operator=(const Stuff::Vector4D& v)
{
Check_Pointer(this);
Verify(!Stuff::Small_Enough(v.w));
// Tell_Value(v);
rhw = 1.0f / v.w;
x = v.x * rhw;
Verify(x>=0.0f && x<=1.0f);
y = v.y * rhw;
Verify(y>=0.0f && y<=1.0f);
z = v.z * rhw;
Verify(z>=0.0f && z<1.0f);
return *this;
}
inline GOSVertex2UV&
operator=(const Stuff::RGBAColor& c)
{
Check_Pointer(this);
// DEBUG_STREAM << "c = <" << c.alpha << ", " << c.red << ", ";
// DEBUG_STREAM << c.green << ", " << c.blue << ">" << endl;
float f;
f = c.alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = Stuff::Round_Float_To_Byte (f);
f = c.red * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.green * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.blue * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
// DEBUG_STREAM << "0x" << hex << argb << dec << endl;
return *this;
}
inline GOSVertex2UV&
operator=(const DWORD c)
{
Check_Pointer(this);
argb = c;
return *this;
}
inline void
GOSTransformNoClip(
const Stuff::Point3D &v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv1,
const Stuff::Scalar *uv2
#if FOG_HACK
, int foggy
#endif
);
protected:
};
#pragma warning (disable : 4725)
void
GOSVertex2UV::GOSTransformNoClip(
const Stuff::Point3D &_v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv1,
const Stuff::Scalar *uv2
#if FOG_HACK
, int foggy
#endif
)
{
Check_Pointer(this);
Check_Object(&_v);
Check_Object(&m);
#if USE_ASSEMBLER_CODE
Stuff::Scalar *f = &x;
_asm {
mov edx, m
mov eax, _v
fld dword ptr [eax] // v.x
fld dword ptr [eax+4] // v.y
fld dword ptr [eax+8] // v.z
mov eax, f
fld dword ptr [edx+34h] // m[1][3]
fmul st, st(2) // v.y
fld dword ptr [edx+38h] // m[2][3]
fmul st, st(2) // v.z
fxch st(1)
fadd dword ptr [edx+3Ch] // m[3][3]
fld dword ptr [edx+30h] // m[0][3]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+14h] // m[1][1]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+18h] // m[2][1]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+0Ch] // w
fadd dword ptr [edx+1Ch] // m[3][1]
fld dword ptr [edx+10h] // m[0][1]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+24h] // m[1][2]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+28h] // m[2][2]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+4] // y
fadd dword ptr [edx+2Ch] // m[3][2]
fld dword ptr [edx+20h] // m[0][2]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+4] // m[1][0]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+8] // m[2][0]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+8] // z
fadd dword ptr [edx+0Ch] // m[3][0]
fld dword ptr [edx] // m[0][0]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
faddp st(1),st
// fld1
// fdivrp st(1),st
// get rid of x, y, z
fstp st(1)
fstp st(1)
fstp st(1)
fstp dword ptr [eax] // x
}
#else
x = v.x*m(0,0) + v.y*m(1,0) + v.z*m(2,0) + m(3,0);
y = v.x*m(0,1) + v.y*m(1,1) + v.z*m(2,1) + m(3,1);
z = v.x*m(0,2) + v.y*m(1,2) + v.z*m(2,2) + m(3,2);
rhw = v.x*m(0,3) + v.y*m(1,3) + v.z*m(2,3) + m(3,3);
#endif
#if 0 //USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset].w;
mov ecx, f
fld1
fdiv dword ptr [ecx+0Ch]
fst dword ptr [ecx+0Ch]
; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [ecx]
fstp dword ptr [ecx]
; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
fld dword ptr [ecx+4]
fmul st,st(1)
fstp dword ptr [ecx+4]
; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
; fld dword ptr [ecx+8]
fmul dword ptr [ecx+8]
fstp dword ptr [ecx+8]
; fstp st(0)
}
#else
#if FOG_HACK
if(foggy)
{
*((BYTE *)&frgb + 3) =
GOSVertex::fogTable[foggy-1][Stuff::Truncate_Float_To_Word(rhw)];
}
else
{
*((BYTE *)&frgb + 3) = 0xff;
}
#endif
rhw = 1.0f/rhw;
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (uv1[0]<MLRState::GetMaxUV() && uv1[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv1[1]<MLRState::GetMaxUV() && uv1[1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv2[0]<MLRState::GetMaxUV() && uv2[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv2[1]<MLRState::GetMaxUV() && uv2[1]>-MLRState::GetMaxUV()) : 1 );
#endif
u1 = uv1[0];
v1 = uv1[1];
u2 = uv2[0];
v2 = uv2[1];
x = x * rhw;
y = y * rhw;
z = z * rhw;
#endif
Verify(rhw > Stuff::SMALL);
Verify(x >= 0.0f);
Verify(y >= 0.0f);
Verify(z >= 0.0f);
Verify(x <= 1.0f);
Verify(y <= 1.0f);
Verify(z < 1.0f);
x = x*ViewportScalars::MulX + ViewportScalars::AddX;
y = y*ViewportScalars::MulY + ViewportScalars::AddY;
}
//######################################################################################################################
// the lines below will produce following functions:
//
// bool GOSCopyData(GOSVertex2UV*, const Stuff::Vector4D*, const Vector2DScalar*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex2UV*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex2UV*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, const Vector2DScalar*, int);
//
// bool GOSCopyTriangleData(GOSVertex2UV*, const Stuff::Vector4D*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex2UV*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex2UV*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
//#######################################################################################################################
#define I_SAY_YES_TO_COLOR
#define I_SAY_YES_TO_TEXTURE
#define I_SAY_YES_TO_DWORD_COLOR
#define I_SAY_YES_TO_MULTI_TEXTURE
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_DWORD_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_MULTI_TEXTURE
#define MLR_GOSVERTEXMANIPULATION_HPP
}
@@ -0,0 +1,26 @@
#include "MLRHeaders.hpp"
#include "MLR\GOSVertex3UV.hpp"
//#############################################################################
//########################## GOSVertex3UV ################################
//#############################################################################
GOSVertex3UV::GOSVertex3UV()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
rhw = 1.0f;
argb = 0xffffffff;
u1 = 0.0f;
v1 = 0.0f;
u2 = 0.0f;
v2 = 0.0f;
u3 = 0.0f;
v3 = 0.0f;
frgb = 0xffffffff;
}
@@ -0,0 +1,355 @@
#pragma once
#define MLR_GOSVERTEX3UV_HPP
#include <GameOS\GameOS.hpp>
#include <MLR\MLR.hpp>
#include "MLR\GOSVertex.hpp"
namespace MidLevelRenderer {
//##########################################################################
//######################### GOSVertex3UV ##############################
//##########################################################################
class GOSVertex3UV :
public gos_VERTEX_3UV
{
public:
GOSVertex3UV();
inline GOSVertex3UV&
operator=(const GOSVertex3UV& V)
{
Check_Pointer(this);
x = V.x;
y = V.y;
z = V.z;
rhw = V.rhw;
argb = V.argb;
frgb = V.frgb;
u1 = V.u1;
v1 = V.v1;
u2 = V.u2;
v2 = V.v2;
u3 = V.u3;
v3 = V.v3;
return *this;
};
inline GOSVertex3UV&
operator=(const Stuff::Vector4D& v)
{
Check_Pointer(this);
Verify(!Stuff::Small_Enough(v.w));
// Tell_Value(v);
rhw = 1.0f / v.w;
x = v.x * rhw;
Verify(x>=0.0f && x<=1.0f);
y = v.y * rhw;
Verify(y>=0.0f && y<=1.0f);
z = v.z * rhw;
Verify(z>=0.0f && z<1.0f);
return *this;
}
inline GOSVertex3UV&
operator=(const Stuff::RGBAColor& c)
{
Check_Pointer(this);
// DEBUG_STREAM << "c = <" << c.alpha << ", " << c.red << ", ";
// DEBUG_STREAM << c.green << ", " << c.blue << ">" << endl;
float f;
f = c.alpha * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = Stuff::Round_Float_To_Byte (f);
f = c.red * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.green * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
f = c.blue * 255.99f;
Clamp(f, 0.0f, 255.f);
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
// DEBUG_STREAM << "0x" << hex << argb << dec << endl;
return *this;
}
inline GOSVertex3UV&
operator=(const DWORD c)
{
Check_Pointer(this);
argb = c;
return *this;
}
inline void
GOSTransformNoClip(
const Stuff::Point3D &v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv1,
const Stuff::Scalar *uv2,
const Stuff::Scalar *uv3
#if FOG_HACK
, int foggy
#endif
);
protected:
};
#pragma warning (disable : 4725)
void
GOSVertex3UV::GOSTransformNoClip(
const Stuff::Point3D &_v,
const Stuff::Matrix4D &m,
const Stuff::Scalar *uv1,
const Stuff::Scalar *uv2,
const Stuff::Scalar *uv3
#if FOG_HACK
, int foggy
#endif
)
{
Check_Pointer(this);
Check_Object(&_v);
Check_Object(&m);
#if USE_ASSEMBLER_CODE
Stuff::Scalar *f = &x;
_asm {
mov edx, m
mov eax, _v
fld dword ptr [eax] // v.x
fld dword ptr [eax+4] // v.y
fld dword ptr [eax+8] // v.z
mov eax, f
fld dword ptr [edx+34h] // m[1][3]
fmul st, st(2) // v.y
fld dword ptr [edx+38h] // m[2][3]
fmul st, st(2) // v.z
fxch st(1)
fadd dword ptr [edx+3Ch] // m[3][3]
fld dword ptr [edx+30h] // m[0][3]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+14h] // m[1][1]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+18h] // m[2][1]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+0Ch] // w
fadd dword ptr [edx+1Ch] // m[3][1]
fld dword ptr [edx+10h] // m[0][1]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+24h] // m[1][2]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+28h] // m[2][2]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+4] // y
fadd dword ptr [edx+2Ch] // m[3][2]
fld dword ptr [edx+20h] // m[0][2]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
fld dword ptr [edx+4] // m[1][0]
fmul st, st(4) // v.y
fxch st(2)
faddp st(1),st
fld dword ptr [edx+8] // m[2][0]
fmul st, st(3) // v.z
fxch st(1)
fstp dword ptr [eax+8] // z
fadd dword ptr [edx+0Ch] // m[3][0]
fld dword ptr [edx] // m[0][0]
fmul st, st(5) // v.x
fxch st(2)
faddp st(1),st
faddp st(1),st
// fld1
// fdivrp st(1),st
// get rid of x, y, z
fstp st(1)
fstp st(1)
fstp st(1)
fstp dword ptr [eax] // x
}
#else
x = v.x*m(0,0) + v.y*m(1,0) + v.z*m(2,0) + m(3,0);
y = v.x*m(0,1) + v.y*m(1,1) + v.z*m(2,1) + m(3,1);
z = v.x*m(0,2) + v.y*m(1,2) + v.z*m(2,2) + m(3,2);
rhw = v.x*m(0,3) + v.y*m(1,3) + v.z*m(2,3) + m(3,3);
#endif
#if 0 //USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset].w;
mov ecx, f
fld1
fdiv dword ptr [ecx+0Ch]
fst dword ptr [ecx+0Ch]
; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [ecx]
fstp dword ptr [ecx]
; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
fld dword ptr [ecx+4]
fmul st,st(1)
fstp dword ptr [ecx+4]
; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
; fld dword ptr [ecx+8]
fmul dword ptr [ecx+8]
fstp dword ptr [ecx+8]
; fstp st(0)
}
#else
#if FOG_HACK
if(foggy)
{
*((BYTE *)&frgb + 3) =
GOSVertex::fogTable[foggy-1][Stuff::Truncate_Float_To_Word(rhw)];
}
else
{
*((BYTE *)&frgb + 3) = 0xff;
}
#endif
rhw = 1.0f/rhw;
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (uv1[0]<MLRState::GetMaxUV() && uv1[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv1[1]<MLRState::GetMaxUV() && uv1[1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv2[0]<MLRState::GetMaxUV() && uv2[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv2[1]<MLRState::GetMaxUV() && uv2[1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv3[0]<MLRState::GetMaxUV() && uv3[0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (uv3[1]<MLRState::GetMaxUV() && uv3[1]>-MLRState::GetMaxUV()) : 1 );
#endif
u1 = uv1[0];
v1 = uv1[1];
u2 = uv2[0];
v2 = uv2[1];
u3 = uv3[0];
v3 = uv3[1];
x = x * rhw;
y = y * rhw;
z = z * rhw;
#endif
Verify(rhw > Stuff::SMALL);
Verify(x >= 0.0f);
Verify(y >= 0.0f);
Verify(z >= 0.0f);
Verify(x <= 1.0f);
Verify(y <= 1.0f);
Verify(z < 1.0f);
x = x*ViewportScalars::MulX + ViewportScalars::AddX;
y = y*ViewportScalars::MulY + ViewportScalars::AddY;
}
//######################################################################################################################
// the lines below will produce following functions:
//
// bool GOSCopyData(GOSVertex3UV*, const Stuff::Vector4D*, const Vector2DScalar*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex3UV*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, const Vector2DScalar*, int);
// bool GOSCopyData(GOSVertex3UV*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, const Vector2DScalar*, int);
//
// bool GOSCopyTriangleData(GOSVertex3UV*, const Stuff::Vector4D*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex3UV*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
// bool GOSCopyTriangleData(GOSVertex3UV*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, const Vector2DScalar*, int, int, int);
//#######################################################################################################################
#define I_SAY_YES_TO_COLOR
#define I_SAY_YES_TO_TEXTURE
#define I_SAY_YES_TO_DWORD_COLOR
#define I_SAY_YES_TO_BUMP_TEXTURE
#define I_SAY_YES_TO_MULTI_TEXTURE
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_DWORD_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_COLOR
#include <MLR\GOSVertexManipulation.hpp>
#undef I_SAY_YES_TO_MULTI_TEXTURE
#undef I_SAY_YES_TO_BUMP_TEXTURE
#define MLR_GOSVERTEXMANIPULATION_HPP
}
@@ -0,0 +1,580 @@
//#if !defined(MLR_GOSVERTEXMANIPULATION_HPP)
#define FCR_TRICK 0
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
#define VERTEX_STRUCT_SIZE 0x30 // (sizeof(GOSVertex3UV))
#define VERTEX_STRUCT_SIZEx2 0x60 // (sizeof(GOSVertex3UV))
#else // I_SAY_YES_TO_BUMP_TEXTURE
#define VERTEX_STRUCT_SIZE 0x28 // (sizeof(GOSVertex2UV))
#define VERTEX_STRUCT_SIZEx2 0x50 // (sizeof(GOSVertex2UV))
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else
#define VERTEX_STRUCT_SIZE 0x20 // (sizeof(GOSVertex))
#define VERTEX_STRUCT_SIZEx2 0x40 //(sizeof(GOSVertex))
#endif
// copies vertex data into rasterizer format
inline bool
GOSCopyData
(
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
GOSVertex3UV *gos_vertices,
#else // I_SAY_YES_TO_BUMP_TEXTURE
GOSVertex2UV *gos_vertices,
#endif
#else
GOSVertex *gos_vertices,
#endif
const Stuff::Vector4D *coords,
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_DWORD_COLOR
const DWORD *colors,
#else // I_SAY_YES_TO_DWORD_COLOR
const Stuff::RGBAColor *colors,
#endif // I_SAY_YES_TO_DWORD_COLOR
#endif // I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
const Vector2DScalar *texCoords1,
const Vector2DScalar *texCoords2,
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
const Vector2DScalar *texCoords3,
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else
const Vector2DScalar *texCoords,
#endif
#endif
int _offset
#if FOG_HACK
, int foggy = 1
#endif // FOG_HACK
)
{
Verify(gos_vertices != NULL);
Verify(coords != NULL);
Verify(coords[_offset].w > Stuff::SMALL);
Verify(coords[_offset].x >= 0.0f);
Verify(coords[_offset].y >= 0.0f);
Verify(coords[_offset].z >= 0.0f);
Verify(coords[_offset].x <= coords[_offset].w);
Verify(coords[_offset].y <= coords[_offset].w);
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
Verify(texCoords1 != NULL);
Verify(texCoords2 != NULL);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[_offset][0]<MLRState::GetMaxUV() && texCoords1[_offset][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[_offset][1]<MLRState::GetMaxUV() && texCoords1[_offset][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[_offset][0]<MLRState::GetMaxUV() && texCoords2[_offset][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[_offset][1]<MLRState::GetMaxUV() && texCoords2[_offset][1]>-MLRState::GetMaxUV()) : 1 );
#endif // UV_CHECK
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
Verify(texCoords3 != NULL);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[_offset][0]<MLRState::GetMaxUV() && texCoords3[_offset][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[_offset][1]<MLRState::GetMaxUV() && texCoords3[_offset][1]>-MLRState::GetMaxUV()) : 1 );
#endif // UV_CHECK
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else // I_SAY_YES_TO_MULTI_TEXTURE
Verify(texCoords != NULL);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (texCoords[_offset][0]<MLRState::GetMaxUV() && texCoords[_offset][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[_offset][1]<MLRState::GetMaxUV() && texCoords[_offset][1]>-MLRState::GetMaxUV()) : 1 );
#endif // UV_CHECK
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#endif // I_SAY_YES_TO_TEXTURE
#if FCR_TRICK
Verify(coords[_offset].z*GOSVertex::farClipReciprocal < 1.0f);
float fcr = GOSVertex::farClipReciprocal;
#else // FCR_TRICK
Verify(coords[_offset].z < coords[_offset].w);
#endif // FCR_TRICK
#if USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset].w;
mov ecx,dword ptr [coords]
fld1
mov edi, _offset
mov eax,edi
shl eax,4
fdiv dword ptr [eax+ecx+0Ch]
add eax,ecx
mov edx,dword ptr [gos_vertices]
fst dword ptr [edx+0Ch]
; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx]
; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+4]
; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
#if FCR_TRICK
fld dword ptr [eax+8]
fmul fcr
fstp dword ptr [edx+8]
fstp st(0)
#else // FCR_TRICK
; fld dword ptr [eax+8]
fmul dword ptr [eax+8]
fstp dword ptr [edx+8]
; fstp st(0)
#endif // FCR_TRICK
}
#else // USE_ASSEMBLER_CODE
gos_vertices[0].rhw = 1.0f/coords[_offset].w;
gos_vertices[0].x = coords[_offset].x * gos_vertices[0].w;
gos_vertices[0].y = coords[_offset].y * gos_vertices[0].w;
#if FCR_TRICK
gos_vertices[0].z = coords[_offset].z * fcr;
#else // FCR_TRICK
gos_vertices[0].z = coords[_offset].z * gos_vertices[0].rhw;
#endif // FCR_TRICK
#endif // USE_ASSEMBLER_CODE
gos_vertices[0].x = gos_vertices[0].x*ViewportScalars::MulX + ViewportScalars::AddX;
gos_vertices[0].y = gos_vertices[0].y*ViewportScalars::MulY + ViewportScalars::AddY;
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_DWORD_COLOR
gos_vertices[0].argb = colors!=NULL ? colors[_offset] : paintMeColorDW;
#else // I_SAY_YES_TO_DWORD_COLOR
gos_vertices[0].argb = GOSCopyColor(colors!=NULL ? (&colors[_offset]) : (&paintMeColorF) );
#endif // I_SAY_YES_TO_DWORD_COLOR
#else // I_SAY_YES_TO_COLOR
gos_vertices[0].argb = paintMeColorDW;
#endif // I_SAY_YES_TO_COLOR
#if FOG_HACK
if(foggy>0)
{
*((BYTE *)&gos_vertices[0].frgb + 3) = GOSVertex::fogTable[foggy-1][Stuff::Truncate_Float_To_Word(coords[_offset].w)];
}
else
{
*((BYTE *)&gos_vertices[0].frgb + 3) = 0xff;
}
#endif // FOG_HACK
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u1 = texCoords1[_offset][0];
gos_vertices[0].v1 = texCoords1[_offset][1];
gos_vertices[0].u2 = texCoords2[_offset][0];
gos_vertices[0].v2 = texCoords2[_offset][1];
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
gos_vertices[0].u3 = texCoords3[_offset][0];
gos_vertices[0].v3 = texCoords3[_offset][1];
#endif
#else // I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u = texCoords[_offset][0];
gos_vertices[0].v = texCoords[_offset][1];
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#else // I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u1 = 0.0f;
gos_vertices[0].v1 = 0.0f;
gos_vertices[0].u2 = 0.0f;
gos_vertices[0].v2 = 0.0f;
#else // I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u = 0.0f;
gos_vertices[0].v = 0.0f;
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#endif // I_SAY_YES_TO_TEXTURE
#if FCR_TRICK
fcr = fcr;
#endif // FCR_TRICK
return true;
}
// copies 3 vertex data into rasterizer format
inline bool
GOSCopyTriangleData
(
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
GOSVertex3UV *gos_vertices,
#else // I_SAY_YES_TO_BUMP_TEXTURE
GOSVertex2UV *gos_vertices,
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else // I_SAY_YES_TO_MULTI_TEXTURE
GOSVertex *gos_vertices,
#endif // I_SAY_YES_TO_MULTI_TEXTURE
const Stuff::Vector4D *coords,
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_DWORD_COLOR
const DWORD *colors,
#else // I_SAY_YES_TO_DWORD_COLOR
const Stuff::RGBAColor *colors,
#endif // I_SAY_YES_TO_DWORD_COLOR
#endif // I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
const Vector2DScalar *texCoords1,
const Vector2DScalar *texCoords2,
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
const Vector2DScalar *texCoords3,
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else // I_SAY_YES_TO_MULTI_TEXTURE
const Vector2DScalar *texCoords,
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#endif // I_SAY_YES_TO_TEXTURE
int offset0, int offset1, int offset2
#if FOG_HACK
, int foggy = 1
#endif // FOG_HACK
)
{
Verify(gos_vertices != NULL);
Verify(coords != NULL);
#ifdef I_SAY_YES_TO_COLOR
Verify(colors != NULL);
#endif // I_SAY_YES_TO_COLOR
Verify(coords[offset0].x >= 0.0f);
Verify(coords[offset0].y >= 0.0f);
Verify(coords[offset0].z >= 0.0f);
Verify(coords[offset0].x <= coords[offset0].w);
Verify(coords[offset0].y <= coords[offset0].w);
Verify(coords[offset1].x >= 0.0f);
Verify(coords[offset1].y >= 0.0f);
Verify(coords[offset1].z >= 0.0f);
Verify(coords[offset1].x <= coords[offset1].w);
Verify(coords[offset1].y <= coords[offset1].w);
Verify(coords[offset2].x >= 0.0f);
Verify(coords[offset2].y >= 0.0f);
Verify(coords[offset2].z >= 0.0f);
Verify(coords[offset2].x <= coords[offset2].w);
Verify(coords[offset2].y <= coords[offset2].w);
#if FCR_TRICK
Verify(coords[offset0].z*GOSVertex::farClipReciprocal < 1.0f);
Verify(coords[offset1].z*GOSVertex::farClipReciprocal < 1.0f);
Verify(coords[offset2].z*GOSVertex::farClipReciprocal < 1.0f);
float fcr = GOSVertex::farClipReciprocal;
#else // FCR_TRICK
Verify(coords[offset0].z < coords[offset0].w);
Verify(coords[offset1].z < coords[offset1].w);
Verify(coords[offset2].z < coords[offset2].w);
#endif // FCR_TRICK
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
Verify(texCoords1 != NULL);
Verify(texCoords2 != NULL);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset0][0]<MLRState::GetMaxUV() && texCoords1[offset0][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset0][1]<MLRState::GetMaxUV() && texCoords1[offset0][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset1][0]<MLRState::GetMaxUV() && texCoords1[offset1][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset1][1]<MLRState::GetMaxUV() && texCoords1[offset1][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset2][0]<MLRState::GetMaxUV() && texCoords1[offset2][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords1[offset2][1]<MLRState::GetMaxUV() && texCoords1[offset2][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset0][0]<MLRState::GetMaxUV() && texCoords2[offset0][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset0][1]<MLRState::GetMaxUV() && texCoords2[offset0][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset1][0]<MLRState::GetMaxUV() && texCoords2[offset1][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset1][1]<MLRState::GetMaxUV() && texCoords2[offset1][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset2][0]<MLRState::GetMaxUV() && texCoords2[offset2][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords2[offset2][1]<MLRState::GetMaxUV() && texCoords2[offset2][1]>-MLRState::GetMaxUV()) : 1 );
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset0][0]<MLRState::GetMaxUV() && texCoords3[offset0][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset0][1]<MLRState::GetMaxUV() && texCoords3[offset0][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset1][0]<MLRState::GetMaxUV() && texCoords3[offset1][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset1][1]<MLRState::GetMaxUV() && texCoords3[offset1][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset2][0]<MLRState::GetMaxUV() && texCoords3[offset2][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords3[offset2][1]<MLRState::GetMaxUV() && texCoords3[offset2][1]>-MLRState::GetMaxUV()) : 1 );
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#endif // UV_CHECK
#else // I_SAY_YES_TO_MULTI_TEXTURE
Verify(texCoords != NULL);
#ifdef UV_CHECK
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset0][0]<MLRState::GetMaxUV() && texCoords[offset0][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset0][1]<MLRState::GetMaxUV() && texCoords[offset0][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset1][0]<MLRState::GetMaxUV() && texCoords[offset1][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset1][1]<MLRState::GetMaxUV() && texCoords[offset1][1]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset2][0]<MLRState::GetMaxUV() && texCoords[offset2][0]>-MLRState::GetMaxUV()) : 1 );
Verify( MLRState::GetHasMaxUVs() ? (texCoords[offset2][1]<MLRState::GetMaxUV() && texCoords[offset2][1]>-MLRState::GetMaxUV()) : 1 );
#endif // UV_CHECK
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#endif // I_SAY_YES_TO_TEXTURE
#if USE_ASSEMBLER_CODE
_asm {
; gos_vertices[0].w = 1.0f/coords[offset0].w;
mov ecx,dword ptr [coords]
fld1
mov edi,dword ptr [offset0]
mov eax,edi
shl eax,4
fdiv dword ptr [eax+ecx+0Ch]
add eax,ecx
mov edx,dword ptr [gos_vertices]
fst dword ptr [edx+0Ch]
; gos_vertices[0].x = coords[offset0].x * gos_vertices[0].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx]
; gos_vertices[0].y = coords[offset0].y * gos_vertices[0].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+4]
; gos_vertices[0].z = coords[offset0].z * gos_vertices[0].w;
fld dword ptr [eax+8]
; gos_vertices[1].w = 1.0f/coords[offset1].w;
mov eax,dword ptr [offset1]
#if FCR_TRICK
fmul fcr
shl eax,4
#else // FCR_TRICK
fmul st,st(1)
shl eax,4
#endif // FCR_TRICK
add eax,ecx
fstp dword ptr [edx+8]
fstp st(0)
fld1
fdiv dword ptr [eax+0Ch]
fst dword ptr [edx + VERTEX_STRUCT_SIZE + 0Ch]
; gos_vertices[1].x = coords[offset1].x * gos_vertices[1].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx+VERTEX_STRUCT_SIZE]
; gos_vertices[1].y = coords[offset1].y * gos_vertices[1].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx+VERTEX_STRUCT_SIZE+4h]
; gos_vertices[1].z = coords[offset1].z * gos_vertices[1].w;
fld dword ptr [eax+8]
; gos_vertices[2].w = 1.0f/coords[offset2].w;
mov eax,dword ptr [offset2]
#if FCR_TRICK
fmul fcr
shl eax,4
#else // FCR_TRICK
fmul st,st(1)
shl eax,4
#endif // FCR_TRICK
add eax,ecx
fstp dword ptr [edx+VERTEX_STRUCT_SIZE+8h]
fstp st(0)
fld1
fdiv dword ptr [eax+0Ch]
fst dword ptr [edx + VERTEX_STRUCT_SIZEx2 + 0Ch]
; gos_vertices[2].x = coords[offset2].x * gos_vertices[2].w;
fld st(0)
fmul dword ptr [eax]
fstp dword ptr [edx + VERTEX_STRUCT_SIZEx2]
; gos_vertices[2].y = coords[offset2].y * gos_vertices[2].w;
fld dword ptr [eax+4]
fmul st,st(1)
fstp dword ptr [edx + VERTEX_STRUCT_SIZEx2 + 4h]
; gos_vertices[2].z = coords[offset2].z * gos_vertices[2].w;
fld dword ptr [eax+8]
#if FCR_TRICK
fmul fcr
#else // FCR_TRICK
fmul st,st(1)
#endif // FCR_TRICK
fstp dword ptr [edx + VERTEX_STRUCT_SIZEx2 + 8h]
fstp st(0)
}
#else // USE_ASSEMBLER_CODE
gos_vertices[0].w = 1.0f/coords[offset0].w;
gos_vertices[0].x = coords[offset0].x * gos_vertices[0].w;
gos_vertices[0].y = coords[offset0].y * gos_vertices[0].w;
#if FCR_TRICK
gos_vertices[0].z = coords[_offset].z * fcr;
#else // FCR_TRICK
gos_vertices[0].z = coords[_offset].z * gos_vertices[0].w;
#endif // FCR_TRICK
gos_vertices[1].w = 1.0f/coords[offset1].w;
gos_vertices[1].x = coords[offset1].x * gos_vertices[1].w;
gos_vertices[1].y = coords[offset1].y * gos_vertices[1].w;
#if FCR_TRICK
gos_vertices[1].z = coords[_offset].z * fcr;
#else // FCR_TRICK
gos_vertices[1].z = coords[_offset].z * gos_vertices[1].w;
#endif // FCR_TRICK
gos_vertices[2].w = 1.0f/coords[offset2].w;
gos_vertices[2].x = coords[offset2].x * gos_vertices[2].w;
gos_vertices[2].y = coords[offset2].y * gos_vertices[2].w;
#if FCR_TRICK
gos_vertices[2].z = coords[_offset].z * fcr;
#else // FCR_TRICK
gos_vertices[2].z = coords[_offset].z * gos_vertices[2].w;
#endif // FCR_TRICK
#endif // USE_ASSEMBLER_CODE
gos_vertices[0].x = gos_vertices[0].x*ViewportScalars::MulX + ViewportScalars::AddX;
gos_vertices[0].y = gos_vertices[0].y*ViewportScalars::MulY + ViewportScalars::AddY;
gos_vertices[1].x = gos_vertices[1].x*ViewportScalars::MulX + ViewportScalars::AddX;
gos_vertices[1].y = gos_vertices[1].y*ViewportScalars::MulY + ViewportScalars::AddY;
gos_vertices[2].x = gos_vertices[2].x*ViewportScalars::MulX + ViewportScalars::AddX;
gos_vertices[2].y = gos_vertices[2].y*ViewportScalars::MulY + ViewportScalars::AddY;
// gos_vertices[0] = colors[offset0];
// gos_vertices[1] = colors[offset1];
// gos_vertices[2] = colors[offset2];
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_DWORD_COLOR
gos_vertices[0].argb = colors[offset0];
gos_vertices[1].argb = colors[offset1];
gos_vertices[2].argb = colors[offset2];
#else // I_SAY_YES_TO_DWORD_COLOR
gos_vertices[0].argb = GOSCopyColor(&colors[offset0]);
gos_vertices[1].argb = GOSCopyColor(&colors[offset1]);
gos_vertices[2].argb = GOSCopyColor(&colors[offset2]);
#endif // I_SAY_YES_TO_DWORD_COLOR
#else
gos_vertices[0].argb = paintMeColorDW;
gos_vertices[1].argb = paintMeColorDW;
gos_vertices[2].argb = paintMeColorDW;
#endif // I_SAY_YES_TO_COLOR
#if FOG_HACK
if(foggy > 0)
{
foggy--;
*((BYTE *)&gos_vertices[0].frgb + 3) = GOSVertex::fogTable[foggy][Stuff::Truncate_Float_To_Word(coords[offset0].w)];
*((BYTE *)&gos_vertices[1].frgb + 3) = GOSVertex::fogTable[foggy][Stuff::Truncate_Float_To_Word(coords[offset1].w)];
*((BYTE *)&gos_vertices[2].frgb + 3) = GOSVertex::fogTable[foggy][Stuff::Truncate_Float_To_Word(coords[offset2].w)];
}
else
{
*((BYTE *)&gos_vertices[0].frgb + 3) = 0xff;
*((BYTE *)&gos_vertices[1].frgb + 3) = 0xff;
*((BYTE *)&gos_vertices[2].frgb + 3) = 0xff;
}
#endif // FOG_HACK
#ifdef I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u1 = texCoords1[offset0][0];
gos_vertices[0].v1 = texCoords1[offset0][1];
gos_vertices[1].u1 = texCoords1[offset1][0];
gos_vertices[1].v1 = texCoords1[offset1][1];
gos_vertices[2].u1 = texCoords1[offset2][0];
gos_vertices[2].v1 = texCoords1[offset2][1];
gos_vertices[0].u2 = texCoords2[offset0][0];
gos_vertices[0].v2 = texCoords2[offset0][1];
gos_vertices[1].u2 = texCoords2[offset1][0];
gos_vertices[1].v2 = texCoords2[offset1][1];
gos_vertices[2].u2 = texCoords2[offset2][0];
gos_vertices[2].v2 = texCoords2[offset2][1];
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
gos_vertices[0].u3 = texCoords3[offset0][0];
gos_vertices[0].v3 = texCoords3[offset0][1];
gos_vertices[1].u3 = texCoords3[offset1][0];
gos_vertices[1].v3 = texCoords3[offset1][1];
gos_vertices[2].u3 = texCoords3[offset2][0];
gos_vertices[2].v3 = texCoords3[offset2][1];
#endif // I_SAY_YES_TO_BUMP_TEXTURE
#else // I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u = texCoords[offset0][0];
gos_vertices[0].v = texCoords[offset0][1];
gos_vertices[1].u = texCoords[offset1][0];
gos_vertices[1].v = texCoords[offset1][1];
gos_vertices[2].u = texCoords[offset2][0];
gos_vertices[2].v = texCoords[offset2][1];
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#else // I_SAY_YES_TO_TEXTURE
#ifdef I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices1[0].u = 0.0f;
gos_vertices1[0].v = 0.0f;
gos_vertices1[1].u = 0.0f;
gos_vertices1[1].v = 0.0f;
gos_vertices1[2].u = 0.0f;
gos_vertices1[2].v = 0.0f;
gos_vertices2[0].u = 0.0f;
gos_vertices2[0].v = 0.0f;
gos_vertices2[1].u = 0.0f;
gos_vertices2[1].v = 0.0f;
gos_vertices2[2].u = 0.0f;
gos_vertices2[2].v = 0.0f;
#else // I_SAY_YES_TO_MULTI_TEXTURE
gos_vertices[0].u = 0.0f;
gos_vertices[0].v = 0.0f;
gos_vertices[1].u = 0.0f;
gos_vertices[1].v = 0.0f;
gos_vertices[2].u = 0.0f;
gos_vertices[2].v = 0.0f;
#endif // I_SAY_YES_TO_MULTI_TEXTURE
#endif // I_SAY_YES_TO_TEXTURE
#if FCR_TRICK
fcr = fcr;
#endif
return true;
}
#undef VERTEX_STRUCT_SIZE
#undef VERTEX_STRUCT_SIZEx2
//#endif
@@ -0,0 +1,253 @@
#pragma once
#define MLR_GOSVERTEXPOOL_HPP
#include <MLR\MLR.hpp>
#include <MLR\GOSVertex.hpp>
#include <MLR\GOSVertex2UV.hpp>
#include <MLR\GOSVertex3UV.hpp>
namespace MidLevelRenderer {
//##########################################################################
//###################### GOSVertexPool ###############################
//##########################################################################
class GOSVertexPool
{
public:
GOSVertexPool();
void Reset();
//
//------------------------------------------------------------------------------------------------------------
//
int GetLength ()
{
Check_Object(this);
return vertices.GetLength()-1;
}
unsigned GetLast ()
{
Check_Object(this);
return lastUsed;
}
int Increase (int add=1)
{
Check_Object(this);
lastUsed += add;
Verify(lastUsed<vertices.GetLength());
#ifdef LAB_ONLY
UsedGOSVertices = UsedGOSVertices < lastUsed ? lastUsed : UsedGOSVertices;
#endif
return lastUsed;
}
GOSVertex*
GetActualVertexPool(bool db=false)
{
Check_Object(this);
if(db)
{
return verticesDB.GetData();
}
else
{
// PAUSE(("This code path in \"GOSVertexPool\" is no longer supported"));
return (GOSVertex*)(vertices.GetData() + lastUsed);
}
}
//
//------------------------------------------------------------------------------------------------------------
//
int GetLength2UV ()
{
Check_Object(this);
return vertices2uv.GetLength()-1;
}
unsigned GetLast2UV ()
{
Check_Object(this);
return lastUsed2uv;
}
int Increase2UV (int add=1)
{
Check_Object(this);
lastUsed2uv += add;
Verify(lastUsed2uv<vertices2uv.GetLength());
#ifdef LAB_ONLY
UsedGOSVertices2UV = UsedGOSVertices2UV < lastUsed2uv ? lastUsed2uv : UsedGOSVertices2UV;
#endif
return lastUsed2uv;
}
GOSVertex2UV*
GetActualVertexPool2UV(bool db=false)
{
Check_Object(this);
if(db)
{
return vertices2uvDB.GetData();
}
else
{
// PAUSE(("This code path in \"GOSVertexPool\" is no longer supported"));
return (GOSVertex2UV*)(vertices2uv.GetData() + lastUsed2uv);
}
}
//
//------------------------------------------------------------------------------------------------------------
//
int GetLength3UV ()
{
Check_Object(this);
return vertices3uv.GetLength()-1;
}
unsigned GetLast3UV ()
{
Check_Object(this);
return lastUsed3uv;
}
int Increase3UV (int add=1)
{
Check_Object(this);
lastUsed3uv += add;
Verify(lastUsed3uv<vertices3uv.GetLength());
#ifdef LAB_ONLY
UsedGOSVertices3UV = UsedGOSVertices3UV < lastUsed3uv ? lastUsed3uv : UsedGOSVertices3UV;
#endif
return lastUsed3uv;
}
GOSVertex3UV*
GetActualVertexPool3UV(bool db=false)
{
Check_Object(this);
if(db)
{
return vertices3uvDB.GetData();
}
else
{
// PAUSE(("This code path in \"GOSVertexPool\" is no longer supported"));
return (GOSVertex3UV*)(vertices3uv.GetData() + lastUsed3uv);
}
}
//
//------------------------------------------------------------------------------------------------------------
//
unsigned GetLastIndex ()
{
Check_Object(this);
return lastUsedIndex;
}
int IncreaseIndex (int add=1)
{
Check_Object(this);
lastUsedIndex += add;
Verify(lastUsedIndex<indices.GetLength());
#ifdef LAB_ONLY
UsedGOSIndicies = UsedGOSIndicies < lastUsedIndex ? lastUsedIndex : UsedGOSIndicies;
#endif
return lastUsedIndex;
}
WORD*
GetActualIndexPool(bool db=false)
{
Check_Object(this);
if(db)
{
return indicesDB.GetData();
}
else
{
// PAUSE(("This code path in \"GOSVertexPool\" is no longer supported"));
return (WORD*)(indices.GetData() + lastUsedIndex);
}
}
//
//------------------------------------------------------------------------------------------------------------
//
void
TestInstance()
{
Verify(lastUsed < Limits::Max_Number_Vertices_Per_Frame);
Verify(lastUsed2uv < Limits::Max_Number_Vertices_Per_Frame);
Verify(lastUsed3uv < Limits::Max_Number_Vertices_Per_Frame);
Verify(lastUsedIndex < Limits::Max_Number_Vertices_Per_Frame);
}
protected:
unsigned lastUsed;
unsigned lastUsed2uv;
unsigned lastUsed3uv;
unsigned lastUsedIndex;
Stuff::DynamicArrayOf<GOSVertex> vertices; // , Max_Number_Vertices_Per_Frame+4*Max_Number_ScreenQuads_Per_Frame
Stuff::DynamicArrayOf<GOSVertex2UV> vertices2uv; // , Max_Number_Vertices_Per_Frame+4*Max_Number_ScreenQuads_Per_Frame
Stuff::DynamicArrayOf<GOSVertex3UV> vertices3uv; // , Max_Number_Vertices_Per_Frame+4*Max_Number_ScreenQuads_Per_Frame
Stuff::DynamicArrayOf<WORD> indices; // , Max_Number_Vertices_Per_Frame
Stuff::DynamicArrayOf<GOSVertex> verticesDB; // , Max_Number_Vertices_Per_Mesh
Stuff::DynamicArrayOf<GOSVertex2UV> vertices2uvDB; // , Max_Number_Vertices_Per_Mesh
Stuff::DynamicArrayOf<GOSVertex3UV> vertices3uvDB; // , Max_Number_Vertices_Per_Mesh
Stuff::DynamicArrayOf<WORD> indicesDB; // , Max_Number_Vertices_Per_Mesh
private:
GOSVertexPool(const GOSVertexPool&);
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline
GOSVertexPool::GOSVertexPool()
{
Verify(gos_GetCurrentHeap() == ClipperHeap);
lastUsed = 0;
lastUsed2uv = 0;
lastUsed3uv = 0;
lastUsedIndex = 0;
gos_PushCurrentHeap(StaticHeap);
vertices.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
vertices2uv.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
vertices3uv.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
indices.SetLength(Limits::Max_Size_Of_Index_Buffer);
verticesDB.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
vertices2uvDB.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
vertices3uvDB.SetLength(Limits::Max_Size_Of_Vertex_Buffer);
indicesDB.SetLength(Limits::Max_Size_Of_Index_Buffer);
gos_PopCurrentHeap();
}
inline void
GOSVertexPool::Reset()
{
Check_Object(this);
lastUsed = 0;
lastUsed2uv = 0;
lastUsedIndex = 0;
}
}
+695
View File
@@ -0,0 +1,695 @@
#include "MLRHeaders.hpp"
#include "MLR\MLRFootstep.hpp"
DWORD gShowClippedPolys=0;
DWORD gShowBirdView=0;
DWORD gEnableDetailTexture=1;
DWORD gEnableTextureSort=1;
DWORD gEnableAlphaSort=1;
DWORD gEnableMultiTexture=1;
DWORD gEnableLightMaps=1;
DWORD gEnableVertexLighting=1;
DWORD gEnableCulturals=1;
DWORD gEnableFootSteps=1;
DWORD gEnableBumpMap=0;
DWORD gShowBucketColors=0;
DWORD gEnableFancyWater=1;
DWORD gEnableMovieTextures=1;
DWORD gEnableSimpleLight=0;
static bool __stdcall CheckDetailTexture()
{
return gEnableDetailTexture!=0;
}
static bool __stdcall CheckTextureSort()
{
return gEnableTextureSort!=0;
}
static bool __stdcall CheckAlphaSort()
{
return gEnableAlphaSort!=0;
}
static bool __stdcall CheckMultiTexture()
{
return gEnableMultiTexture!=0;
}
static bool __stdcall CheckLightMaps()
{
return gEnableLightMaps!=0;
}
static bool __stdcall CheckVertexLighting()
{
return gEnableVertexLighting!=0;
}
static bool __stdcall CheckCulturals()
{
return gEnableCulturals!=0;
}
static bool __stdcall CheckFootSteps()
{
return gEnableFootSteps!=0;
}
static bool __stdcall CheckBumpMap()
{
return gEnableBumpMap!=0;
}
static bool __stdcall CheckShowBucketColors()
{
return gShowBucketColors!=0;
}
static bool __stdcall CheckFancyWater()
{
return gEnableFancyWater!=0;
}
static bool __stdcall CheckMovieTextures()
{
return gEnableMovieTextures!=0;
}
static bool __stdcall CheckSimpleLight()
{
return gEnableSimpleLight!=0;
}
static void __stdcall EnableDetailTexture()
{
gEnableDetailTexture=!gEnableDetailTexture;
}
static void __stdcall EnableTextureSort()
{
gEnableTextureSort=!gEnableTextureSort;
}
static void __stdcall EnableAlphaSort()
{
gEnableAlphaSort=!gEnableAlphaSort;
}
static void __stdcall EnableMultiTexture()
{
gEnableMultiTexture=!gEnableMultiTexture;
}
static void __stdcall EnableLightMaps()
{
gEnableLightMaps=!gEnableLightMaps;
}
static void __stdcall EnableVertexLighting()
{
gEnableVertexLighting=!gEnableVertexLighting;
}
static void __stdcall EnableCulturals()
{
gEnableCulturals=!gEnableCulturals;
}
static void __stdcall EnableFootSteps()
{
gEnableFootSteps=!gEnableFootSteps;
}
static void __stdcall EnableBumpMap()
{
gEnableBumpMap=!gEnableBumpMap;
}
static void __stdcall EnableShowBucketColors()
{
gShowBucketColors=!gShowBucketColors;
}
static void __stdcall EnableFancyWater()
{
gEnableFancyWater=!gEnableFancyWater;
}
static void __stdcall EnableMovieTextures()
{
gEnableMovieTextures=!gEnableMovieTextures;
}
static void __stdcall EnableSimpleLight()
{
gEnableSimpleLight=!gEnableSimpleLight;
}
extern DWORD gShowClippedPolys;
static bool __stdcall Check_ShowClippedPolys() {return gShowClippedPolys!=0;}
static void __stdcall Toggle_ShowClippedPolys() {gShowClippedPolys=!gShowClippedPolys;}
extern DWORD gShowBirdView;
static bool __stdcall Check_ShowBirdView() {return gShowBirdView!=0;}
static void __stdcall Toggle_ShowBirdView() {gShowBirdView=!gShowBirdView;}
unsigned
Limits::Max_Number_Vertices_Per_Frame,
Limits::Max_Number_Primitives_Per_Frame,
Limits::Max_Number_ScreenQuads_Per_Frame,
Limits::Max_Size_Of_LightMap_MemoryStream;
Scalar
Limits::LightThreshold;
HGOSHEAP
MidLevelRenderer::Heap = NULL,
MidLevelRenderer::StaticHeap = NULL,
MidLevelRenderer::StatesHeap = NULL,
MidLevelRenderer::LightsHeap = NULL,
MidLevelRenderer::MiscellaneousHeap = NULL,
MidLevelRenderer::PrimitiveHeap = NULL,
MidLevelRenderer::ShapeHeap = NULL,
MidLevelRenderer::VertexPoolHeap = NULL,
MidLevelRenderer::EffectHeap = NULL,
MidLevelRenderer::ClipperHeap = NULL,
MidLevelRenderer::SorterHeap = NULL,
MidLevelRenderer::TexturePoolHeap = NULL;
DEFINE_TIMER(MidLevelRenderer, Scene_Draw_Time);
DEFINE_TIMER(MidLevelRenderer, Transform_Time);
DEFINE_TIMER(MidLevelRenderer, Clipping_Time);
DEFINE_TIMER(MidLevelRenderer, GOS_Draw_Time);
DEFINE_TIMER(MidLevelRenderer, Vertex_Light_Time);
DEFINE_TIMER(MidLevelRenderer, LightMap_Light_Time);
DEFINE_TIMER(MidLevelRenderer, Texture_Sorting_Time);
DEFINE_TIMER(MidLevelRenderer, Alpha_Sorting_Time);
DEFINE_TIMER(MidLevelRenderer, Unlock_Texture_Time);
DEFINE_TIMER(MidLevelRenderer, Shape_Setup_Time);
DEFINE_TIMER(MidLevelRenderer, Find_Backface_Time);
DEFINE_TIMER(MidLevelRenderer, Fog_Time);
DEFINE_TIMER(MidLevelRenderer, Shadow_Time);
DWORD MidLevelRenderer::Number_Of_Primitives;
DWORD MidLevelRenderer::NumAllIndices;
DWORD MidLevelRenderer::NumAllVertices;
float MidLevelRenderer::Index_Over_Vertex_Ratio;
DWORD MidLevelRenderer::TransformedVertices;
DWORD MidLevelRenderer::NumberOfAlphaSortedTriangles;
DWORD MidLevelRenderer::LitVertices;
DWORD MidLevelRenderer::NonClippedVertices;
DWORD MidLevelRenderer::ClippedVertices;
DWORD MidLevelRenderer::PolysClippedButOutside;
DWORD MidLevelRenderer::PolysClippedButInside;
DWORD MidLevelRenderer::PolysClippedButOnePlane;
DWORD MidLevelRenderer::PolysClippedButGOnePlane;
DWORD MidLevelRenderer::UsedGOSVertices;
DWORD MidLevelRenderer::UsedGOSVertices2UV;
DWORD MidLevelRenderer::UsedGOSVertices3UV;
DWORD MidLevelRenderer::UsedGOSIndicies;
bool MidLevelRenderer::ConvertToTriangleMeshes = false;
int MidLevelRenderer::terrainTextureResolution = 3;
DWORD MidLevelRenderer::bucketColors[] = {
0xff800000,
0xffc00000,
0xff00ff00,
0xff0000ff,
0xff808000,
0xffa0a000,
0xffc0c000,
0xffe0e000,
0xff800080,
0xffa000a0,
0xffc000c0,
0xffe000e0,
0xff008080,
0xff00a0a0,
0xff00c0c0,
0xff00e0e0
};
DWORD MidLevelRenderer::paintMeColorDW;
RGBAColor MidLevelRenderer::paintMeColorF;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MidLevelRenderer::InitializeClasses(
Stuff::NotationFile *startup_ini,
unsigned Max_Number_Vertices_Per_Frame,
unsigned Max_Number_Primitives_Per_Frame,
unsigned Max_Number_ScreenQuads_Per_Frame,
unsigned Max_Size_Of_LightMap_MemoryStream,
bool Convert_To_Triangle_Meshes
)
{
Verify(FirstFreeMLRClassID <= LastMLRClassID);
#if !(defined(NO_STATS) && defined(NO_TIMERS))
StatisticFormat( "" );
StatisticFormat( "Mid Level Renderer" );
StatisticFormat( "==================" );
StatisticFormat( "" );
#endif
Verify(!Heap);
Heap = gos_CreateMemoryHeap("MLR");
Check_Pointer(Heap);
Verify(!TexturePoolHeap);
TexturePoolHeap = gos_CreateMemoryHeap("MLR Texture Pool", 0, Heap);
Check_Pointer(TexturePoolHeap);
Verify(!StatesHeap);
StatesHeap = gos_CreateMemoryHeap("MLR States", 0, Heap);
Check_Pointer(StatesHeap);
Verify(!LightsHeap);
LightsHeap = gos_CreateMemoryHeap("MLR Lights", 0, Heap);
Check_Pointer(LightsHeap);
Verify(!MiscellaneousHeap);
MiscellaneousHeap = gos_CreateMemoryHeap("MLR Miscellaneous", 0, Heap);
Check_Pointer(MiscellaneousHeap);
Verify(!ShapeHeap);
ShapeHeap = gos_CreateMemoryHeap("MLR Shapes", 0, Heap);
Check_Pointer(ShapeHeap);
Verify(!PrimitiveHeap);
PrimitiveHeap = gos_CreateMemoryHeap("MLR Primitives", 0, Heap);
Check_Pointer(PrimitiveHeap);
Verify(!EffectHeap);
EffectHeap = gos_CreateMemoryHeap("MLR Effect", 0, Heap);
Check_Pointer(EffectHeap);
Verify(!ClipperHeap);
ClipperHeap = gos_CreateMemoryHeap("MLR Clipper", 0, Heap);
Check_Pointer(ClipperHeap);
Verify(!SorterHeap);
SorterHeap = gos_CreateMemoryHeap("MLR Sorter", 0, Heap);
Check_Pointer(SorterHeap);
Verify(!VertexPoolHeap);
VertexPoolHeap = gos_CreateMemoryHeap("MLR Vertex Pool", 0, Heap);
Check_Pointer(VertexPoolHeap);
Verify(!StaticHeap);
StaticHeap = gos_CreateMemoryHeap("MLR Static", 0, Heap);
Check_Pointer(StaticHeap);
gos_PushCurrentHeap(StaticHeap);
Limits::Max_Number_Vertices_Per_Frame = Max_Number_Vertices_Per_Frame;
Limits::Max_Number_Primitives_Per_Frame = Max_Number_Primitives_Per_Frame;
Limits::Max_Number_ScreenQuads_Per_Frame = Max_Number_ScreenQuads_Per_Frame;
Limits::Max_Size_Of_LightMap_MemoryStream = Max_Size_Of_LightMap_MemoryStream;
Limits::LightThreshold = 0.05f;
ConvertToTriangleMeshes = Convert_To_Triangle_Meshes;
MLRLight::InitializeClass();
MLRTexturePool::InitializeClass();
MLRClipper::InitializeClass();
MLRSorter::InitializeClass();
MLRSortByOrder::InitializeClass();
MLRShape::InitializeClass();
MLREffect::InitializeClass();
MLRPointCloud::InitializeClass();
MLRTriangleCloud::InitializeClass();
MLRNGonCloud::InitializeClass();
MLRCardCloud::InitializeClass();
MLRAmbientLight::InitializeClass();
MLRInfiniteLight::InitializeClass();
MLRInfiniteLightWithFalloff::InitializeClass();
MLRPointLight::InitializeClass();
MLRSpotLight::InitializeClass();
MLRPrimitiveBase::InitializeClass();
MLRIndexedPrimitiveBase::InitializeClass();
MLR_I_PMesh::InitializeClass();
MLR_I_C_PMesh::InitializeClass();
MLR_I_L_PMesh::InitializeClass();
MLR_I_DT_PMesh::InitializeClass();
MLR_I_C_DT_PMesh::InitializeClass();
MLR_I_L_DT_PMesh::InitializeClass();
MLR_I_DeT_PMesh::InitializeClass();
MLR_I_C_DeT_PMesh::InitializeClass();
MLR_I_L_DeT_PMesh::InitializeClass();
MLR_I_TMesh::InitializeClass();
MLR_I_DeT_TMesh::InitializeClass();
MLR_I_C_TMesh::InitializeClass();
MLR_I_L_TMesh::InitializeClass();
MLR_Terrain2::InitializeClass();
MLRLineCloud::InitializeClass();
MLRIndexedTriangleCloud::InitializeClass();
MLR_I_DT_TMesh::InitializeClass();
MLR_I_C_DT_TMesh::InitializeClass();
MLR_I_L_DT_TMesh::InitializeClass();
MLR_I_C_DeT_TMesh::InitializeClass();
MLR_I_L_DeT_TMesh::InitializeClass();
MLRLookUpLight::InitializeClass();
MLR_Water::InitializeClass();
MLRProjectLight::InitializeClass();
MLRSpriteCloud::InitializeClass();
MLRShadowLight::InitializeClass();
MLRCulturShape::InitializeClass();
MLRCenterPointLight::InitializeClass();
MLRFootStep::InitializeClass();
MLR_BumpyWater::InitializeClass();
MLRLightMap::InitializeClass();
MLRTexture::InitializeClass();
MLRMovieTexture::InitializeClass();
#if FOG_HACK
for(int i=0;i<Limits::Max_Number_Of_FogStates;i++)
{
GOSVertex::SetFogTableEntry(i+1, 700.0f, 1000.0f, 0.0f);
}
#endif
gos_PopCurrentHeap();
//
//-------------------------
// Setup the debugger menus
//-------------------------
//
AddDebuggerMenuItem(
"Libraries\\MLR\\Show Clipped Polygons",
Check_ShowClippedPolys,
Toggle_ShowClippedPolys,
NULL
);
AddDebuggerMenuItem(
"Libraries\\MLR\\Show Bird View",
Check_ShowBirdView,
Toggle_ShowBirdView,
NULL
);
AddDebuggerMenuItem("Libraries\\MLR\\Texture Sort", CheckTextureSort, EnableTextureSort, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\Enable Detail Texture", CheckDetailTexture, EnableDetailTexture, NULL );
AddDebuggerMenuItem("Libraries\\MLR\\Alpha Sort", CheckAlphaSort, EnableAlphaSort, NULL );
AddDebuggerMenuItem("Libraries\\MLR\\Show Bucket Colors", CheckShowBucketColors, EnableShowBucketColors, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\MultiTexture Enabled", CheckMultiTexture, EnableMultiTexture, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\LightMaps Enabled", CheckLightMaps, EnableLightMaps, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\VertexLighting Enabled", CheckVertexLighting, EnableVertexLighting, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\Culturals Enabled", CheckCulturals, EnableCulturals, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\FootSteps Enabled", CheckFootSteps, EnableFootSteps, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\Fancy Water Enabled", CheckFancyWater, EnableFancyWater, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\Movie Textures Enabled", CheckMovieTextures, EnableMovieTextures, NULL );
AddDebuggerMenuItem("Libraries\\Graphics Options\\Simple Lighting", CheckSimpleLight, EnableSimpleLight, NULL );
if( (0<gos_GetMachineInformation(gos_Info_CanBumpEnvMap)) || (0<gos_GetMachineInformation(gos_Info_CanBumpDotMap)) )
{
AddDebuggerMenuItem("Libraries\\Graphics Options\\BumpMap Enabled", CheckBumpMap, EnableBumpMap, NULL );
}
//
//--------------------------------------------
// Now set the menu defaults from the ini file
//--------------------------------------------
//
if (startup_ini)
{
Check_Object(startup_ini);
Page *page = startup_ini->FindPage("Graphics Options");
if (page)
{
Check_Object(page);
bool status;
if (page->GetEntry("DetailTexture", &status))
gEnableDetailTexture = status;
if (page->GetEntry("MultiTexture", &status))
gEnableMultiTexture = status;
if (page->GetEntry("LightMaps", &status))
gEnableLightMaps = status;
if (page->GetEntry("Culturals", &status))
gEnableCulturals = status;
if (page->GetEntry("Footsteps", &status))
gEnableFootSteps = status;
if (page->GetEntry("FancyWater", &status))
gEnableFancyWater = status;
if (page->GetEntry("MovieTextures", &status))
gEnableMovieTextures = status;
if (page->GetEntry("SimpleLighting", &status))
gEnableSimpleLight = status;
}
}
//
//---------------------
// Setup the statistics
//---------------------
//
Initialize_Timer(Transform_Time, "Transform Time");
Initialize_Timer(Clipping_Time, "Clipping Time");
Initialize_Timer(GOS_Draw_Time, "GOS Draw Time");
Initialize_Timer(Vertex_Light_Time, "Vertex Light Time");
Initialize_Timer(LightMap_Light_Time, "LightMap Light Time");
Initialize_Timer(Texture_Sorting_Time, "Texture Sorting Time");
Initialize_Timer(Alpha_Sorting_Time, "Alpha Sorting Time");
Initialize_Timer(Unlock_Texture_Time, "Unlock Texture Time");
Initialize_Timer(Shape_Setup_Time, "Shape Setup Time");
Initialize_Timer(Find_Backface_Time, "Find Backface Time");
Initialize_Timer(Fog_Time, "Fog Time");
Initialize_Timer(Shadow_Time, "Shadow Time");
#if !defined(NO_STATS)
AddStatistic( "MLR Primitives", "prims", gos_DWORD, &Number_Of_Primitives, Stat_AutoReset );
AddStatistic( "Indices/Vertices", "Ratio", gos_float, &Index_Over_Vertex_Ratio, Stat_AutoReset+Stat_2DP );
AddStatistic( "Transformed vertices", "vertices", gos_DWORD, &TransformedVertices, Stat_AutoReset );
AddStatistic( "Number of alphasorted Tri", "tri", gos_DWORD, &NumberOfAlphaSortedTriangles, Stat_AutoReset );
AddStatistic( "Lit vertices", "vertices", gos_DWORD, &LitVertices, Stat_AutoReset );
AddStatistic( "Unclipped vertices", "vertices", gos_DWORD, &NonClippedVertices, Stat_AutoReset );
AddStatistic( "Clipped vertices", "vertices", gos_DWORD, &ClippedVertices, Stat_AutoReset );
// Polygons in primitives which are clipped but polys are outside the viewing frustrum
AddStatistic( "Clip: Offscreen", "Poly", gos_DWORD, &PolysClippedButOutside, Stat_AutoReset );
// Polygons in primitives which are clipped but polys are inside the viewing frustrum
AddStatistic( "Clip: Onscreen", "Poly", gos_DWORD, &PolysClippedButInside, Stat_AutoReset );
// Polygons in primitives which are clipped, polys clipped against one plain
AddStatistic( "Clip: One Plane", "Poly", gos_DWORD, &PolysClippedButOnePlane, Stat_AutoReset );
// Polygons in primitives which are clipped, polys clipped against more than one plain
AddStatistic( "Clip: > One Plane", "Poly", gos_DWORD, &PolysClippedButGOnePlane, Stat_AutoReset );
AddStatistic( "Used Vertices in GOSVertexPool", "#", gos_DWORD, &UsedGOSVertices, Stat_AutoReset );
AddStatistic( "Used Vertices2UV in GOSVertexPool", "#", gos_DWORD, &UsedGOSVertices2UV, Stat_AutoReset );
AddStatistic( "Used Vertices3UV in GOSVertexPool", "#", gos_DWORD, &UsedGOSVertices3UV, Stat_AutoReset );
AddStatistic( "Used Indecies in GOSVertexPool", "#", gos_DWORD, &UsedGOSIndicies, Stat_AutoReset );
#endif
paintMeColorDW = 0xffffffff;
paintMeColorF = RGBAColor(1.0f, 1.0f, 1.0f, 1.0f);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MidLevelRenderer::TerminateClasses(Stuff::NotationFile *startup_ini)
{
//
//----------------------------------
// Now set the ini file if it exists
//----------------------------------
//
if (startup_ini)
{
Check_Object(startup_ini);
Page *page = startup_ini->SetPage("Graphics Options");
Check_Object(page);
page->SetEntry("DetailTexture", gEnableDetailTexture!=0);
page->SetEntry("MultiTexture", gEnableMultiTexture!=0);
page->SetEntry("LightMaps", gEnableLightMaps!=0);
page->SetEntry("Culturals", gEnableCulturals!=0);
page->SetEntry("Footsteps", gEnableFootSteps!=0);
page->SetEntry("FancyWater", gEnableFancyWater!=0);
page->SetEntry("MovieTextures", gEnableMovieTextures!=0);
page->SetEntry("SimpleLighting", gEnableSimpleLight!=0);
}
gos_PushCurrentHeap(Heap);
MLRMovieTexture::TerminateClass();
MLRTexture::TerminateClass();
MLRLightMap::TerminateClass();
MLR_BumpyWater::TerminateClass();
MLRFootStep::TerminateClass();
MLRCenterPointLight::TerminateClass();
MLRCulturShape::TerminateClass();
MLRShadowLight::TerminateClass();
MLRSpriteCloud::TerminateClass();
MLRProjectLight::TerminateClass();
MLR_Water::TerminateClass();
MLRLookUpLight::TerminateClass();
MLR_I_L_DeT_TMesh::TerminateClass();
MLR_I_C_DeT_TMesh::TerminateClass();
MLR_I_L_DT_TMesh::TerminateClass();
MLR_I_C_DT_TMesh::TerminateClass();
MLR_I_DT_TMesh::TerminateClass();
MLRIndexedTriangleCloud::TerminateClass();
MLRLineCloud::TerminateClass();
MLR_Terrain2::TerminateClass();
MLR_I_L_TMesh::TerminateClass();
MLR_I_C_TMesh::TerminateClass();
MLR_I_DeT_TMesh::TerminateClass();
MLR_I_TMesh::TerminateClass();
MLR_I_L_DeT_PMesh::TerminateClass();
MLR_I_C_DeT_PMesh::TerminateClass();
MLR_I_DeT_PMesh::TerminateClass();
MLR_I_L_DT_PMesh::TerminateClass();
MLR_I_C_DT_PMesh::TerminateClass();
MLR_I_DT_PMesh::TerminateClass();
MLR_I_L_PMesh::TerminateClass();
MLR_I_C_PMesh::TerminateClass();
MLR_I_PMesh::TerminateClass();
MLRIndexedPrimitiveBase::TerminateClass();
MLRPrimitiveBase::TerminateClass();
MLRSpotLight::TerminateClass();
MLRPointLight::TerminateClass();
MLRInfiniteLightWithFalloff::TerminateClass();
MLRInfiniteLight::TerminateClass();
MLRAmbientLight::TerminateClass();
MLRCardCloud::TerminateClass();
MLRNGonCloud::TerminateClass();
MLRTriangleCloud::TerminateClass();
MLRPointCloud::TerminateClass();
MLREffect::TerminateClass();
MLRShape::TerminateClass();
MLRSortByOrder::TerminateClass();
MLRSorter::TerminateClass();
MLRClipper::TerminateClass();
MLRTexturePool::TerminateClass();
MLRLight::TerminateClass();
gos_PopCurrentHeap();
Check_Pointer(StaticHeap);
gos_DestroyMemoryHeap(StaticHeap);
StaticHeap = NULL;
Check_Pointer(TexturePoolHeap);
gos_DestroyMemoryHeap(TexturePoolHeap);
TexturePoolHeap = NULL;
Check_Pointer(StatesHeap);
gos_DestroyMemoryHeap(StatesHeap);
StatesHeap = NULL;
Check_Pointer(LightsHeap);
gos_DestroyMemoryHeap(LightsHeap);
LightsHeap = NULL;
Check_Pointer(MiscellaneousHeap);
gos_DestroyMemoryHeap(MiscellaneousHeap);
MiscellaneousHeap = NULL;
Check_Pointer(ShapeHeap);
gos_DestroyMemoryHeap(ShapeHeap);
ShapeHeap = NULL;
Check_Pointer(PrimitiveHeap);
gos_DestroyMemoryHeap(PrimitiveHeap);
PrimitiveHeap = NULL;
Check_Pointer(VertexPoolHeap);
gos_DestroyMemoryHeap(VertexPoolHeap);
VertexPoolHeap = NULL;
Check_Pointer(EffectHeap);
gos_DestroyMemoryHeap(EffectHeap);
EffectHeap = NULL;
Check_Pointer(ClipperHeap);
gos_DestroyMemoryHeap(ClipperHeap);
ClipperHeap = NULL;
Check_Pointer(SorterHeap);
gos_DestroyMemoryHeap(SorterHeap);
SorterHeap = NULL;
Check_Pointer(Heap);
gos_DestroyMemoryHeap(Heap);
Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MidLevelRenderer::ReadMLRVersion(MemoryStream *erf_stream)
{
Check_Object(erf_stream);
//
//------------------------------------------------------------------------
// See if this file has an erf signature. If so, the next int will be the
// version number. If not, assume it is version 1 and rewind the file
//------------------------------------------------------------------------
//
int version = -1;
int erf_signature;
*erf_stream >> erf_signature;
if (erf_signature == 'MLR#')
*erf_stream >> version;
else
erf_stream->RewindPointer(sizeof(erf_signature));
if (version > Current_MLR_Version)
STOP(("Application must be rebuilt to use this version of MLR data"));
return version;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MidLevelRenderer::WriteMLRVersion(MemoryStream *erf_stream)
{
Check_Object(erf_stream);
*erf_stream << 'MLR#' << static_cast<int>(Current_MLR_Version);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BYTE
FogData::FogVertex(const Stuff::Point3D *p)
{
Stuff::Vector3D v;
v.Subtract(*p, cameraPos);
Scalar d = v.GetApproximateLength();
BYTE df = (BYTE)( (d<near_fog+SMALL) ? 0xff : (d+SMALL>far_fog) ? 0 : Truncate_Float_To_Byte(255.0f*(1.0f - (d-near_fog)*one_over)) );
BYTE hhf;
if(height_fog_density < 0xff)
{
v.Subtract(*p, orgInShape);
Scalar h = v*upInShape;
hhf = (BYTE)( (h<height_low_fog+SMALL) ? height_fog_density : (h+SMALL>height_top_fog) ? 0xff : Truncate_Float_To_Byte(height_fog_density + height_fog_density0*(h-height_low_fog)) );
return (df < hhf ? df : hhf);
}
return df;
}
+727
View File
@@ -0,0 +1,727 @@
# Microsoft Developer Studio Project File - Name="MLR" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=MLR - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "MLR.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "MLR.mak" CFG="MLR - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MLR - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "MLR - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE "MLR - Win32 Armor" (based on "Win32 (x86) Static Library")
!MESSAGE "MLR - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "MLR - Win32 icecap" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/GameLeapCode/mw4/Libraries/MLR", STHAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "MLR - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../rel.bin"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /GR /Oa /Og /Oi /Oy /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "RELEASE" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /Yu"MLRHeaders.hpp" /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MLR - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../pro.bin"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /Zi /O2 /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "LAB_ONLY" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /Yu"MLRHeaders.hpp" /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MLR - Win32 Armor"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Armor"
# PROP BASE Intermediate_Dir "Armor"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../arm.bin"
# PROP Intermediate_Dir "Armor"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /GR /Zi /Ox /Ot /Oa /Og /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "LAB_ONLY" /D "NDEBUG" /D "_ARMOR" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /Yu"MLRHeaders.hpp" /FD /GF /c
# SUBTRACT CPP /WX /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MLR - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../dbg.bin"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /G6 /Zp4 /MDd /W4 /GR /Zi /Od /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "TRACE_ENABLE" /D "_ARMOR" /D "LAB_ONLY" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /D "_DEBUG" /FR /Yu"MLRHeaders.hpp" /FD /c
# SUBTRACT CPP /WX
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "MLR - Win32 icecap"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "icecap"
# PROP BASE Intermediate_Dir "icecap"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../ice.bin"
# PROP Intermediate_Dir "icecap"
# PROP Target_Dir ""
MTL=midl.exe
# ADD BASE CPP /nologo /G6 /Zp4 /MD /W4 /WX /Zi /Ox /Ot /Oa /Og /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "LAB_ONLY" /D "NDEBUG" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "WIN32" /Yu"MLRHeaders.hpp" /FD /GF /c
# SUBTRACT BASE CPP /Gf
# ADD CPP /nologo /G6 /Zp4 /MD /W4 /Zi /Ot /Oa /Oi /Gy /I "..\..\Libraries" /I "..\..\..\CoreTech\Libraries" /D "LAB_ONLY" /D "USE_PROTOTYPES" /D "STRICT" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /D "_ICECAP" /Yu"MLRHeaders.hpp" /FD /GF /c
# SUBTRACT CPP /WX /Og /Fr
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "MLR - Win32 Release"
# Name "MLR - Win32 Profile"
# Name "MLR - Win32 Armor"
# Name "MLR - Win32 Debug"
# Name "MLR - Win32 icecap"
# Begin Group "Geometries"
# PROP Default_Filter ""
# Begin Group "Indexed Polygon Meshes"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLR_I_C_DeT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DeT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DeT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DeT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DeT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DeT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DT_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DT_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_PMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_PMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_PMesh.hpp
# End Source File
# End Group
# Begin Group "Indexed Triangle Meshes"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLR_I_C_DeT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DeT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_DT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_C_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DeT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DeT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_DT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DeT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DeT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DT_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_DT_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_L_TMesh.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_TMesh.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_I_TMesh.hpp
# End Source File
# End Group
# Begin Group "Terrain"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLR_BumpyWater.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_BumpyWater.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_Terrain2.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_Terrain2.hpp
# End Source File
# Begin Source File
SOURCE=.\MLR_Water.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR_Water.hpp
# End Source File
# End Group
# Begin Source File
SOURCE=.\MLRClipTrick.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRCulturShape.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRCulturShape.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRFootstep.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRFootstep.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRIndexedPrimitiveBase.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRIndexedPrimitiveBase.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRPrimitiveBase.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRPrimitiveBase.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRPrimitiveClipping.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRPrimitiveLighting.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRShape.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRShape.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRTriangleClipping.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRTriangleLighting.hpp
# End Source File
# End Group
# Begin Group "Lighting"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLRAmbientLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRAmbientLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRCenterPointLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRCenterPointLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRInfiniteLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRInfiniteLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRInfiniteLightWithFalloff.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRInfiniteLightWithFallOff.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRLightMap.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRLightMap.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRLookUpLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRLookUpLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRPointLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRPointLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRProjectLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRProjectLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRShadowLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRShadowLight.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRSpotLight.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRSpotLight.hpp
# End Source File
# End Group
# Begin Group "Sorting"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLRSortByOrder.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRSortByOrder.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRSorter.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRSorter.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRState.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRState.hpp
# End Source File
# End Group
# Begin Group "Texture"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLRMovieTexture.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRMovieTexture.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRTexture.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRTexture.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRTexturePool.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRTexturePool.hpp
# End Source File
# End Group
# Begin Group "Rasterizer"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\GOSImage.cpp
# End Source File
# Begin Source File
SOURCE=.\GOSImage.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSImagePool.cpp
# End Source File
# Begin Source File
SOURCE=.\GOSImagePool.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex.cpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex2UV.cpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex2UV.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex3UV.cpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertex3UV.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertexManipulation.hpp
# End Source File
# Begin Source File
SOURCE=.\GOSVertexPool.hpp
# End Source File
# End Group
# Begin Group "Clipping"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLRClipper.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRClipper.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRClippingState.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRClippingState.hpp
# End Source File
# End Group
# Begin Group "Effects"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\MLRCardCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRCardCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLREffect.cpp
# End Source File
# Begin Source File
SOURCE=.\MLREffect.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRIndexedTriangleCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRIndexedTriangleCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRLineCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRLineCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRNGonCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRNGonCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRPointCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRPointCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRSpriteCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRSpriteCloud.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRTriangleCloud.cpp
# End Source File
# Begin Source File
SOURCE=.\MLRTriangleCloud.hpp
# End Source File
# End Group
# Begin Group "Documentation"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Documentation\overview.txt
# End Source File
# End Group
# Begin Source File
SOURCE=.\MLR.cpp
# End Source File
# Begin Source File
SOURCE=.\MLR.hpp
# End Source File
# Begin Source File
SOURCE=.\MLRHeaders.cpp
# ADD CPP /Yc"MLRHeaders.hpp"
# End Source File
# Begin Source File
SOURCE=.\MLRHeaders.hpp
# End Source File
# End Target
# End Project
+252
View File
@@ -0,0 +1,252 @@
//===========================================================================//
// File: MLRStuff.hpp //
// Project: Adept Brick: ??? //
// Contents: ??? //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 00/00/00 XXX Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1995-1998, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#define MLR_MLR_HPP
#if !defined(STUFF_STUFF_HPP)
#include <Stuff\Stuff.hpp>
#endif
namespace MidLevelRenderer
{
//
//--------------
// Stuff classes
//--------------
//
enum
{
MLRStateClassID = Stuff::FirstMLRClassID,
MLRClippingStateClassID,
MLRClipperClassID,
MLRSorterClassID,
MLRSortByOrderClassID,
MLRLightClassID,
MLRTexturePoolClassID,
MLRPrimitiveClassID,
MLRIndexedPrimitiveClassID,
MLRPolyMeshClassID,
MLRIndexedPolyMeshClassID,
MLRShapeClassID,
MLREffectClassID,
MLRPointCloudClassID,
MLRTriangleCloudClassID,
MLRAmbientLightClassID,
MLRInfiniteLightClassID,
MLRInfiniteLightWithFalloffClassID,
MLRPointLightClassID,
MLRSpotLightClassID,
MLRLightMapClassID,
MLRPrimitiveBaseClassID,
MLRIndexedPrimitiveBaseClassID,
MLR_I_PMeshClassID,
MLR_I_C_PMeshClassID,
MLR_I_L_PMeshClassID,
MLR_I_DT_PMeshClassID,
MLR_I_C_DT_PMeshClassID,
MLR_I_L_DT_PMeshClassID,
MLRNGonCloudClassID,
MLRCardCloudClassID,
MLR_I_MT_PMeshClassID,
MLR_I_DeT_PMeshClassID,
MLR_I_C_DeT_PMeshClassID,
MLR_I_L_DeT_PMeshClassID,
MLR_I_TMeshClassID,
MLR_I_DeT_TMeshClassID,
MLR_I_C_TMeshClassID,
MLR_I_L_TMeshClassID,
MLR_WaterClassID,
MLR_Terrain2ClassID,
MLRLineCloudClassID,
MLRIndexedTriangleCloudClassID,
MLR_I_DT_TMeshClassID,
MLR_I_C_DT_TMeshClassID,
MLR_I_L_DT_TMeshClassID,
MLR_I_C_DeT_TMeshClassID,
MLR_I_L_DeT_TMeshClassID,
MLRLookUpLightClassID,
MLRProjectLightClassID,
MLRSpriteCloudClassID,
MLRShadowLightClassID,
MLRCulturShapeClassID,
MLRCenterPointLightClassID,
MLRFootSteplClassID,
MLR_BumpyWaterClassID,
MLRTextureClassID,
MLRMovieTextureClassID,
FirstFreeMLRClassID
};
enum {
Current_MLR_Version = 18
};
struct Limits {
static unsigned
Max_Number_Vertices_Per_Frame,
Max_Number_Primitives_Per_Frame,
Max_Number_ScreenQuads_Per_Frame,
Max_Size_Of_LightMap_MemoryStream;
static Stuff::Scalar
LightThreshold;
enum {
Max_Number_Vertices_Per_Mesh = 256,
Max_Number_Vertices_Per_Effect = 1024,
Max_Number_Vertices_Per_Polygon = 32,
Max_Number_Of_Texture_Bits = 14,
Max_Number_Textures = 1 << Max_Number_Of_Texture_Bits,
Max_Number_Of_NGon_Vertices = 9,
Max_Number_Of_Multitextures = 8,
Max_Number_Of_Lights_Per_Primitive = 8,
Max_Number_Of_FogStates = 5,
Max_Size_Of_Vertex_Buffer = 2*Max_Number_Vertices_Per_Effect, // make sure this is the bigger one from
Max_Size_Of_Index_Buffer = 2*Max_Number_Vertices_Per_Effect // Max_Number_Vertices_Per_Mesh or
// Max_Number_Vertices_Per_Effect
};
};
int
ReadMLRVersion(Stuff::MemoryStream *erf_stream);
void
WriteMLRVersion(Stuff::MemoryStream *erf_stream);
void InitializeClasses(
Stuff::NotationFile *startup_ini = NULL,
unsigned Max_Number_Vertices_Per_Frame = 8192,
unsigned Max_Number_Primitives_Per_Frame = 1024,
unsigned Max_Number_ScreenQuads_Per_Frame = 512,
unsigned Max_Size_Of_LightMap_MemoryStream = 32768,
bool Convert_To_Triangle_Meshes = true
);
void TerminateClasses(Stuff::NotationFile *startup_ini=NULL);
extern HGOSHEAP Heap;
extern HGOSHEAP StaticHeap;
extern HGOSHEAP TexturePoolHeap;
extern HGOSHEAP StatesHeap;
extern HGOSHEAP LightsHeap;
extern HGOSHEAP MiscellaneousHeap;
extern HGOSHEAP ShapeHeap;
extern HGOSHEAP PrimitiveHeap;
extern HGOSHEAP VertexPoolHeap;
extern HGOSHEAP EffectHeap;
extern HGOSHEAP ClipperHeap;
extern HGOSHEAP SorterHeap;
extern bool ConvertToTriangleMeshes;
extern DWORD bucketColors[];
extern int terrainTextureResolution;
DECLARE_TIMER(extern, Scene_Draw_Time);
DECLARE_TIMER(extern, Transform_Time);
DECLARE_TIMER(extern, Clipping_Time);
DECLARE_TIMER(extern, GOS_Draw_Time);
DECLARE_TIMER(extern, Vertex_Light_Time);
DECLARE_TIMER(extern, LightMap_Light_Time);
DECLARE_TIMER(extern, Texture_Sorting_Time);
DECLARE_TIMER(extern, Alpha_Sorting_Time);
DECLARE_TIMER(extern, Unlock_Texture_Time);
DECLARE_TIMER(extern, Shape_Setup_Time);
DECLARE_TIMER(extern, Find_Backface_Time);
DECLARE_TIMER(extern, Fog_Time);
DECLARE_TIMER(extern, Shadow_Time);
extern DWORD Number_Of_Primitives;
extern DWORD NumAllIndices;
extern DWORD NumAllVertices;
extern float Index_Over_Vertex_Ratio;
extern DWORD TransformedVertices;
extern DWORD NumberOfAlphaSortedTriangles;
extern DWORD LitVertices;
extern DWORD NonClippedVertices;
extern DWORD ClippedVertices;
extern DWORD PolysClippedButOutside;
extern DWORD PolysClippedButInside;
extern DWORD PolysClippedButOnePlane;
extern DWORD PolysClippedButGOnePlane;
extern DWORD UsedGOSVertices;
extern DWORD UsedGOSVertices2UV;
extern DWORD UsedGOSVertices3UV;
extern DWORD UsedGOSIndicies;
#define COLOR_AS_DWORD 1
#if COLOR_AS_DWORD>0
typedef DWORD ColorType;
#else
typedef Stuff::RGBAColor ColorType;
#endif
extern DWORD paintMeColorDW;
extern Stuff::RGBAColor paintMeColorF;
typedef Stuff::Vector2DOf<Stuff::Scalar> Vector2DScalar;
}
#define EFECT_CLIPPED 0
#undef UV_CHECK
#define FOG_HACK 0
#if FOG_HACK==0
struct FogData {
Stuff::Scalar near_fog;
Stuff::Scalar far_fog;
Stuff::Scalar one_over;
Stuff::Scalar height_low_fog;
Stuff::Scalar height_top_fog;
Stuff::Scalar height_one_over;
Stuff::Scalar height_fog_density0;
BYTE height_fog_density;
Stuff::Point3D cameraPos;
Stuff::Point3D orgInShape;
Stuff::Vector3D upInShape;
BYTE FogVertex(const Stuff::Point3D*);
};
#endif
#define TO_DO Abort_Program("Here has work to be done !");
#include <MLR\MLRState.hpp>
+16
View File
@@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: MLR - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
MLR.lib - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
@@ -0,0 +1,102 @@
#include "MLRHeaders.hpp"
//#############################################################################
//########################### MLRAmbientLight ###########################
//#############################################################################
MLRAmbientLight::ClassData*
MLRAmbientLight::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRAmbientLight::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRAmbientLightClassID,
"MidLevelRenderer::MLRAmbientLight",
MLRLight::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRAmbientLight::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRAmbientLight::MLRAmbientLight() :
MLRLight(DefaultData)
{
Verify(gos_GetCurrentHeap() == LightsHeap);
lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRAmbientLight::MLRAmbientLight(
Stuff::MemoryStream *stream,
int version
) :
MLRLight(DefaultData, stream, version)
{
Check_Object(stream);
Verify(gos_GetCurrentHeap() == LightsHeap);
lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRAmbientLight::MLRAmbientLight(Stuff::Page *page) :
MLRLight(DefaultData, page)
{
Check_Object(page);
Verify(gos_GetCurrentHeap() == LightsHeap);
lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRAmbientLight::~MLRAmbientLight()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRAmbientLight::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRAmbientLight::LightVertex(const MLRVertexData& vertexData)
{
Stuff::RGBAColor *t = const_cast<Stuff::RGBAColor*>(vertexData.color);
Check_Pointer(t);
t->red += (color.red*intensity);
t->green += (color.green*intensity);
t->blue += (color.blue*intensity);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRAmbientLight::LightCenter(RGBAColor& rcol)
{
rcol.red += (color.red*intensity);
rcol.green += (color.green*intensity);
rcol.blue += (color.blue*intensity);
}
@@ -0,0 +1,57 @@
#pragma once
#define MLR_MLRAMBIENTLIGHT_HPP
#include "MLR.hpp"
#include "MLRLight.hpp"
namespace MidLevelRenderer {
//##########################################################################
//###################### MLRAmbientLight #############################
//##########################################################################
class MLRAmbientLight:
public MLRLight
{
public:
static void
InitializeClass();
static void
TerminateClass();
MLRAmbientLight();
MLRAmbientLight(
Stuff::MemoryStream *stream,
int version
);
MLRAmbientLight(Stuff::Page *page);
~MLRAmbientLight();
virtual void
LightVertex(const MLRVertexData&);
virtual void
LightCenter(RGBAColor&);
virtual LightType
GetLightType()
{ Check_Object(this); return AmbientLight; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance();
protected:
};
}
@@ -0,0 +1,862 @@
#include "MLRHeaders.hpp"
#if !defined(MLR_MLRCLIPTRICK_HPP)
#include <MLR\MLRClipTrick.hpp>
#endif
extern DWORD gShowClippedPolys;
//#############################################################################
//######################### MLRCardCloud ################################
//#############################################################################
DynamicArrayOf<MLRClippingState>
*MLRCardCloud::clipPerVertex;
DynamicArrayOf<Vector4D>
*MLRCardCloud::clipExtraCoords;
DynamicArrayOf<RGBAColor>
*MLRCardCloud::clipExtraColors;
DynamicArrayOf<Vector2DScalar>
*MLRCardCloud::clipExtraTexCoords;
DynamicArrayOf<int>
*MLRCardCloud::clipExtraLength;
MLRCardCloud::ClassData*
MLRCardCloud::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRCardCloudClassID,
"MidLevelRenderer::MLRCardCloud",
MLREffect::DefaultData
);
Register_Object(DefaultData);
clipPerVertex = new DynamicArrayOf<MLRClippingState> (Limits::Max_Number_Vertices_Per_Effect);
Register_Object(clipPerVertex);
clipExtraCoords = new DynamicArrayOf<Vector4D> (Limits::Max_Number_Vertices_Per_Effect);
Register_Object(clipExtraCoords);
clipExtraColors = new DynamicArrayOf<RGBAColor> (Limits::Max_Number_Vertices_Per_Effect);
Register_Object(clipExtraColors);
clipExtraTexCoords = new DynamicArrayOf<Vector2DScalar> (Limits::Max_Number_Vertices_Per_Effect);
Register_Object(clipExtraTexCoords);
clipExtraLength = new DynamicArrayOf<int> (Limits::Max_Number_Primitives_Per_Frame);
Register_Object(clipExtraLength);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::TerminateClass()
{
Unregister_Object(clipPerVertex);
delete clipPerVertex;
Unregister_Object(clipExtraCoords);
delete clipExtraCoords;
Unregister_Object(clipExtraColors);
delete clipExtraColors;
Unregister_Object(clipExtraTexCoords);
delete clipExtraTexCoords;
Unregister_Object(clipExtraLength);
delete clipExtraLength;
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCardCloud::MLRCardCloud(int nr) :
MLREffect(nr, DefaultData)
{
Verify(gos_GetCurrentHeap() == EffectHeap);
usedNrOfCards = NULL;
Check_Pointer(this);
drawMode = SortData::TriList;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCardCloud::~MLRCardCloud()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::SetData
(
const int *count,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
)
{
Check_Pointer(this);
usedNrOfCards = count;
Verify(*usedNrOfCards <= maxNrOf);
points = point_data;
colors = color_data;
Verify(texCoords != NULL);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::SetData
(
const int *count,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data,
const Vector2DScalar *uv_data
)
{
Check_Pointer(this);
usedNrOfCards = count;
Verify(*usedNrOfCards <= maxNrOf);
texCoords = uv_data;
SetData(count, point_data, color_data);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::Draw (DrawEffectInformation *dInfo, GOSVertexPool *allVerticesToDraw, MLRSorter *sorter)
{
Check_Object(this);
#ifdef LAB_ONLY
if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw->GetLast() + *usedNrOfCards * 4)
{
SPEWALWAYS((0, "Not drawing MLRCardCloud. Too many vertices! Raid a bug to Art!"));
return;
}
#endif
worldToEffect.Invert(*dInfo->effectToWorld);
Transform(*usedNrOfCards, 4);
if( Clip(dInfo->clippingFlags, allVerticesToDraw, false) )
{
sorter->AddEffect(this, dInfo->state);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MLRCardCloud::Draw (ToBeDrawnPrimitive *tbdp, MLRSorter *sorter)
{
Check_Object(this);
effectToClipMatrix = tbdp->shapeToClipMatrix;
Transform(*usedNrOfCards, 4);
int index = -1;
if( Clip(tbdp->clippingFlags, tbdp->allVerticesToDraw, true) )
{
sorter->AddEffect(this, tbdp->state, index);
}
return index;
}
static MLRClippingState theAnd, theOr, theTest;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MLRCardCloud::Clip(MLRClippingState clippingFlags, GOSVertexPool *vt, bool db)
{
Check_Object(this);
int i, j, k, l;
int end, len = *usedNrOfCards;
int mask, k1, ct=0, ret = 0;
Scalar a=0.0f, bc0, bc1;
Check_Object(vt);
gos_vertices = vt->GetActualVertexPool(db);
Check_Pointer(gos_vertices);
numGOSVertices = 0;
//
//--------------------------------------
// See if we don't have to draw anything
//--------------------------------------
//
if(clippingFlags.GetClippingState() == 0 || len <= 0)
{
if(len <= 0)
{
visible = 0;
}
else
{
//
//-------------------------------
// Handle the non-indexed version
//-------------------------------
//
for(i=0,j=0;i<len;i++,j+=4)
{
if(IsOn(i) == false)
{
continue;
}
GOSCopyTriangleData(
&gos_vertices[numGOSVertices],
transformedCoords->GetData(),
texCoords,
j, j+1, j+2
#if FOG_HACK
, true
#endif
);
DWORD tmpColor = GOSCopyColor(&colors[i]);
for(k=numGOSVertices;k<numGOSVertices+3;k++)
{
gos_vertices[k].argb = tmpColor;
}
gos_vertices[numGOSVertices + 3] = gos_vertices[numGOSVertices];
gos_vertices[numGOSVertices + 4] = gos_vertices[numGOSVertices + 2];
GOSCopyData(
&gos_vertices[numGOSVertices + 5],
transformedCoords->GetData(),
texCoords,
j+3
#if FOG_HACK
, true
#endif
);
gos_vertices[numGOSVertices + 5].argb = tmpColor;
numGOSVertices += 6;
}
if(db==false)
{
Check_Object(vt);
vt->Increase(numGOSVertices);
}
visible = numGOSVertices ? 1 : 0;
}
return visible;
}
int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
myNumberUsedClipVertex = 0;
myNumberUsedClipIndex = 0;
myNumberUsedClipLength = 0;
//
//-------------------------------
// Handle the non-indexed version
//-------------------------------
//
//
//-----------------------------------------------------------------
// Step through each polygon, making sure that we don't try to clip
// backfaced polygons
//-----------------------------------------------------------------
//
for(i=0,j=0;i<len;i++,j+=4)
{
if(IsOn(i) == false)
{
continue;
}
TurnVisible(i);
//
//---------------------------------------------------------------
// Test each vertex of the polygon against the allowed clipping
// planes, and accumulate status for which planes always clip and
// which planes clipped at least once
//---------------------------------------------------------------
//
theAnd.SetClippingState(0x3f);
theOr.SetClippingState(0);
end = j+4;
Stuff::Vector4D *v4d = transformedCoords->GetData() + j;
MLRClippingState *cs = clipPerVertex->GetData() + j;
for(k=j;k<end;k++,v4d++,cs++)
{
cs->Clip4dVertex(v4d);;
theAnd &= (*clipPerVertex)[k];
theOr |= (*clipPerVertex)[k];
#ifdef LAB_ONLY
if(*cs==0)
{
Set_Statistic(NonClippedVertices, NonClippedVertices+1);
}
else
{
Set_Statistic(ClippedVertices, ClippedVertices+1);
}
#endif
}
//
//-------------------------------------------------------------------
// If any bit is set for all vertices, then the polygon is completely
// outside the viewing space and we don't have to draw it. On the
// other hand, if no bits at all were ever set, we can do a trivial
// accept of the polygon
//-------------------------------------------------------------------
//
if (theAnd != 0)
{
TurnInVisible(i);
}
else if (theOr == 0)
{
TurnVisible(i);
GOSCopyTriangleData(
&gos_vertices[numGOSVertices],
transformedCoords->GetData(),
texCoords,
j, j+1, j+2
#if FOG_HACK
, true
#endif
);
DWORD tmpColor = GOSCopyColor(&colors[i]);
gos_vertices[numGOSVertices].argb = tmpColor;
gos_vertices[numGOSVertices + 1].argb = tmpColor;
gos_vertices[numGOSVertices + 2].argb = tmpColor;
gos_vertices[numGOSVertices + 3] = gos_vertices[numGOSVertices];
gos_vertices[numGOSVertices + 4] = gos_vertices[numGOSVertices + 2];
GOSCopyData(
&gos_vertices[numGOSVertices + 5],
transformedCoords->GetData(),
texCoords,
j+3
#if FOG_HACK
, true
#endif
);
gos_vertices[numGOSVertices + 5].argb = tmpColor;
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
for(l=0;l<6;l++)
{
gos_vertices[numGOSVertices+l].argb = 0xff0000ff;
gos_vertices[numGOSVertices+l].u = 0.0f;
gos_vertices[numGOSVertices+l].v = 0.0f;
}
}
#endif
numGOSVertices += 6;
ret++;
}
//
//-----------------------------------------------------------------
// It is not a trivial case, so we must now do real clipping on the
// polygon
//-----------------------------------------------------------------
//
else
{
// ultra small triangles clipped at farclip cause problems
if(theOr.IsFarClipped() == true)
{
continue;
}
int numberVerticesPerPolygon = 0;
//
//---------------------------------------------------------------
// Handle the case of a single clipping plane by stepping through
// the vertices and finding the edge it originates
//---------------------------------------------------------------
//
if (theOr.GetNumberOfSetBits() == 1)
{
for(k=j;k<end;k++)
{
k1 = (k+1 < end) ? k + 1 : j;
//
//----------------------------------------------------
// If this vertex is inside the viewing space, copy it
// directly to the clipping buffer
//----------------------------------------------------
//
int clipped_index =
myNumberUsedClipVertex + numberVerticesPerPolygon;
theTest = (*clipPerVertex)[k];
if(theTest == 0)
{
(*clipExtraCoords)[clipped_index] = (*transformedCoords)[k];
(*clipExtraTexCoords)[clipped_index] = texCoords[k];
(*clipExtraColors)[clipped_index] = colors[i];
numberVerticesPerPolygon++;
clipped_index++;
//
//-------------------------------------------------------
// We don't need to clip this edge if the next vertex is
// also in the viewing space, so just move on to the next
// vertex
//-------------------------------------------------------
//
if((*clipPerVertex)[k1] == 0)
{
continue;
}
}
//
//---------------------------------------------------------
// This vertex is outside the viewing space, so if the next
// vertex is also outside the viewing space, no clipping is
// needed and we throw this vertex away. Since only one
// clipping plane is involved, it must be in the same space
// as the first vertex
//---------------------------------------------------------
//
else if((*clipPerVertex)[k1] != 0)
{
Verify((*clipPerVertex)[k1] == (*clipPerVertex)[k]);
continue;
}
//
//--------------------------------------------------
// We now find the distance along the edge where the
// clipping plane will intersect
//--------------------------------------------------
//
mask = 1;
theTest |= (*clipPerVertex)[k1];
//
//-----------------------------------------------------
// Find the boundary conditions that match our clipping
// plane
//-----------------------------------------------------
//
for (l=0; l<MLRClippingState::NextBit; l++)
{
if(theTest.IsClipped(mask))
{
//
//-------------------------------------------
// Find the clipping interval from bc0 to bc1
//-------------------------------------------
//
a = GetLerpFactor(l, (*transformedCoords)[k], (*transformedCoords)[k1]);
Verify(a >= 0.0f && a <= 1.0f);
ct = l;
break;
}
mask <<= 1;
}
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
(*clipExtraCoords)[clipped_index].Lerp(
(*transformedCoords)[k],
(*transformedCoords)[k1],
a
);
DoClipTrick((*clipExtraCoords)[clipped_index], ct);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
(*clipExtraTexCoords)[clipped_index].Lerp(
texCoords[k],
texCoords[k1],
a
);
(*clipExtraColors)[clipped_index] = colors[i];
//
//--------------------------------
// Bump the polygon's vertex count
//--------------------------------
//
numberVerticesPerPolygon++;
}
}
//
//---------------------------------------------------------------
// We have to handle multiple planes. We do this by creating two
// buffers and we switch between them as we clip plane by plane
//---------------------------------------------------------------
//
else
{
EffectClipData srcPolygon, dstPolygon;
int dstBuffer = 0;
//
//-----------------------------------------------------
// Point the source polygon buffer at our original data
//-----------------------------------------------------
//
srcPolygon.coords = &((*transformedCoords)[j]);
srcPolygon.clipPerVertex = &((*clipPerVertex)[j]);
srcPolygon.flags = 0;
// srcPolygon.colors = const_cast<RGBAColor*>(&colors[j]);
srcPolygon.flags |= 2;
srcPolygon.texCoords = const_cast<Vector2DScalar*>(&texCoords[j]);
srcPolygon.length = 4;
//
//--------------------------------
// Point to the destination buffer
//--------------------------------
//
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
// dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
dstPolygon.flags = srcPolygon.flags;
dstPolygon.length = 0;
//
//-----------------------------------------------------------
// Spin through each plane that clipped the primitive and use
// it to actually clip the primitive
//-----------------------------------------------------------
//
mask = 1;
MLRClippingState theNewOr(0);
int loop = 4;
do
{
for(l=0; l<MLRClippingState::NextBit; l++)
{
if(theOr.IsClipped(mask))
{
//
//-----------------------------------
// Clip each vertex against the plane
//-----------------------------------
//
for(k=0;k<srcPolygon.length;k++)
{
k1 = (k+1 < srcPolygon.length) ? k+1 : 0;
theTest = srcPolygon.clipPerVertex[k];
//
//----------------------------------------------------
// If this vertex is inside the viewing space, copy it
// directly to the clipping buffer
//----------------------------------------------------
//
if(theTest.IsClipped(mask) == 0)
{
dstPolygon.coords[dstPolygon.length] =
srcPolygon.coords[k];
dstPolygon.clipPerVertex[dstPolygon.length] =
srcPolygon.clipPerVertex[k];
dstPolygon.texCoords[dstPolygon.length] =
srcPolygon.texCoords[k];
dstPolygon.length++;
//
//-------------------------------------------------------
// We don't need to clip this edge if the next vertex is
// also in the viewing space, so just move on to the next
// vertex
//-------------------------------------------------------
//
if(srcPolygon.clipPerVertex[k1].IsClipped(mask) == 0)
{
continue;
}
}
//
//---------------------------------------------------------
// This vertex is outside the viewing space, so if the next
// vertex is also outside the viewing space, no clipping is
// needed and we throw this vertex away. Since only one
// clipping plane is involved, it must be in the same space
// as the first vertex
//---------------------------------------------------------
//
else if(srcPolygon.clipPerVertex[k1].IsClipped(mask) != 0)
{
Verify(
srcPolygon.clipPerVertex[k1].IsClipped(mask)
== srcPolygon.clipPerVertex[k].IsClipped(mask)
);
continue;
}
//
//-------------------------------------------
// Find the clipping interval from bc0 to bc1
//-------------------------------------------
//
bc0 = GetBC(l, srcPolygon.coords[k]);
bc1 = GetBC(l, srcPolygon.coords[k1]);
Verify(!Close_Enough(bc0, bc1));
a = bc0 / (bc0 - bc1);
Verify(a >= 0.0f && a <= 1.0f);
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
dstPolygon.coords[dstPolygon.length].Lerp(
srcPolygon.coords[k],
srcPolygon.coords[k1],
a
);
DoCleanClipTrick(dstPolygon.coords[dstPolygon.length], l);
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k],
srcPolygon.texCoords[k1],
a
);
//
//-------------------------------------
// We have to generate a new clip state
//-------------------------------------
//
dstPolygon.clipPerVertex[dstPolygon.length].Clip4dVertex(&dstPolygon.coords[dstPolygon.length]);
//
//----------------------------------
// Bump the new polygon vertex count
//----------------------------------
//
dstPolygon.length++;
}
//
//-----------------------------------------------
// Swap source and destination buffer pointers in
// preparation for the next plane test
//-----------------------------------------------
//
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
// srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
srcPolygon.length = dstPolygon.length;
dstBuffer = !dstBuffer;
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
// dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
dstPolygon.length = 0;
}
mask = mask << 1;
}
theNewOr = 0;
for(k=0;k<srcPolygon.length;k++)
{
theNewOr |= srcPolygon.clipPerVertex[k];
}
theOr == theNewOr;
} while (theNewOr != 0 && loop--);
//
//--------------------------------------------------
// could not clip this rare case, just ignore it
//--------------------------------------------------
//
if(theNewOr != 0)
{
testList[i] = 0;
continue;
}
//
//--------------------------------------------------
// Move the most recent polygon into the clip buffer
//--------------------------------------------------
//
for(k=0;k<srcPolygon.length;k++)
{
int clipped_index = myNumberUsedClipVertex + k;
if(srcPolygon.coords[k].z == srcPolygon.coords[k].w)
{
srcPolygon.coords[k].z -= SMALL;
}
(*clipExtraCoords)[clipped_index] = srcPolygon.coords[k];
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[k];
(*clipExtraColors)[clipped_index] = colors[i];
}
numberVerticesPerPolygon = srcPolygon.length;
}
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
myNumberUsedClipVertex += numberVerticesPerPolygon;
myNumberUsedClipLength++;
ret++;
// clip
// dont draw the original
TurnInVisible(i);
}
}
if(myNumberUsedClipLength > 0)
{
for(i=0,j=0;i<myNumberUsedClipLength;i++)
{
int stride = (*clipExtraLength)[i];
for(k=1;k<stride-1;k++)
{
if(db==false)
{
Verify((vt->GetLast() + 3 + numGOSVertices) < vt->GetLength());
}
GOSCopyTriangleData(
&gos_vertices[numGOSVertices],
clipExtraCoords->GetData(),
clipExtraColors->GetData(),
clipExtraTexCoords->GetData(),
j, j+k+1, j+k
#if FOG_HACK
, true
#endif
);
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
gos_vertices[numGOSVertices].argb = 0xffff0000;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
gos_vertices[numGOSVertices+1].argb = 0xffff0000;
gos_vertices[numGOSVertices+1].u = 0.0f;
gos_vertices[numGOSVertices+1].v = 0.0f;
gos_vertices[numGOSVertices+2].argb = 0xffff0000;
gos_vertices[numGOSVertices+2].u = 0.0f;
gos_vertices[numGOSVertices+2].v = 0.0f;
}
#endif
numGOSVertices += 3;
}
j += stride;
}
}
if(db==false)
{
vt->Increase(numGOSVertices);
}
visible = numGOSVertices ? 1 : 0;
return visible;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCardCloud::TestInstance() const
{
if (usedNrOfCards)
{
Check_Pointer(usedNrOfCards);
Verify(*usedNrOfCards >= 0);
Verify(*usedNrOfCards <= maxNrOf);
}
}
@@ -0,0 +1,87 @@
#pragma once
#define MLR_MLRCardCloud_HPP
#if !defined(MLR_MLR_HPP)
#include <MLR\MLR.hpp>
#endif
#if !defined(MLR_MLREFFECT_HPP)
#include <MLR\MLREffect.hpp>
#endif
namespace MidLevelRenderer {
//##########################################################################
//####################### MLRCardCloud ###############################
//##########################################################################
class MLRCardCloud:
public MLREffect
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void
InitializeClass();
static void
TerminateClass();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
public:
MLRCardCloud(int);
~MLRCardCloud();
void
SetData(
const int *count,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data,
const Vector2DScalar *uv_data
);
void
SetData(
const int *count,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
);
void Draw (DrawEffectInformation*, GOSVertexPool*, MLRSorter*);
int Draw (ToBeDrawnPrimitive*, MLRSorter*);
int Clip(MLRClippingState, GOSVertexPool*, bool);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const;
protected:
const int *usedNrOfCards;
const Vector2DScalar *texCoords;
static Stuff::DynamicArrayOf<MLRClippingState> *clipPerVertex; // , Max_Number_Vertices_Per_Effect
static Stuff::DynamicArrayOf<Stuff::Vector4D> *clipExtraCoords; // , Max_Number_Vertices_Per_Effect
static Stuff::DynamicArrayOf<Stuff::RGBAColor> *clipExtraColors; // , Max_Number_Vertices_Per_Effect
static Stuff::DynamicArrayOf<Vector2DScalar> *clipExtraTexCoords; // , Max_Number_Vertices_Per_Effect
static Stuff::DynamicArrayOf<int> *clipExtraLength; // , Max_Number_Primitives_Per_Frame
};
}
@@ -0,0 +1,189 @@
#include "MLRHeaders.hpp"
//#############################################################################
//########################### MLRCenterPointLight #############################
//#############################################################################
MLRCenterPointLight::ClassData*
MLRCenterPointLight::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRCenterPointLightClassID,
"MidLevelRenderer::MLRCenterPointLight",
MLRInfiniteLightWithFalloff::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCenterPointLight::MLRCenterPointLight() :
MLRInfiniteLightWithFalloff(DefaultData)
{
Verify(gos_GetCurrentHeap() == LightsHeap);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCenterPointLight::MLRCenterPointLight(
Stuff::MemoryStream *stream,
int version
) :
MLRInfiniteLightWithFalloff(DefaultData, stream, version)
{
Check_Object(stream);
Verify(gos_GetCurrentHeap() == LightsHeap);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCenterPointLight::MLRCenterPointLight(Stuff::Page *page):
MLRInfiniteLightWithFalloff(DefaultData, page)
{
Check_Object(page);
Verify(gos_GetCurrentHeap() == LightsHeap);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCenterPointLight::~MLRCenterPointLight()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
MLRInfiniteLightWithFalloff::Save(stream);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::Write(Stuff::Page *page)
{
Check_Object(this);
Check_Object(page);
MLRInfiniteLightWithFalloff::Write(page);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::SetLightToShapeMatrix(const LinearMatrix4D& worldToShape)
{
Check_Object(this);
MLRLight::SetLightToShapeMatrix(worldToShape);
Point3D vertex_to_light;
GetInShapePosition(vertex_to_light);
Scalar lightToShapeDistance = vertex_to_light.GetApproximateLength();
falloff = 1.0f;
if(!GetFalloff(lightToShapeDistance, falloff))
{
falloff = -1.0f;
}
else
{
falloff *= intensity;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::TestInstance()
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::LightVertex(const MLRVertexData& vertexData)
{
UnitVector3D light_z;
RGBColor light_color(color);
//
//--------------------------------------------------------------
// If the distance to the vertex is zero, the light will not
// contribute to the vertex coloration. Otherwise, decrease the
// light level as appropriate to the distance
//--------------------------------------------------------------
//
if(falloff<0.0f)
{
return;
}
else
{
light_color.red *= falloff;
light_color.green *= falloff;
light_color.blue *= falloff;
}
Stuff::RGBAColor *t = const_cast<Stuff::RGBAColor*>(vertexData.color);
Check_Pointer(t);
t->red += light_color.red;
t->green += light_color.green;
t->blue += light_color.blue;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCenterPointLight::LightCenter(RGBAColor& rcol)
{
UnitVector3D light_z;
RGBColor light_color(color);
//
//--------------------------------------------------------------
// If the distance to the vertex is zero, the light will not
// contribute to the vertex coloration. Otherwise, decrease the
// light level as appropriate to the distance
//--------------------------------------------------------------
//
if(falloff<0.0f)
{
return;
}
else
{
light_color.red *= falloff;
light_color.green *= falloff;
light_color.blue *= falloff;
}
rcol.red += light_color.red;
rcol.green += light_color.green;
rcol.blue += light_color.blue;
}
@@ -0,0 +1,71 @@
#pragma once
#define MLR_MLRCENTERPOINTLIGHT_HPP
#include "MLR.hpp"
#include "MLRPointLight.hpp"
namespace MidLevelRenderer {
//##########################################################################
//################### MLRCenterPointLight ############################
//##########################################################################
class MLRCenterPointLight:
public MLRInfiniteLightWithFalloff
{
public:
static void
InitializeClass();
static void
TerminateClass();
MLRCenterPointLight();
MLRCenterPointLight(
Stuff::MemoryStream *stream,
int version
);
MLRCenterPointLight(Stuff::Page *page);
~MLRCenterPointLight();
void
Save(Stuff::MemoryStream *stream);
void
Write(Stuff::Page *page);
virtual void
LightVertex(const MLRVertexData&);
virtual void
LightCenter(RGBAColor&);
virtual LightType
GetLightType()
{ Check_Object(this); return CenterPointLight; }
virtual MLRLightMap *
GetLightMap()
{Check_Object(this); return NULL; }
virtual
void SetLightToShapeMatrix(const Stuff::LinearMatrix4D&);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance();
protected:
Stuff::Scalar
falloff;
};
}
@@ -0,0 +1,21 @@
#pragma once
#define MLR_MLRCLIPTRICK_HPP
#if !defined(STUFF_VECTOR4D_HPP)
#include <Stuff\Vector4D.hpp>
#endif
// defined in MLRPrimitiveBase.cpp
extern int clipTrick[6][2];
inline void
DoClipTrick(Vector4D& v, int ct)
{
v[clipTrick[ct][0]] = clipTrick[ct][1] ? v.w-SMALL : SMALL;
}
inline void
DoCleanClipTrick(Vector4D& v, int ct)
{
v[clipTrick[ct][0]] = clipTrick[ct][1] ? v.w : 0.0f;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
#pragma once
#define MLR_MLRCLIPPER_HPP
#include <MLR\MLR.hpp>
#include <MLR\MLRSorter.hpp>
#include <MLR\MLRLight.hpp>
#include <MLR\MLRCulturShape.hpp>
#include <MLR\GOSVertexPool.hpp>
namespace MidLevelRenderer {
typedef int AndyDisplay;
class DrawShapeInformation
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
DrawShapeInformation();
MLRShape *shape;
MLRState state;
MLRClippingState clippingFlags;
const Stuff::LinearMatrix4D *shapeToWorld;
const Stuff::LinearMatrix4D *worldToShape;
MLRLight *const *activeLights;
int nrOfActiveLights;
const Stuff::RGBAColor *paintMeColor;
void
TestInstance() const
{}
};
class DrawScalableShapeInformation : public DrawShapeInformation
{
public:
DrawScalableShapeInformation();
const Stuff::Vector3D *scaling;
void
TestInstance() const
{}
};
class MLREffect;
class DrawEffectInformation
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
DrawEffectInformation();
MLREffect *effect;
MLRState state;
MLRClippingState clippingFlags;
const Stuff::LinearMatrix4D *effectToWorld;
#if 0 // for the time being no lights on the effects
MLRLight *const *activeLights;
int nrOfActiveLights;
#endif
void
TestInstance() const
{}
};
class DrawScreenQuadsInformation
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
DrawScreenQuadsInformation();
const Stuff::Vector4D *coords;
const Stuff::RGBAColor *colors;
const Vector2DScalar *texCoords;
const bool *onOrOff;
int
nrOfQuads,
currentNrOfQuads;
MLRState state;
void
TestInstance() const
{}
};
//##########################################################################
//######################### MLRClipper #################################
//##########################################################################
class MLRClipper :
public Stuff::RegisteredClass
{
public:
static void
InitializeClass();
static void
TerminateClass();
// Camera gets attached to a film
MLRClipper(AndyDisplay*, MLRSorter*);
~MLRClipper();
// lets begin the dance
void StartDraw(
const Stuff::LinearMatrix4D& camera_to_world,
const Stuff::Matrix4D& clip_matrix,
const Stuff::RGBAColor &fog_color, // NOT USED ANYMORE
const Stuff::RGBAColor *background_color,
const MLRState &default_state,
const Stuff::Scalar *z_value,
float top=1.0f, float left=1.0f, float bottom=0.0f, float right=0.0f
);
void UpdateClipperCameraData(
const Stuff::LinearMatrix4D &camera_to_world,
const Stuff::Matrix4D &cameraToClip
);
// add another shape
void DrawShape (DrawShapeInformation*);
// add another shape
void DrawScalableShape (DrawScalableShapeInformation*);
// add screen quads
void DrawScreenQuads (DrawScreenQuadsInformation*);
// add another effect
void DrawEffect (DrawEffectInformation*);
// starts the action
void RenderNow ()
{ Check_Object(this); sorter->RenderNow(); }
// clear the film
void Clear (unsigned int flags);
AndyDisplay* GetDisplay () const
{ Check_Object(this); return display; };
// statistics and time
unsigned int GetFrameRate () const
{ Check_Object(this); return frameRate; }
void SetTime (Stuff::Scalar t)
{ Check_Object(this); nowTime = t; }
Stuff::Scalar GetTime () const
{ Check_Object(this); return nowTime; }
const Stuff::LinearMatrix4D&
GetCameraToWorldMatrix()
{Check_Object(this); return cameraToWorldMatrix;}
const Stuff::LinearMatrix4D&
GetWorldToCameraMatrix()
{Check_Object(this); return worldToCameraMatrix;}
const Stuff::Matrix4D&
GetCameraToClipMatrix()
{Check_Object(this); return cameraToClipMatrix;}
const Stuff::Matrix4D&
GetWorldToClipMatrix()
{Check_Object(this); return worldToClipMatrix;}
void
ResetSorter(const MLRState &default_state)
{Check_Object(this); sorter->StartDraw(default_state); sorter->Reset();}
void
SetCurrentState()
{ Check_Object(this); sorter->SetCurrentState(); }
void
SetTexturePoolInSorter(MLRTexturePool *pool)
{ Check_Object(this); sorter->SetTexturePool(pool); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{};
protected:
// statistics and time
unsigned int frameRate;
Stuff::Scalar usedTime;
Stuff::Scalar nowTime;
// world-to-camera matrix
Stuff::LinearMatrix4D
worldToCameraMatrix;
Stuff::LinearMatrix4D
cameraToWorldMatrix;
Stuff::Matrix4D
cameraToClipMatrix;
Stuff::Matrix4D
worldToClipMatrix;
Stuff::Point3D
cameraPosition;
Stuff::Point3D
cameraDirection;
// this is the film
AndyDisplay *display;
// this defines the sort order of the draw
MLRSorter *sorter;
GOSVertexPool allVerticesToDraw;
};
}
@@ -0,0 +1,49 @@
#include "MLRHeaders.hpp"
//#############################################################################
//######################### MLRClippingState ############################
//#############################################################################
int MLRClippingState::numberBitsLookUpTable[MLRClippingState::ClipMask+1] = {
0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRClippingState::Save(MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
//
//-------------------------------------
// Save the clippingState to the stream
//-------------------------------------
//
*stream << clippingState;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRClippingState::Load(MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
//
//---------------------------------------
// Load the clippingState from the stream
//---------------------------------------
//
*stream >> clippingState;
}
@@ -0,0 +1,338 @@
#pragma once
#define MLR_MLRCLIPPINGSTATE_HPP
#if !defined(MLR_MLR_HPP)
#include <MLR\MLR.hpp>
#endif
namespace MidLevelRenderer {
//##########################################################################
//#################### MLRClippingState ##############################
//##########################################################################
class MLRClippingState
{
protected:
int
clippingState;
public:
MLRClippingState()
{ clippingState = 0; };
MLRClippingState(int i)
{ clippingState = i; };
MLRClippingState(const MLRClippingState& state)
{ clippingState = state.clippingState;}
//##########################################################################
// Attention !!! when changing the flags also change them in
// Stuff::Vector4D::MultiplySetClip the assembler block
//
//##########################################################################
enum {
TopClipBit = 0,
BottomClipBit,
LeftClipBit,
RightClipBit,
NearClipBit,
FarClipBit,
NextBit
};
enum {
TopClipFlag = 1<<TopClipBit,
BottomClipFlag = 1<<BottomClipBit,
LeftClipFlag = 1<<LeftClipBit,
RightClipFlag = 1<<RightClipBit,
NearClipFlag = 1<<NearClipBit,
FarClipFlag = 1<<FarClipBit,
ClipMask =
TopClipFlag | BottomClipFlag | LeftClipFlag
| RightClipFlag | NearClipFlag | FarClipFlag
};
bool
IsFarClipped()
{Check_Pointer(this); return (clippingState&FarClipFlag) != 0;}
void
SetFarClip()
{Check_Pointer(this); clippingState |= FarClipFlag;}
void
ClearFarClip()
{Check_Pointer(this); clippingState &= ~FarClipFlag;}
bool
IsNearClipped()
{Check_Pointer(this); return (clippingState&NearClipFlag) != 0;}
void
SetNearClip()
{Check_Pointer(this); clippingState |= NearClipFlag;}
void
ClearNearClip()
{Check_Pointer(this); clippingState &= ~NearClipFlag;}
bool
IsTopClipped()
{Check_Pointer(this); return clippingState&TopClipFlag;}
void
SetTopClip()
{Check_Pointer(this); clippingState |= TopClipFlag;}
void
ClearTopClip()
{Check_Pointer(this); clippingState &= ~TopClipFlag;}
bool
IsBottomClipped()
{Check_Pointer(this); return (clippingState&BottomClipFlag) != 0;}
void
SetBottomClip()
{Check_Pointer(this); clippingState |= BottomClipFlag;}
void
ClearBottomClip()
{Check_Pointer(this); clippingState &= ~BottomClipFlag;}
bool
IsLeftClipped()
{Check_Pointer(this); return (clippingState&LeftClipFlag) != 0;}
void
SetLeftClip()
{Check_Pointer(this); clippingState |= LeftClipFlag;}
void
ClearLeftClip()
{Check_Pointer(this); clippingState &= ~LeftClipFlag;}
bool
IsRightClipped()
{Check_Pointer(this); return (clippingState&RightClipFlag) != 0;}
void
SetRightClip()
{Check_Pointer(this); clippingState |= RightClipFlag;}
void
ClearRightClip()
{Check_Pointer(this); clippingState &= ~RightClipFlag;}
void
SetClip(int mask, int flag)
{
Check_Pointer(this);
#if USE_ASSEMBLER_CODE
_asm {
xor ecx, ecx
mov ebx, mask
test ebx, 0ffffffffh
seta cl
xor eax, eax
sub eax, ecx
and flag, eax
}
clippingState |= flag;
#else
if(mask != 0)
{
clippingState |= flag;
}
#endif
}
bool
IsClipped(int mask)
{Check_Pointer(this); return (clippingState & mask) != 0;}
int
GetClippingState()
{Check_Pointer(this); return (clippingState & ClipMask);}
void
SetClippingState(int state)
{Check_Pointer(this); clippingState = state & ClipMask;}
int
GetNumberOfSetBits()
{Check_Pointer(this); Verify(clippingState<=ClipMask);
return numberBitsLookUpTable[clippingState]; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Assignment operators
//
public:
MLRClippingState&
operator=(const MLRClippingState &s)
{
Check_Pointer(this);
clippingState = s.clippingState;
return *this;
}
MLRClippingState&
operator&=(const MLRClippingState &s)
{
Check_Pointer(this);
clippingState &= s.clippingState;
return *this;
}
MLRClippingState&
operator|=(const MLRClippingState &s)
{
Check_Pointer(this);
clippingState |= s.clippingState;
return *this;
}
bool
operator==(const MLRClippingState &s)
{
Check_Pointer(this);
return (clippingState == s.clippingState);
}
bool
operator==(const int &s)
{
Check_Pointer(this);
return (clippingState == s);
}
bool
operator!=(const MLRClippingState &s)
{
Check_Pointer(this);
return (clippingState != s.clippingState);
}
bool
operator!=(const int &s)
{
Check_Pointer(this);
return (clippingState != s);
}
void
Save(Stuff::MemoryStream *stream);
void
Load(Stuff::MemoryStream *stream);
inline void
Clip4dVertex(Stuff::Vector4D *v4d);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance()
{}
private:
static int numberBitsLookUpTable[ClipMask+1];
};
inline void
MLRClippingState::Clip4dVertex(Stuff::Vector4D *v4d)
{
#if USE_ASSEMBLER_CODE
int _ret = 0;
_asm {
mov edi, v4d
xor ecx,ecx
xor edx, edx
test dword ptr [edi], 080000000h
setne cl
sub edx, ecx
and edx, 8 // RightClipFlag
xor ebx, ebx
test dword ptr [edi+4], 080000000h
setne cl
sub ebx, ecx
and ebx, 2 // BottomClipFlag
or edx, ebx
xor ebx, ebx
test dword ptr [edi+8], 080000000h
setne cl
sub ebx, ecx
and ebx, 16 // NearClipFlag
or edx, ebx
fld dword ptr [edi+0Ch]
xor ebx, ebx
fcom dword ptr [edi]
fnstsw ax
test ah, 1
setne cl
sub ebx, ecx
and ebx, 4 // LeftClipFlag
or edx, ebx
xor ebx, ebx
fcom dword ptr [edi+4]
fnstsw ax
test ah, 1
setne cl
sub ebx, ecx
and ebx, 1 // TopClipFlag
or edx, ebx
xor ebx, ebx
fcomp dword ptr [edi+8]
fnstsw ax
test ah, 41h
setne cl
sub ebx, ecx
and ebx, 32 // FarClipFlag
or edx, ebx
mov _ret, edx
}
clippingState = _ret;
#else
clippingState = 0;
if(v4d->w <= v4d->z)
{
SetFarClip();
}
if(v4d->z < 0.0f)
{
SetNearClip();
}
if(v4d->x < 0.0f)
{
SetRightClip();
}
if(v4d->w < v4d->x)
{
SetLeftClip();
}
if(v4d->y < 0.0f)
{
SetBottomClip();
}
if(v4d->w < v4d->y)
{
SetTopClip();
}
#endif
}
}
@@ -0,0 +1,173 @@
#include "MLRHeaders.hpp"
//#############################################################################
//########################### MLRCulturShape ############################
//#############################################################################
MLRCulturShape::ClassData*
MLRCulturShape::DefaultData = NULL;
MLRShape*
MLRCulturShape::culturalRevolution = NULL;
bool
MLRCulturShape::isDayTime = true;
Stuff::RGBAColor
MLRCulturShape::dayColor = RGBAColor::White;
Stuff::RGBAColor
MLRCulturShape::nightColor = RGBAColor::White;
Stuff::DynamicArrayOf<MLR_I_C_TMesh*> *MLRCulturShape::theNaturals = NULL;
Stuff::DynamicArrayOf<Stuff::Point3D> *MLRCulturShape::theNaturalCoords = NULL;
Stuff::DynamicArrayOf<Vector2DScalar> *MLRCulturShape::theNaturalTexCoords = NULL;
Stuff::DynamicArrayOf<BYTE> *MLRCulturShape::theNaturalIndicies = NULL;
Stuff::DynamicArrayOf<ColorType> *MLRCulturShape::theNaturalColors = NULL;
int MLRCulturShape::lastUsedMesh = 0, MLRCulturShape::lastUsedVertex = 0, MLRCulturShape::nrOfNaturalMeshes = 16;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCulturShape::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRCulturShapeClassID,
"MidLevelRenderer::MLRCulturShape",
MLRShape::DefaultData
);
Register_Object(DefaultData);
isDayTime = true;
dayColor = RGBAColor::White;
nightColor = RGBAColor(0.447059f, 0.55934f, 0.58317f, 1.0f);
theNaturals = new DynamicArrayOf<MLR_I_C_TMesh*> (nrOfNaturalMeshes);
for(int i=0;i<nrOfNaturalMeshes;i++)
{
(*theNaturals)[i] = new MLR_I_C_TMesh;
}
theNaturalCoords = new DynamicArrayOf<Point3D> (nrOfNaturalMeshes*Limits::Max_Number_Vertices_Per_Mesh);
theNaturalTexCoords = new DynamicArrayOf<Vector2DScalar> (nrOfNaturalMeshes*Limits::Max_Number_Vertices_Per_Mesh);
theNaturalIndicies = new DynamicArrayOf<BYTE> (nrOfNaturalMeshes*Limits::Max_Number_Vertices_Per_Mesh);
theNaturalColors = new DynamicArrayOf<ColorType> (nrOfNaturalMeshes*Limits::Max_Number_Vertices_Per_Mesh);
culturalRevolution = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCulturShape::TerminateClass()
{
if(culturalRevolution!=NULL)
{
culturalRevolution->DetachReference();
}
for(int i=0;i<nrOfNaturalMeshes;i++)
{
(*theNaturals)[i]->DetachReference();
}
theNaturals->SetLength(0);
delete theNaturals;
theNaturalCoords->SetLength(0);
delete theNaturalCoords;
theNaturalTexCoords->SetLength(0);
delete theNaturalTexCoords;
theNaturalIndicies->SetLength(0);
delete theNaturalIndicies;
theNaturalColors->SetLength(0);
delete theNaturalColors;
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
if(culturalRevolution!=NULL)
{
Unregister_Object(culturalRevolution);
culturalRevolution->DetachReference();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCulturShape::MLRCulturShape(
MemoryStream *stream,
int version
) :
MLRShape(DefaultData, stream, version)
{
*stream >> centerInWorldX >> centerInWorldZ;
*stream >> fadeOutStart >> fadeOutEnd;
*stream >> radius;
MemoryStreamIO_Read(stream, &culturals);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCulturShape::MLRCulturShape():
MLRShape(0, DefaultData)
{
Verify(gos_GetCurrentHeap() == ShapeHeap);
centerInWorldX = 0.0f;
centerInWorldZ = 0.0f;
fadeOutStart = 50.0f;
fadeOutEnd = 80.0f;
radius = 114.0f;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCulturShape::~MLRCulturShape()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRCulturShape*
MLRCulturShape::Make(
MemoryStream *stream,
int version
)
{
Check_Object(stream);
gos_PushCurrentHeap(ShapeHeap);
MLRCulturShape *shape = new MLRCulturShape(stream, version);
gos_PopCurrentHeap();
return shape;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRCulturShape::Save(MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
MLRShape::Save(stream);
*stream << centerInWorldX << centerInWorldZ;
*stream << fadeOutStart << fadeOutEnd;
*stream << radius;
MemoryStreamIO_Write(stream, &culturals);
}
@@ -0,0 +1,119 @@
#pragma once
#define MLR_MLRCULTURSHAPE_HPP
#include <MLR\MLRShape.hpp>
#include <MLR\MLR_I_C_TMesh.hpp>
namespace MidLevelRenderer {
struct MLRCultural {
Stuff::Point3D loc;
BYTE yaw;
BYTE type;
};
//##########################################################################
//####################### MLRCulturShape #############################
//##########################################################################
class MLRCulturShape :
public MLRShape
{
friend class MLRClipper;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void
InitializeClass();
static void
TerminateClass();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
MLRCulturShape(
Stuff::MemoryStream *stream,
int version
);
~MLRCulturShape();
public:
MLRCulturShape();
static MLRCulturShape*
Make(
Stuff::MemoryStream *stream,
int version
);
void
Save(Stuff::MemoryStream *stream);
void
SetCenterInWorld(Stuff::Scalar ciwx, Stuff::Scalar ciwz, Stuff::Scalar r)
{ Check_Object(this); centerInWorldX = ciwx; centerInWorldZ = ciwz; radius = r; }
void
FadeValue(Stuff::Scalar start, Stuff::Scalar end)
{ Check_Object(this); fadeOutStart = start; fadeOutEnd = end;}
void
AssignCulturalData(MLRCultural *data, int count)
{ Check_Object(this); culturals.AssignData(data, count); }
static MLRShape*
culturalRevolution;
static void
IsDayTime(bool b=true)
{ isDayTime = b; }
static void
SetColor(Stuff::RGBAColor day, Stuff::RGBAColor night)
{ dayColor = day; nightColor = night; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{};
protected:
static Stuff::RGBAColor
dayColor, nightColor;
static bool
isDayTime;
Stuff::Scalar
centerInWorldX, centerInWorldZ, radius;
Stuff::Scalar
fadeOutStart, fadeOutEnd;
Stuff::ReadOnlyArrayOf<MLRCultural>
culturals;
static int lastUsedMesh, lastUsedVertex, nrOfNaturalMeshes;
static Stuff::DynamicArrayOf<MLR_I_C_TMesh*> *theNaturals;
static Stuff::DynamicArrayOf<Stuff::Point3D> *theNaturalCoords;
static Stuff::DynamicArrayOf<Vector2DScalar> *theNaturalTexCoords;
static Stuff::DynamicArrayOf<BYTE> *theNaturalIndicies;
static Stuff::DynamicArrayOf<ColorType> *theNaturalColors;
};
}
@@ -0,0 +1,193 @@
#include "MLRHeaders.hpp"
//#############################################################################
//############################ MLREffect #################################
//#############################################################################
void EffectClipPolygon::Init()
{
Verify(gos_GetCurrentHeap() == StaticHeap);
coords.SetLength(Limits::Max_Number_Vertices_Per_Polygon);
colors.SetLength(Limits::Max_Number_Vertices_Per_Polygon);
texCoords.SetLength(Limits::Max_Number_Vertices_Per_Polygon);
clipPerVertex.SetLength(Limits::Max_Number_Vertices_Per_Polygon);
}
void EffectClipPolygon::Destroy()
{
coords.SetLength(0);
colors.SetLength(0);
texCoords.SetLength(0);
clipPerVertex.SetLength(0);
}
//#############################################################################
//############################ MLREffect #################################
//#############################################################################
MLREffect::ClassData*
MLREffect::DefaultData = NULL;
EffectClipPolygon
*MLREffect::clipBuffer;
DynamicArrayOf<Vector4D>
*MLREffect::transformedCoords;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLREffectClassID,
"MidLevelRenderer::MLREffect",
RegisteredClass::DefaultData
);
Register_Object(DefaultData);
transformedCoords = new DynamicArrayOf<Vector4D> (Limits::Max_Number_Vertices_Per_Effect);
Register_Object(transformedCoords);
clipBuffer = new EffectClipPolygon [2];
Register_Pointer(clipBuffer);
clipBuffer[0].Init();
clipBuffer[1].Init();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::TerminateClass()
{
clipBuffer[1].Destroy();
clipBuffer[0].Destroy();
Unregister_Pointer(clipBuffer);
delete [] clipBuffer;
Unregister_Object(transformedCoords);
delete transformedCoords;
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLREffect::MLREffect(int nr, ClassData *class_data):
RegisteredClass(class_data)
{
Verify(gos_GetCurrentHeap() == EffectHeap);
visible = 0;
maxNrOf = nr;
testList.SetLength(maxNrOf);
for(int i=0; i < maxNrOf; i++)
{
testList[i] = 0;
}
TurnAllOff();
TurnAllVisible();
worldToEffect = LinearMatrix4D::Identity;
gos_vertices = NULL;
numGOSVertices = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLREffect::~MLREffect()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::Transform(int nrOfUsedEffects, int nrOfVertices)
{
Check_Object(this);
MLR_RENDER("Transform::MLREffect");
Start_Timer(Transform_Time);
int i, j, k;
for(i=0,j=0;i<nrOfUsedEffects;i++,j+=nrOfVertices)
{
if(IsOn(i) == false)
{
continue;
}
for(k=j;k<j+nrOfVertices;k++)
{
(*transformedCoords)[k].Multiply(points[k], effectToClipMatrix);
}
}
Stop_Timer(Transform_Time);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::TurnAllOn()
{
Check_Object(this);
int i;
for(i=0;i<maxNrOf;i++)
{
testList[i] |= 2;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::TurnAllOff()
{
Check_Object(this);
int i;
for(i=0;i<maxNrOf;i++)
{
testList[i] &= ~2;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::TurnAllVisible()
{
Check_Object(this);
int i;
for(i=0;i<maxNrOf;i++)
{
testList[i] |= 1;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLREffect::TurnAllInVisible()
{
Check_Object(this);
int i;
for(i=0;i<maxNrOf;i++)
{
testList[i] &= ~1;
}
}
@@ -0,0 +1,175 @@
#pragma once
#define MLR_MLREFFECT_HPP
#if !defined(MLR_MLR_HPP)
#include <MLR\MLR.hpp>
#endif
namespace MidLevelRenderer {
struct EffectClipPolygon
{
void Init();
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; //[Max_Number_Vertices_Per_Polygon];
Stuff::DynamicArrayOf<MLRClippingState> clipPerVertex; //[Max_Number_Vertices_Per_Polygon];
};
class DrawEffectInformation;
class GOSVertexPool;
class SortData;
struct ToBeDrawnPrimitive;
class GOSVertex;
//##########################################################################
//######################### MLREffect #################################
//##########################################################################
class MLREffect :
public Stuff::RegisteredClass
{
public:
static void
InitializeClass();
static void
TerminateClass();
MLREffect(int, ClassData *class_data);
~MLREffect();
virtual void
SetData(
const int *count,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data
) = 0;
virtual int
GetType(int) { return 0; }
// add another effect
virtual void Draw (DrawEffectInformation*, GOSVertexPool*, MLRSorter*) = 0;
virtual int Draw (ToBeDrawnPrimitive*, MLRSorter*) = 0;
virtual void Transform(int, int);
// switches single/all effects on or off
void
TurnAllOn();
void
TurnAllOff();
void
TurnOn(int nr)
{ Check_Object(this); Verify(nr<maxNrOf); testList[nr] |= 2; }
void
TurnOff(int nr)
{ Check_Object(this); Verify(nr<maxNrOf); testList[nr] &= ~2; }
bool IsOn(int nr)
{ Check_Object(this); Verify(nr<maxNrOf); return (testList[nr] & 2)? true : false; }
virtual int Clip(MLRClippingState, GOSVertexPool*, bool) = 0;
void
SetEffectToClipMatrix(
const Stuff::LinearMatrix4D *effectToWorld,
const Stuff::Matrix4D *worldToClipMatrix
)
{
Check_Object(this);
effectToClipMatrix.Multiply(*effectToWorld, *worldToClipMatrix);
}
GOSVertex*
GetGOSVertices()
{ Check_Object(this); return gos_vertices; }
int
GetNumGOSVertices()
{ Check_Object(this); return numGOSVertices; }
int
GetSortDataMode()
{ Check_Object(this); return drawMode; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class Data Support
//
public:
static ClassData
*DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{};
void
GetCoordData(
const Stuff::Point3D **array,
int *point_count
)
{
*array=points;
*point_count=visible;
}
protected:
static EffectClipPolygon *clipBuffer;
void
TurnAllVisible();
void
TurnAllInVisible();
void
TurnVisible(int nr)
{ Check_Object(this); Verify(nr<maxNrOf); testList[nr] |= 1; }
void
TurnInVisible(int nr)
{ Check_Object(this); Verify(nr<maxNrOf); testList[nr] &= ~1; }
int visible;
int maxNrOf;
const Stuff::Point3D *points;
const Stuff::RGBAColor *colors;
static Stuff::DynamicArrayOf<Stuff::Vector4D> *transformedCoords;
Stuff::DynamicArrayOf<BYTE> testList;
int drawMode;
Stuff::LinearMatrix4D
worldToEffect;
Stuff::Matrix4D
effectToClipMatrix;
GOSVertex *gos_vertices;
int numGOSVertices;
};
struct EffectClipData
{
Stuff::Vector4D *coords;
Stuff::RGBAColor *colors;
Vector2DScalar *texCoords;
MLRClippingState *clipPerVertex;
int flags;
int length;
};
}
@@ -0,0 +1,195 @@
#include "MLRHeaders.hpp"
#include "MLR\MLRFootstep.hpp"
MLRFootStep *MLRFootStep::Instance = NULL;
MLRFootStep::ClassData*
MLRFootStep::DefaultData = NULL;
//#############################################################################
//############################ MLRFootStep ##############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRFootStep::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRFootSteplClassID,
"MidLevelRenderer::MLRFootStep",
RegisteredClass::DefaultData
);
Register_Object(DefaultData);
Instance = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRFootStep::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRFootStep::MLRFootStep(MemoryStream *stream):
RegisteredClass(DefaultData)
{
STOP(("Not implemented"));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRFootStep::MLRFootStep(int nrOfActiveFootSteps):
RegisteredClass(DefaultData), theFootSteps(nrOfActiveFootSteps)
{
firstStep = 0;
lastStep = 0;
SetFadeOut(150.0f, 200.0f);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRFootStep::~MLRFootStep()
{
for(int i=0;i<theFootSteps.GetLength();i++)
{
if(theFootSteps[i].shape != NULL)
{
theFootSteps[i].shape->DetachReference();
theFootSteps[i].shape = NULL;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FootStepInfo*
MLRFootStep::AddAStep(MLRShape *shape, Point3D& loc)
{
if(theFootSteps[lastStep].shape != NULL)
{
theFootSteps[lastStep].shape->DetachReference();
}
int ret = lastStep;
theFootSteps[lastStep].shape = shape;
theFootSteps[lastStep].location = loc;
lastStep++;
if(lastStep==theFootSteps.GetLength())
{
lastStep = 0;
}
if(lastStep==firstStep)
{
firstStep++;
if(firstStep==theFootSteps.GetLength())
{
firstStep = 0;
}
}
return &theFootSteps[ret];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRFootStep::Draw(MLRClipper *theClipper, const LinearMatrix4D& eye)
{
Check_Object(this);
Check_Object(theClipper);
Check_Object(&eye);
if(firstStep == lastStep || ShowSteps()==false)
{
return;
}
int eighthOfLen, sevenEightOfLen, len = theFootSteps.GetLength();
eighthOfLen = len>>3;
sevenEightOfLen = len - eighthOfLen;
Scalar oneOverEighthOfLen = 1.0f/(len>>3);
int flip = firstStep > lastStep ? 1 : 0;
DrawShapeInformation drawShapeInfo;
LinearMatrix4D matrix;
matrix = LinearMatrix4D::Identity;
RGBAColor fade;
fade = RGBAColor::White;
drawShapeInfo.activeLights = NULL;
drawShapeInfo.clippingFlags = 0x3f;
drawShapeInfo.nrOfActiveLights = 0;
drawShapeInfo.shapeToWorld = &matrix;
drawShapeInfo.worldToShape = &matrix;
int index = firstStep;
int numberOfActiveSteps = lastStep-firstStep+len*flip;
Scalar fadeFactor0, fadeFactor1;
UnitVector3D forward;
eye.GetLocalForwardInWorld(&forward);
Point3D eyeLocation;
eyeLocation = eye;
Vector3D stepToEye;
for(int i=0;i<numberOfActiveSteps;i++,index++)
{
if(index==len)
{
index = 0;
}
stepToEye.Subtract(theFootSteps[index].location, eyeLocation);
fadeFactor0 = stepToEye*forward;
if(fadeFactor0<0.0f || fadeFactor0>fadeOutEnd)
{
continue;
}
if(fadeFactor0 > fadeOutStart)
{
fadeFactor0 = 1.0f - oneOverFadeOut*(fadeFactor0-fadeOutStart);
}
else
{
fadeFactor0 = 1.0f;
}
int howFar = sevenEightOfLen-numberOfActiveSteps+i;
if(howFar > 0)
{
fadeFactor1 = 1.0f;
}
else
{
fadeFactor1 = 1.0f + oneOverEighthOfLen*howFar;
}
fade.alpha = fadeFactor0<fadeFactor1 ? fadeFactor0 : fadeFactor1;
drawShapeInfo.paintMeColor = &fade;
drawShapeInfo.shape = theFootSteps[index].shape;
theClipper->DrawShape(&drawShapeInfo);
}
}
@@ -0,0 +1,81 @@
#pragma once
#define MLR_MLRFOOTSTEP_HPP
#include <MLR\MLR.hpp>
extern DWORD gEnableFootSteps;
namespace MidLevelRenderer {
class MLRClipper;
struct FootStepInfo {
FootStepInfo() { Reset(); }
void Reset() { shape = NULL; location = Stuff::Point3D::Identity; }
MLRShape *shape;
Stuff::Point3D location;
};
class MLRFootStep:
public Stuff::RegisteredClass
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//
public:
static void
InitializeClass();
static void
TerminateClass();
static ClassData
*DefaultData;
static MLRFootStep
*Instance;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors/Destructors
//
protected:
MLRFootStep(Stuff::MemoryStream *stream);
public:
MLRFootStep(int);
~MLRFootStep();
static MLRFootStep*
Make(Stuff::MemoryStream *stream);
FootStepInfo*
AddAStep(MLRShape*, Stuff::Point3D& loc);
bool
ShowSteps()
{ Check_Object(this); return gEnableFootSteps==1; }
void
Draw(MLRClipper *theClipper, const Stuff::LinearMatrix4D& eye);
void
SetFadeOut(Stuff::Scalar start, Stuff::Scalar end)
{ Check_Object(this); Verify(end>start); fadeOutStart = start; fadeOutEnd = end; oneOverFadeOut = 1.0f/(end-start); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
//
public:
void
TestInstance() const
{}
protected:
Stuff::DynamicArrayOf<FootStepInfo>
theFootSteps;
int firstStep, lastStep;
Stuff::Scalar fadeOutStart, fadeOutEnd, oneOverFadeOut;
};
}
@@ -0,0 +1,3 @@
#include "MLRHeaders.hpp"
// This file does nothing but make the pch file

Some files were not shown because too many files have changed in this diff Show More