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

1892 lines
49 KiB
C++

#if !defined(MLR_MLRCLIPTRICK_HPP)
#include <MLR\MLRClipTrick.hpp>
#endif
extern DWORD gEnableTextureSort, gShowClippedPolys, gEnableSimpleLight;
extern WORD *indexOffset; // [MidLevelRenderer::Max_Number_Vertices_Per_Mesh]
extern DWORD Trivial_Accepts;
#define HUNT_CLIP_ERROR 0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CLASSNAME::TransformNoClip(Matrix4D *mat, GOSVertexPool *vt, FogData *fogData, DWORD paintMeColor, bool db)
{
Check_Object(this);
Check_Object(vt);
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
if(actualColors==NULL || actualColors->GetLength() == 0 || gEnableSimpleLight>0)
{
CLASSNAMENOCOLOR::TransformNoClip(mat, vt, fogData, paintMeColor, db);
return;
}
#else
if(colors.GetLength()==0)
{
CLASSNAMENOCOLOR::TransformNoClip(mat, vt, fogData, paintMeColor, db);
return;
}
#endif
#endif
MLR_RENDER("Transform::NoClip::MLRPrimitiveClipping");
Start_Timer(Transform_Time);
Verify(index.GetLength() > 0);
WORD stride;
bool textureAnimation = false;
Scalar deltaU=0.0f, deltaV=0.0f;
if(state.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
if(texture!=NULL)
{
MLRState::SetCurrentTextureSize(texture->GetImage()->GetWidth());
textureAnimation = texture->GetAnimateTexture();
if(textureAnimation)
{
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
deltaU = (*textureMatrix)(3, 0);
deltaV = (*textureMatrix)(3, 1);
}
}
}
int i, j, k, len = lengths.GetLength();
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
int tex2count = 0;
#endif
int numVertices = GetNumVertices();
if (numVertices>Limits::Max_Number_Vertices_Per_Mesh)
{
numVertices = Limits::Max_Number_Vertices_Per_Mesh;
}
gos_vertices = vt->GetActualVertexPool(db);
numGOSVertices = 0;
Verify(index.GetLength() > 0);
if(visibleIndexedVerticesKey == false)
{
FindVisibleVertices();
}
for(j=0,stride=0;j<numVertices;j++)
{
if((*visibleIndexedVertices)[j] == 0)
{
stride++;
}
else
{
#ifdef LAB_ONLY
TransformedVertices++;
#endif
if(db==false)
{
Verify (vt->GetLast() + numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
}
else
{
Verify (numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
}
indexOffset[j] = (WORD)(j - stride);
gos_vertices[numGOSVertices].GOSTransformNoClip(
coords[j],
*mat,
&texCoords[j][0]
#if FOG_HACK
, (state.GetFogMode() != 0)
#endif
);
// gos_vertices[numGOSVertices].u = texCoords[j][0];
// gos_vertices[numGOSVertices].v = texCoords[j][1];
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
#if COLOR_AS_DWORD
gos_vertices[numGOSVertices].argb = (*actualColors)[j];
#else
gos_vertices[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
#endif
#else
#if COLOR_AS_DWORD
gos_vertices[numGOSVertices].argb = colors[j];
#else
gos_vertices[numGOSVertices].argb = GOSCopyColor(&colors[j]);
#endif
#endif
#else
gos_vertices[numGOSVertices].argb = paintMeColor;
#endif
#if 1
if(fogData!=NULL)
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = fogData->FogVertex(&coords[j]);
}
#else
if(channelUse & 1<<FogChannel)
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
}
#endif
if(textureAnimation)
{
gos_vertices[numGOSVertices].u += deltaU;
gos_vertices[numGOSVertices].v += deltaV;
}
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*texCoords2)[tex2count++] = texCoords[numVertices + j];
#endif
numGOSVertices++;
}
}
#ifdef LAB_ONLY
Set_Statistic(NonClippedVertices, NonClippedVertices+numGOSVertices);
#endif
Check_Object(vt);
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
Verify (tex2count == numGOSVertices);
if(db==false)
{
Verify (vt->GetLast() + 2*numGOSVertices < vt->GetLength());
}
else
{
Verify (numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
}
if(state2.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
textureAnimation = texture->GetAnimateTexture();
if(textureAnimation)
{
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
deltaU = (*textureMatrix)(3, 0);
deltaV = (*textureMatrix)(3, 1);
}
}
memcpy(gos_vertices + numGOSVertices, gos_vertices, numGOSVertices * sizeof(GOSVertex));
if(textureAnimation)
{
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = (*texCoords2)[i][0] + deltaU;
gos_vertices[j].v = (*texCoords2)[i][1] + deltaV;
}
}
else
{
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = (*texCoords2)[i][0];
gos_vertices[j].v = (*texCoords2)[i][1];
}
}
if(db==false)
{
vt->Increase(2*numGOSVertices);
}
#else
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
if(db==false)
{
Verify (vt->GetLast() + 2*numGOSVertices < vt->GetLength());
}
else
{
Verify (numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
}
memcpy(gos_vertices + numGOSVertices, gos_vertices, numGOSVertices * sizeof(GOSVertex));
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = gos_vertices[i].u*xScale + xOffset;
gos_vertices[j].v = gos_vertices[i].v*yScale + yOffset;
}
if(db==false)
{
vt->Increase(2*numGOSVertices);
}
#else
if(db==false)
{
vt->Increase(numGOSVertices);
}
#endif
#endif
gos_indices = vt->GetActualIndexPool(db);
numGOSIndices = 0;
int ngi = 0;
for(i=0,j=0;i<len;j+=stride,i++)
{
stride = lengths[i];
Verify(stride >= 3);
if((*testList)[i] == 0)
{
continue;
}
for(k=1;k<stride-1;k++)
{
if(db==false)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
else
{
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
}
gos_indices[ngi++] = indexOffset[index[j]];
gos_indices[ngi++] = indexOffset[index[j+1+k]];
gos_indices[ngi++] = indexOffset[index[j+k]];
}
}
numGOSIndices = (WORD)ngi;
Check_Object(vt);
if(db==false)
{
vt->IncreaseIndex(numGOSIndices);
}
Stop_Timer(Transform_Time);
visible = numGOSVertices ? (BYTE)1 : (BYTE)0;
}
static MLRClippingState theAnd, theOr, theTest;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Now it gets serious
int
CLASSNAME::TransformAndClip(Matrix4D *mat, MLRClippingState clippingFlags, GOSVertexPool *vt, FogData *fogData, DWORD paintMeColor, bool db)
{
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
if(actualColors==NULL || actualColors->GetLength() == 0 || gEnableSimpleLight>0)
{
return CLASSNAMENOCOLOR::TransformAndClip(mat, clippingFlags, vt, fogData, paintMeColor, db);
}
#else
if(colors.GetLength()==0)
{
return CLASSNAMENOCOLOR::TransformAndClip(mat, clippingFlags, vt, fogData, paintMeColor, db);
}
#endif
#endif
WORD l;
int i, j, k, ret = 0;
int len;
{
MLR_RENDER("Transform::Clip::MLRPrimitiveClipping");
Start_Timer(Transform_Time);
Verify(clippingFlags.GetClippingState() != 0);
//
//--------------------------------------
// See if we don't have to draw anything
//--------------------------------------
//
if(lengths.GetLength() <= 0)
{
visible = 0;
Stop_Timer(Transform_Time);
return visible;
}
Verify(index.GetLength() > 0);
#ifdef I_SAY_YES_TO_TERRAIN2
#ifdef CALCULATEuvONtheFLY
Vector2DScalar terrainUV;
#endif // CALCULATEuvONtheFLY
#endif // I_SAY_YES_TO_TERRAIN2
len = coords.GetLength();
if(visibleIndexedVerticesKey == false)
{
FindVisibleVertices();
}
Stuff::Vector4D *v4d = transformedCoords->GetData();
const Stuff::Point3D *p3d = coords.GetData();
int *cs = (int *)clipPerVertex->GetData();
BYTE *viv = visibleIndexedVertices->GetData();
if(fogData!=NULL)
{
for(i=0;i<len;i++,p3d++,v4d++,cs++,viv++)
{
if(*viv == 0)
{
continue;
}
*viv = 0;
v4d->MultiplySetClip(*p3d, *mat, cs);
(*extraChannels[2*FogChannel])[i] = fogData->FogVertex(p3d);
#ifdef LAB_ONLY
Set_Statistic(TransformedVertices, TransformedVertices+1);
#endif // LAB_ONLY
//
//--------------------------------------------------------
// I claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
#ifdef LAB_ONLY
if( (*cs)==0)
{
#if defined(_ARMOR)
if(ArmorLevel > 3)
{
//
//--------------------------------------------------------
// I claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
Verify(v4d->x >= 0.0f && v4d->x <= v4d->w );
Verify(v4d->y >= 0.0f && v4d->y <= v4d->w );
Verify(v4d->z >= 0.0f && v4d->z <= v4d->w );
}
#endif // _ARMOR
Set_Statistic(NonClippedVertices, NonClippedVertices+1);
}
else
{
Set_Statistic(ClippedVertices, ClippedVertices+1);
}
#endif // LAB_ONLY
}
}
else
{
for(i=0;i<len;i++,p3d++,v4d++,cs++,viv++)
{
if(*viv == 0)
{
continue;
}
*viv = 0;
v4d->MultiplySetClip(*p3d, *mat, cs);
#ifdef LAB_ONLY
Set_Statistic(TransformedVertices, TransformedVertices+1);
#endif // LAB_ONLY
//
//--------------------------------------------------------
// I claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
#ifdef LAB_ONLY
if( (*cs)==0)
{
#if defined(_ARMOR)
if(ArmorLevel > 3)
{
//
//--------------------------------------------------------
// I claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
Verify(v4d->x >= 0.0f && v4d->x <= v4d->w );
Verify(v4d->y >= 0.0f && v4d->y <= v4d->w );
Verify(v4d->z >= 0.0f && v4d->z <= v4d->w );
}
#endif // _ARMOR
Set_Statistic(NonClippedVertices, NonClippedVertices+1);
}
else
{
Set_Statistic(ClippedVertices, ClippedVertices+1);
}
#endif // LAB_ONLY
}
}
Stop_Timer(Transform_Time);
}
MLR_RENDER("Clipping::MLRPrimitiveClipping");
Start_Timer(Clipping_Time);
int mask, end, k0, k1, ct=0;
Scalar a=0.0f;
WORD stride;
len = lengths.GetLength();
// Scalar bc0=0.0f, bc1=0.0f;
bool textureAnimation = false;
Scalar deltaU=0.0f, deltaV=0.0f;
if(state.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
if(texture!=NULL)
{
MLRState::SetCurrentTextureSize(texture->GetImage()->GetWidth());
textureAnimation = texture->GetAnimateTexture();
if(textureAnimation)
{
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
deltaU = (*textureMatrix)(3, 0);
deltaV = (*textureMatrix)(3, 1);
}
}
}
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
bool textureAnimation2 = false;
Scalar deltaU2=0.0f, deltaV2=0.0f;
if(state2.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
textureAnimation2 = texture->GetAnimateTexture();
if(textureAnimation2)
{
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
deltaU2 = (*textureMatrix)(3, 0);
deltaV2 = (*textureMatrix)(3, 1);
}
}
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
int tex2count = 0;
int numVertices = GetNumVertices();
if (numVertices>Limits::Max_Number_Vertices_Per_Mesh)
{
numVertices = Limits::Max_Number_Vertices_Per_Mesh;
}
#endif
int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
myNumberUsedClipVertex = 0;
myNumberUsedClipIndex = 0;
myNumberUsedClipLength = 0;
Verify(index.GetLength() > 0);
if(visibleIndexedVerticesKey == false)
{
FindVisibleVertices();
}
//
//------------------------
// Handle the indexed case
//------------------------
//
// initialize visibleIndexedVertices
memset(visibleIndexedVertices->GetData(), 0, visibleIndexedVertices->GetSize());
//
//-----------------------------------------------------------------
// Step through each polygon, making sure that we don't try to clip
// backfaced polygons
//-----------------------------------------------------------------
//
for(i=0,j=0;i<len;i++)
{
stride = lengths[i];
if((*testList)[i] == 0)
{
j += stride;
continue;
}
//
//---------------------------------------------------------------
// 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+stride;
for(k=j;k<end;k++)
{
theAnd &= (*clipPerVertex)[index[k]];
theOr |= (*clipPerVertex)[index[k]];
}
//
//-------------------------------------------------------------------
// 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)
{
(*testList)[i] = 0;
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButOutside, PolysClippedButOutside+1);
#endif
}
else if (theOr == 0)
{
ret++;
for(k=j;k<end;k++)
{
(*visibleIndexedVertices)[index[k]] = 1;
}
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButInside, PolysClippedButInside+1);
#endif
}
//
//-----------------------------------------------------------------
// It is not a trivial case, so we must now do real clipping on the
// polygon
//-----------------------------------------------------------------
//
else
{
WORD numberVerticesPerPolygon = 0;
//
//---------------------------------------------------------------
// Handle the case of a single clipping plane by stepping through
// the vertices and finding the edge it originates
//---------------------------------------------------------------
//
bool firstIsIn;
if (theOr.GetNumberOfSetBits() == 1)
{
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
#endif
for(k=j;k<end;k++)
{
k0 = index[k];
k1 = index[(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)[k0];
if(theTest == 0)
{
firstIsIn = true;
(*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
Verify((*actualColors).GetLength() > 0);
(*clipExtraColors)[clipped_index] = (*actualColors)[k0];
#else
Verify(colors.GetLength() > 0);
(*clipExtraColors)[clipped_index] = colors[k0];
#endif
#endif
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index] = texCoords[k0];
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index] = texCoords[k0+numVertices];
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n+=2,mask<<=1)
{
if(channelUse & mask)
{
(*extraChannels[n+1])[clipped_index] = (*extraChannels[n])[k0];
}
}
}
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
{
firstIsIn = false;
if((*clipPerVertex)[k1] != 0)
{
Verify((*clipPerVertex)[k1] == (*clipPerVertex)[k0]);
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))
{
// GetDoubleBC(l, bc0, bc1, transformedCoords[k0], transformedCoords[k1]);
//
//-------------------------------------------
// Find the clipping interval from bc0 to bc1
//-------------------------------------------
//
if(firstIsIn==true)
{
a = GetLerpFactor(l, (*transformedCoords)[k0], (*transformedCoords)[k1]);
}
else
{
a = GetLerpFactor(l, (*transformedCoords)[k1], (*transformedCoords)[k0]);
}
Verify(a >= 0.0f && a <= 1.0f);
ct = l;
break;
}
mask <<= 1;
}
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
if(firstIsIn==true)
{
(*clipExtraCoords)[clipped_index].Lerp(
(*transformedCoords)[k0],
(*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
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
Verify((*actualColors).GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#else
(*clipExtraColors)[clipped_index].Lerp(
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#endif
#else
Verify(colors.GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
colors[k0],
colors[k1],
a
);
#else
(*clipExtraColors)[clipped_index].Lerp(
colors[k0],
colors[k1],
a
);
#endif
#endif
#endif
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k0],
texCoords[k1],
a
);
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index].Lerp
(
texCoords[k0+numVertices],
texCoords[k1+numVertices],
a
);
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n+=2,mask<<=1)
{
if(channelUse & mask)
{
(*extraChannels[n+1])[clipped_index] = BYTE_Lerp (
(*extraChannels[n])[k0],
(*extraChannels[n])[k1],
a
);
}
}
}
}
else
{
(*clipExtraCoords)[clipped_index].Lerp(
(*transformedCoords)[k1],
(*transformedCoords)[k0],
a
);
DoClipTrick((*clipExtraCoords)[clipped_index], ct);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
Verify((*actualColors).GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
(*actualColors)[k1],
(*actualColors)[k0],
a
);
#else
(*clipExtraColors)[clipped_index].Lerp(
(*actualColors)[k1],
(*actualColors)[k0],
a
);
#endif
#else
Verify(colors.GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
colors[k1],
colors[k0],
a
);
#else
(*clipExtraColors)[clipped_index].Lerp(
colors[k1],
colors[k0],
a
);
#endif
#endif
#endif
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k1],
texCoords[k0],
a
);
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index].Lerp
(
texCoords[k1+numVertices],
texCoords[k0+numVertices],
a
);
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n+=2,mask<<=1)
{
if(channelUse & mask)
{
(*extraChannels[n+1])[clipped_index] = BYTE_Lerp (
(*extraChannels[n])[k1],
(*extraChannels[n])[k0],
a
);
}
}
}
}
//
//--------------------------------
// Bump the polygon's vertex count
//--------------------------------
//
numberVerticesPerPolygon++;
}
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
#ifdef _ARMOR
(*clipExtraLength)[myNumberUsedClipLength] &= ~0x8000;
#endif
}
//
//---------------------------------------------------------------
// 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
{
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButGOnePlane, PolysClippedButGOnePlane+1);
#endif
ClipData2 srcPolygon, dstPolygon;
int dstBuffer = 1;
Verify(texCoords.GetLength() > 0);
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
Verify((*actualColors).GetLength() > 0);
#else
Verify(colors.GetLength() > 0);
#endif
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
#endif
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
srcPolygon.extraChannel[n] = clipBuffer[dstBuffer].extraChannel[n].GetData();
}
}
}
//
//----------------------------------------------------------
// unravel and copy the original data into the source buffer
//----------------------------------------------------------
//
for(k=j,l=0;k<end;k++,l++)
{
int indexK = index[k];
srcPolygon.coords[l] = (*transformedCoords)[indexK];
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
#if COLOR_AS_DWORD>0
DWORD2Color(srcPolygon.colors[l], (*actualColors)[indexK]);
#else
srcPolygon.colors[l] = (*actualColors)[indexK];
#endif
#else
#if COLOR_AS_DWORD>0
DWORD2Color(srcPolygon.colors[l], colors[indexK]);
#else
srcPolygon.colors[l] = colors[indexK];
#endif
#endif
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
srcPolygon.texCoords[2*l] = texCoords[indexK];
srcPolygon.texCoords[2*l+1] = texCoords[indexK + numVertices];
#else
srcPolygon.texCoords[l] = texCoords[indexK];
#endif
srcPolygon.clipPerVertex[l] = (*clipPerVertex)[indexK];
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
srcPolygon.extraChannel[n][l] = (*extraChannels[2*n])[indexK];
}
}
}
}
srcPolygon.length = l;
//
//--------------------------------
// Point to the destination buffer
//--------------------------------
//
dstBuffer = 0;
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
#ifdef I_SAY_YES_TO_COLOR
dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
#endif
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
dstPolygon.extraChannel[n] = clipBuffer[dstBuffer].extraChannel[n].GetData();
}
}
}
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;
#if HUNT_CLIP_ERROR
for(k=0;k<srcPolygon.length;k++)
{
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
}
#endif
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "TheOriginalOR: " << hex << theOr.GetClippingState() << dec << '\n';
#endif
do
{
for(l=0; l<MLRClippingState::NextBit; l++)
{
if(theOr.IsClipped(mask))
{
//
//-----------------------------------
// Clip each vertex against the plane
//-----------------------------------
//
#if HUNT_CLIP_ERROR
DEBUG_STREAM << l << ": " << '\n';
#endif
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)
{
firstIsIn = true;
dstPolygon.coords[dstPolygon.length] =
srcPolygon.coords[k];
#if HUNT_CLIP_ERROR
DEBUG_STREAM << k << " goes " << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
#endif
dstPolygon.clipPerVertex[dstPolygon.length] =
srcPolygon.clipPerVertex[k];
#ifdef I_SAY_YES_TO_COLOR
dstPolygon.colors[dstPolygon.length] =
srcPolygon.colors[k];
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
dstPolygon.texCoords[2*dstPolygon.length] =
srcPolygon.texCoords[2*k];
dstPolygon.texCoords[2*dstPolygon.length+1] =
srcPolygon.texCoords[2*k+1];
#else
dstPolygon.texCoords[dstPolygon.length] =
srcPolygon.texCoords[k];
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
dstPolygon.extraChannel[n][dstPolygon.length] =
srcPolygon.extraChannel[n][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
{
firstIsIn = false;
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
//-------------------------------------------
//
if(firstIsIn == true)
{
a = GetLerpFactor (l, srcPolygon.coords[k], srcPolygon.coords[k1]);
Verify(a >= 0.0f && a <= 1.0f);
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
dstPolygon.coords[dstPolygon.length].Lerp(
srcPolygon.coords[k],
srcPolygon.coords[k1],
a
);
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "True " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< dstPolygon.coords[dstPolygon.length].x << " "
<< dstPolygon.coords[dstPolygon.length].y << " "
<< dstPolygon.coords[dstPolygon.length].z << " "
<< dstPolygon.coords[dstPolygon.length].w << '\n';
#endif
DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
dstPolygon.colors[dstPolygon.length].Lerp(
srcPolygon.colors[k],
srcPolygon.colors[k1],
a
);
#endif
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
dstPolygon.texCoords[2*dstPolygon.length].Lerp
(
srcPolygon.texCoords[2*k],
srcPolygon.texCoords[2*k1],
a
);
dstPolygon.texCoords[2*dstPolygon.length+1].Lerp
(
srcPolygon.texCoords[2*k+1],
srcPolygon.texCoords[2*k1+1],
a
);
#else
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k],
srcPolygon.texCoords[k1],
a
);
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
dstPolygon.extraChannel[n][dstPolygon.length] = BYTE_Lerp (
srcPolygon.extraChannel[n][k],
srcPolygon.extraChannel[n][k1],
a
);
}
}
}
}
else
{
a = GetLerpFactor (l, srcPolygon.coords[k1], srcPolygon.coords[k]);
Verify(a >= 0.0f && a <= 1.0f);
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
dstPolygon.coords[dstPolygon.length].Lerp(
srcPolygon.coords[k1],
srcPolygon.coords[k],
a
);
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "False " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< dstPolygon.coords[dstPolygon.length].x << " "
<< dstPolygon.coords[dstPolygon.length].y << " "
<< dstPolygon.coords[dstPolygon.length].z << " "
<< dstPolygon.coords[dstPolygon.length].w << '\n';
#endif
DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
dstPolygon.colors[dstPolygon.length].Lerp(
srcPolygon.colors[k1],
srcPolygon.colors[k],
a
);
#endif
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
dstPolygon.texCoords[2*dstPolygon.length].Lerp
(
srcPolygon.texCoords[2*k1],
srcPolygon.texCoords[2*k],
a
);
dstPolygon.texCoords[2*dstPolygon.length+1].Lerp
(
srcPolygon.texCoords[2*k1+1],
srcPolygon.texCoords[2*k+1],
a
);
#else
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k1],
srcPolygon.texCoords[k],
a
);
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
dstPolygon.extraChannel[n][dstPolygon.length] = BYTE_Lerp (
srcPolygon.extraChannel[n][k1],
srcPolygon.extraChannel[n][k],
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();
#ifdef I_SAY_YES_TO_COLOR
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
#endif
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
srcPolygon.extraChannel[n] = clipBuffer[dstBuffer].extraChannel[n].GetData();
}
}
}
srcPolygon.length = dstPolygon.length;
dstBuffer = !dstBuffer;
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
#ifdef I_SAY_YES_TO_COLOR
dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
#endif
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
dstPolygon.extraChannel[n] = clipBuffer[dstBuffer].extraChannel[n].GetData();
}
}
}
dstPolygon.length = 0;
}
mask = mask << 1;
}
theNewOr = 0;
for(k=0;k<srcPolygon.length;k++)
{
theNewOr |= srcPolygon.clipPerVertex[k];
}
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "TheOR: " << hex << theNewOr.GetClippingState() << dec << '\n';
#endif
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
//--------------------------------------------------
//
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "Final: " << srcPolygon.length << '\n';
#endif
for(k=0;k<srcPolygon.length;k++)
{
int clipped_index = myNumberUsedClipVertex + k;
#if HUNT_CLIP_ERROR
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
#endif
(*clipExtraCoords)[clipped_index] = srcPolygon.coords[k];
#ifdef I_SAY_YES_TO_COLOR
#if COLOR_AS_DWORD>0
(*clipExtraColors)[clipped_index] = GOSCopyColor(&srcPolygon.colors[k]);
#else
(*clipExtraColors)[clipped_index] = srcPolygon.colors[k];
#endif
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[2*k];
(*clipExtraTexCoords2)[clipped_index] = srcPolygon.texCoords[2*k+1];
#else
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[k];
#endif
if(channelUse > 0)
{
mask = 1;
for(int n=0;n<MaxNumberOfExtraChannel;n++,mask<<=1)
{
if(channelUse & mask)
{
(*extraChannels[2*n+1])[clipped_index] = srcPolygon.extraChannel[n][k];
}
}
}
}
numberVerticesPerPolygon = srcPolygon.length;
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "---" << '\n';
#endif
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
#ifdef _ARMOR
(*clipExtraLength)[myNumberUsedClipLength] |= 0x8000;
#endif
}
myNumberUsedClipVertex += numberVerticesPerPolygon;
myNumberUsedClipLength++;
ret++;
// clip
// dont draw the original
(*testList)[i] = 0;
}
j += stride;
}
Check_Object(vt);
gos_vertices = vt->GetActualVertexPool(db);
numGOSVertices = 0;
gos_indices = vt->GetActualIndexPool(db);
numGOSIndices = 0;
k = visibleIndexedVertices->GetLength();
for(j=0,stride=0;j<k;j++)
{
if((*visibleIndexedVertices)[j] == 0)
{
stride++;
}
else
{
indexOffset[j] = stride;
if(channelUse & 1<<FogChannel)
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
}
#if FOG_HACK
else
{
int fogEntry = state.GetFogMode();
if(fogEntry)
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) =
GOSVertex::fogTable[fogEntry-1][Truncate_Float_To_Word((*transformedCoords)[j].w)];
}
else
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = 0xff;
}
}
#endif
GOSCopyData(
&gos_vertices[numGOSVertices],
transformedCoords->GetData(),
#ifdef I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_LIGHTING
actualColors->GetData(),
#else
colors.GetData(),
#endif
#endif
texCoords.GetData(),
j
);
if(textureAnimation)
{
gos_vertices[numGOSVertices].u += deltaU;
gos_vertices[numGOSVertices].v += deltaV;
}
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
gos_vertices[numGOSVertices].argb = 0xff0000ff;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
}
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*texCoords2)[tex2count++] = texCoords[numVertices + j];
#endif
numGOSVertices++;
}
}
for(i=0,j=0;i<len;i++)
{
stride = lengths[i];
Verify(stride >= 3);
if((*testList)[i] == 0)
{
j += stride;
continue;
}
for(k=1;k<stride-1;k++)
{
if(db==false)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
else
{
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
}
gos_indices[numGOSIndices] = (WORD)(index[j] - indexOffset[index[j]]);
gos_indices[numGOSIndices+1] = (WORD)(index[j+k+1] - indexOffset[index[j+k+1]]);
gos_indices[numGOSIndices+2] = (WORD)(index[j+k] - indexOffset[index[j+k]]);
numGOSIndices += 3;
}
j += stride;
}
if(myNumberUsedClipLength > 0)
{
for(i=0,j=0;i<myNumberUsedClipLength;i++)
{
#ifdef _ARMOR
stride = static_cast<WORD>((*clipExtraLength)[i] & 0x7fff);
#else
stride = (*clipExtraLength)[i];
#endif
#if 0
for(k=j;k<stride+j;k++)
{
if(clipExtraCoords[k].x < 0.0f && clipExtraCoords[k].x > -SMALL)
{
clipExtraCoords[k].x = 0.0f;
}
if(clipExtraCoords[k].y < 0.0f && clipExtraCoords[k].y > -SMALL)
{
clipExtraCoords[k].y = 0.0f;
}
if(clipExtraCoords[k].z < 0.0f && clipExtraCoords[k].z > -SMALL)
{
clipExtraCoords[k].z = 0.0f;
}
if(clipExtraCoords[k].x > clipExtraCoords[k].w && clipExtraCoords[k].x < clipExtraCoords[k].w + SMALL)
{
clipExtraCoords[k].x = clipExtraCoords[k].w;
}
if(clipExtraCoords[k].y > clipExtraCoords[k].w && clipExtraCoords[k].y < clipExtraCoords[k].w + SMALL)
{
clipExtraCoords[k].y = clipExtraCoords[k].w;
}
if(clipExtraCoords[k].z >= clipExtraCoords[k].w && clipExtraCoords[k].z < clipExtraCoords[k].w + SMALL)
{
clipExtraCoords[k].z = clipExtraCoords[k].w - SMALL;
}
}
#endif
for(k=1;k<stride-1;k++)
{
if(db==false)
{
Verify((vt->GetLast() + 3 + numGOSVertices) < vt->GetLength());
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
else
{
Verify(3 + numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
}
if(channelUse & 1<<FogChannel)
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel+1])[j];
*((BYTE *)&gos_vertices[numGOSVertices+1].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k+1];
*((BYTE *)&gos_vertices[numGOSVertices+2].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k];
}
#if FOG_HACK
else
{
int fogEntry = state.GetFogMode();
if(fogEntry)
{
fogEntry--;
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) =
GOSVertex::fogTable[fogEntry][Truncate_Float_To_Word((*clipExtraCoords)[j].w)];
*((BYTE *)&gos_vertices[numGOSVertices+1].frgb + 3) =
GOSVertex::fogTable[fogEntry][Truncate_Float_To_Word((*clipExtraCoords)[j+k+1].w)];
*((BYTE *)&gos_vertices[numGOSVertices+2].frgb + 3) =
GOSVertex::fogTable[fogEntry][Truncate_Float_To_Word((*clipExtraCoords)[j+k].w)];
}
else
{
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = 0xff;
*((BYTE *)&gos_vertices[numGOSVertices+1].frgb + 3) = 0xff;
*((BYTE *)&gos_vertices[numGOSVertices+2].frgb + 3) = 0xff;
}
}
#endif
GOSCopyTriangleData(
&gos_vertices[numGOSVertices],
clipExtraCoords->GetData(),
#ifdef I_SAY_YES_TO_COLOR
clipExtraColors->GetData(),
#endif
clipExtraTexCoords->GetData(),
j, j+k+1, j+k
);
if(textureAnimation)
{
gos_vertices[numGOSVertices].u += deltaU;
gos_vertices[numGOSVertices].v += deltaV;
gos_vertices[numGOSVertices+1].u += deltaU;
gos_vertices[numGOSVertices+1].v += deltaV;
gos_vertices[numGOSVertices+2].u += deltaU;
gos_vertices[numGOSVertices+2].v += deltaV;
}
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
if((*clipExtraLength)[i] & 0x8000)
{
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;
}
else
{
gos_vertices[numGOSVertices].argb = 0xffff9999;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
gos_vertices[numGOSVertices+1].argb = 0xffff9999;
gos_vertices[numGOSVertices+1].u = 0.0f;
gos_vertices[numGOSVertices+1].v = 0.0f;
gos_vertices[numGOSVertices+2].argb = 0xffff9999;
gos_vertices[numGOSVertices+2].u = 0.0f;
gos_vertices[numGOSVertices+2].v = 0.0f;
}
}
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j];
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j+k+1];
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j+k];
#endif
if(db==false)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
else
{
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
}
Verify(numGOSIndices%3 == 0);
gos_indices[numGOSIndices] = numGOSVertices;
gos_indices[numGOSIndices+1] = (WORD)(numGOSVertices + 1);
gos_indices[numGOSIndices+2] = (WORD)(numGOSVertices + 2);
numGOSVertices += 3;
numGOSIndices += 3;
}
j += stride;
}
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "***" << endl << endl;
#endif
}
#ifdef LAB_ONLY
else
{
Trivial_Accepts++;
}
#endif
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
Verify (tex2count == numGOSVertices);
if(db==false)
{
Verify (vt->GetLast() + 2*numGOSVertices < vt->GetLength());
}
else
{
Verify (2*numGOSVertices < 2*Limits::Max_Number_Vertices_Per_Mesh);
}
memcpy(gos_vertices + numGOSVertices, gos_vertices, numGOSVertices * sizeof(GOSVertex));
if(textureAnimation2)
{
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = (*texCoords2)[i][0] + deltaU2;
gos_vertices[j].v = (*texCoords2)[i][1] + deltaV2;
}
}
else
{
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = (*texCoords2)[i][0];
gos_vertices[j].v = (*texCoords2)[i][1];
}
}
if(db==false)
{
vt->Increase(2*numGOSVertices);
}
#else
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
if(db==false)
{
Verify (vt->GetLast() + 2*numGOSVertices < vt->GetLength());
}
else
{
Verify (numGOSVertices < Limits::Max_Size_Of_Vertex_Buffer);
}
memcpy(gos_vertices + numGOSVertices, gos_vertices, numGOSVertices * sizeof(GOSVertex));
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = gos_vertices[i].u*xScale + xOffset;
gos_vertices[j].v = gos_vertices[i].v*yScale + yOffset;
}
if(db==false)
{
vt->Increase(2*numGOSVertices);
}
#else
if(db==false)
{
vt->Increase(numGOSVertices);
}
#endif
#endif
if(db==false)
{
vt->IncreaseIndex(numGOSIndices);
}
visible = numGOSVertices ? (BYTE)1 : (BYTE)0;
if(visible)
{
}
else
{
}
Stop_Timer(Clipping_Time);
return ret;
}