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.
2834 lines
80 KiB
C++
2834 lines
80 KiB
C++
#if !defined(MLR_MLRCLIPTRICK_HPP)
|
|
#include <MLR\MLRClipTrick.hpp>
|
|
#endif
|
|
|
|
extern DWORD gEnableTextureSort, gShowClippedPolys, gEnableDetailTexture, gShowBucketColors, gEnableSimpleLight;
|
|
extern WORD *indexOffset; // [MidLevelRenderer::Max_Number_Vertices_Per_Mesh]
|
|
extern DWORD Trivial_Accepts;
|
|
|
|
#define HUNT_CLIP_ERROR 0
|
|
//#define HUNT_CLIP_ERROR2 "micgaert"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CLASSNAME::TransformNoClip(Matrix4D *mat, GOSVertexPool *vt, FogData *fogData, DWORD paintMeColor, bool db)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(vt);
|
|
Verify(index.GetLength() > 0);
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#ifdef I_SAY_YES_TO_LIGHTING
|
|
if(actualColors==NULL || actualColors->GetLength() == 0 || gEnableSimpleLight>0
|
|
#ifdef LAB_ONLY
|
|
|| gShowBucketColors>0
|
|
#endif
|
|
)
|
|
{
|
|
CLASSNAMENOCOLOR::TransformNoClip(mat, vt, fogData, paintMeColor, db);
|
|
return;
|
|
}
|
|
#else
|
|
if(colors.GetLength()==0
|
|
#ifdef LAB_ONLY
|
|
|| gShowBucketColors>0
|
|
#endif
|
|
)
|
|
{
|
|
CLASSNAMENOCOLOR::TransformNoClip(mat, vt, fogData, paintMeColor, db);
|
|
return;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
MLR_RENDER("Transform::NoClip::MLRTriangleClipping");
|
|
Start_Timer(Transform_Time);
|
|
|
|
// WORD stride;
|
|
int stride;
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
bool textureAnimation = false;
|
|
Scalar deltaU=0.0f, deltaV=0.0f;
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
if(state.GetTextureHandle())
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
|
|
|
|
if(texture!=NULL)
|
|
{
|
|
MLRState::SetCurrentTextureSize(texture->GetImage()->GetWidth());
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
if(true==(textureAnimation = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU = (*textureMatrix)(3, 0);
|
|
deltaV = (*textureMatrix)(3, 1);
|
|
}
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
}
|
|
}
|
|
|
|
#if defined(I_SAY_YES_TO_DUAL_TEXTURES) || defined(I_SAY_YES_TO_DETAIL_TEXTURES)
|
|
gos_vertices2uv = vt->GetActualVertexPool2UV(db);
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
bool textureAnimation2 = false;
|
|
Scalar deltaU2=0.0f, deltaV2=0.0f;
|
|
|
|
if(state2.GetTextureHandle())
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[state2.GetTextureHandle()];
|
|
|
|
if(texture!=NULL && true==(textureAnimation2 = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU2 = (*textureMatrix)(3, 0);
|
|
deltaV2 = (*textureMatrix)(3, 1);
|
|
}
|
|
}
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES || I_SAY_YES_TO_DETAIL_TEXTURES
|
|
|
|
int i, j;
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
Scalar terrainUV[2];
|
|
#endif // CALCULATEuvONtheFLY
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
int numVertices = GetNumVertices();
|
|
if (numVertices>Limits::Max_Number_Vertices_Per_Mesh)
|
|
{
|
|
numVertices = Limits::Max_Number_Vertices_Per_Mesh;
|
|
}
|
|
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
bool textureAnimation2 = false;
|
|
Scalar deltaU2=0.0f, deltaV2=0.0f;
|
|
|
|
if(textureNorm)
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[textureNorm];
|
|
Verify(texture);
|
|
|
|
if(texture!=NULL && true==(textureAnimation2 = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU2 = (*textureMatrix)(3, 0);
|
|
deltaV2 = (*textureMatrix)(3, 1);
|
|
}
|
|
}
|
|
|
|
gos_vertices3uv = vt->GetActualVertexPool3UV(db);
|
|
#else
|
|
gos_vertices = vt->GetActualVertexPool(db);
|
|
#endif
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
int tex2count = 0;
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
Scalar detailTexCoords[2];
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
|
|
#if defined(I_SAY_YES_TO_DUAL_TEXTURES) || defined(I_SAY_YES_TO_DETAIL_TEXTURES)
|
|
gos_vertices2uv = vt->GetActualVertexPool2UV(db);
|
|
#endif
|
|
|
|
numGOSVertices = 0;
|
|
|
|
Verify(index.GetLength() > 0);
|
|
|
|
if(visibleIndexedVerticesKey == false)
|
|
{
|
|
FindVisibleVertices();
|
|
}
|
|
|
|
#ifdef _ARMOR
|
|
memset(indexOffset, 0xff, Limits::Max_Size_Of_Index_Buffer*sizeof(WORD));
|
|
#endif // _ARMOR
|
|
|
|
for(j=0,stride=0;j<numVertices;j++)
|
|
{
|
|
if((*visibleIndexedVertices)[j] == 0)
|
|
{
|
|
stride++;
|
|
}
|
|
else
|
|
{
|
|
#ifdef LAB_ONLY
|
|
Set_Statistic(TransformedVertices, TransformedVertices+1);
|
|
|
|
if(db==false)
|
|
{
|
|
Verify (vt->GetLast() + numGOSVertices < Limits::Max_Number_Vertices_Per_Frame);
|
|
}
|
|
else
|
|
{
|
|
Verify (numGOSVertices < Limits::Max_Size_Of_Index_Buffer);
|
|
}
|
|
#endif // LAB_ONLY
|
|
|
|
*(int *)(&indexOffset[j]) = (j - stride);
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
CalculateUV(j, terrainUV[0], terrainUV[1]);
|
|
#endif // CALCULATEuvONtheFLY
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == true && state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode)
|
|
{
|
|
gos_vertices2uv[numGOSVertices].GOSTransformNoClip(
|
|
coords[j],
|
|
*mat,
|
|
&texCoords[j][0],
|
|
&texCoords[numVertices + j][0]
|
|
#if FOG_HACK
|
|
,state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#if COLOR_AS_DWORD
|
|
gos_vertices2uv[numGOSVertices].argb = (*actualColors)[j];
|
|
#else // COLOR_AS_DWORD
|
|
gos_vertices2uv[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
|
|
#endif // COLOR_AS_DWORD
|
|
#else // I_SAY_YES_TO_COLOR
|
|
gos_vertices2uv[numGOSVertices].argb = paintMeColor;
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#if 1
|
|
if(fogData!=NULL)
|
|
{
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices].frgb + 3) = fogData->FogVertex(&coords[j]);
|
|
}
|
|
#else
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
gos_vertices[numGOSVertices].GOSTransformNoClip(
|
|
coords[j],
|
|
*mat,
|
|
&texCoords[j][0]
|
|
#if FOG_HACK
|
|
,state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
(*texCoords2)[tex2count++] = texCoords[numVertices + j];
|
|
|
|
#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
|
|
}
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if( MLRState::GetMultitextureLightMap() == true &&
|
|
state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode &&
|
|
gEnableDetailTexture==1
|
|
)
|
|
{
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
detailTexCoords[0] = terrainUV[0]*xScale;
|
|
detailTexCoords[1] = terrainUV[1]*yScale;
|
|
#else // CALCULATEuvONtheFLY
|
|
detailTexCoords[0] = texCoords[j][0]*xScale;
|
|
detailTexCoords[1] = texCoords[j][1]*yScale;
|
|
#endif // CALCULATEuvONtheFLY
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
detailTexCoords[0] = texCoords[j][0]*xScale + xOffset;
|
|
detailTexCoords[1] = texCoords[j][1]*yScale + yOffset;
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef UV_CHECK
|
|
Verify( MLRState::GetHasMaxUVs() ? (detailTexCoords[0]>=-MLRState::GetMaxUV() && detailTexCoords[0]<=MLRState::GetMaxUV()) : 1);
|
|
Verify( MLRState::GetHasMaxUVs() ? (detailTexCoords[1]>=-MLRState::GetMaxUV() && detailTexCoords[1]<=MLRState::GetMaxUV()) : 1);
|
|
#endif // UV_CHECK
|
|
#ifdef CALCULATEuvONtheFLY
|
|
gos_vertices2uv[numGOSVertices].GOSTransformNoClip(
|
|
coords[j],
|
|
*mat,
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
terrainUV,
|
|
#else
|
|
&texCoords[j][0],
|
|
#endif
|
|
&detailTexCoords[0]
|
|
#if FOG_HACK
|
|
,state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
gos_vertices2uv[numGOSVertices].GOSTransformNoClip(
|
|
coords[j],
|
|
*mat,
|
|
&texCoords[j][0],
|
|
&detailTexCoords[0]
|
|
#if FOG_HACK
|
|
,state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#if COLOR_AS_DWORD
|
|
gos_vertices2uv[numGOSVertices].argb = (*actualColors)[j];
|
|
#else // COLOR_AS_DWORD
|
|
gos_vertices2uv[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
|
|
#endif // COLOR_AS_DWORD
|
|
#else // I_SAY_YES_TO_COLOR
|
|
gos_vertices2uv[numGOSVertices].argb = paintMeColor;
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
}
|
|
else
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
gos_vertices[numGOSVertices].GOSTransformNoClip(
|
|
coords[j],
|
|
*mat,
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
terrainUV
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
&texCoords[j][0]
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices3uv[numGOSVertices].GOSTransformNoClip(
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices[numGOSVertices].GOSTransformNoClip(
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
coords[j],
|
|
*mat,
|
|
&texCoords[j][0]
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
, &(*texCoords2)[j][0]
|
|
, &(*texCoords3)[j][0]
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#if COLOR_AS_DWORD
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices3uv[numGOSVertices].argb = (*actualColors)[j];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices[numGOSVertices].argb = (*actualColors)[j];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#else // COLOR_AS_DWORD
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices3uv[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // COLOR_AS_DWORD
|
|
#else // I_SAY_YES_TO_COLOR
|
|
gos_vertices[numGOSVertices].argb = paintMeColor;
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
}
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
if(textureAnimation)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u1 += deltaU;
|
|
gos_vertices3uv[numGOSVertices].v1 += deltaV;
|
|
}
|
|
if(textureAnimation2)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u2 += deltaU2;
|
|
gos_vertices3uv[numGOSVertices].v2 += deltaV2;
|
|
}
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
if(textureAnimation)
|
|
{
|
|
gos_vertices[numGOSVertices].u += deltaU;
|
|
gos_vertices[numGOSVertices].v += deltaV;
|
|
}
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif
|
|
#if 1
|
|
if(fogData!=NULL)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices].frgb + 3) = fogData->FogVertex(&coords[j]);
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = fogData->FogVertex(&coords[j]);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
#else
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
#endif
|
|
#ifdef I_SAY_YES_TO_WATER
|
|
if(channelUse & 1<<SpecularRedChannel)
|
|
{
|
|
gos_vertices[numGOSVertices].frgb &= 0xff000000;
|
|
BYTE b = (*extraChannels[2*SpecularRedChannel])[j];
|
|
gos_vertices[numGOSVertices].frgb += ((b<<16) + (b<<8) + b);
|
|
}
|
|
|
|
#endif // I_SAY_YES_TO_WATER
|
|
numGOSVertices++;
|
|
}
|
|
}
|
|
|
|
#ifdef LAB_ONLY
|
|
Set_Statistic(NonClippedVertices, NonClippedVertices+numGOSVertices);
|
|
#endif // LAB_ONLY
|
|
|
|
Check_Object(vt);
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == false || state.GetMultiTextureMode()==MLRState::MultiTextureOffMode)
|
|
{
|
|
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)[state2.GetTextureHandle()];
|
|
|
|
if(texture!=NULL && true==(textureAnimation = texture->GetAnimateTexture()))
|
|
{
|
|
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
|
|
{
|
|
if(db==false)
|
|
{
|
|
vt->Increase2UV(numGOSVertices);
|
|
}
|
|
}
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if( gEnableDetailTexture==1)
|
|
{
|
|
if(MLRState::GetMultitextureLightMap() == false || state.GetMultiTextureMode()==MLRState::MultiTextureOffMode )
|
|
{
|
|
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));
|
|
|
|
stride = 0;
|
|
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
|
|
{
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
gos_vertices[j].u = gos_vertices[i].u*xScale;
|
|
gos_vertices[j].v = gos_vertices[i].v*yScale;
|
|
#else
|
|
gos_vertices[j].u = gos_vertices[i].u*xScale + xOffset + deltaU2;
|
|
gos_vertices[j].v = gos_vertices[i].v*yScale + yOffset + deltaV2;
|
|
#endif
|
|
#ifdef UV_CHECK
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices[j].u>=-MLRState::GetMaxUV() && gos_vertices[j].u<=MLRState::GetMaxUV()) : 1);
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices[j].v>=-MLRState::GetMaxUV() && gos_vertices[j].v<=MLRState::GetMaxUV()) : 1);
|
|
#endif // UV_CHECK
|
|
if(gos_vertices[j].rhw < fadeDetailEnd)
|
|
{
|
|
gos_vertices[j].argb &= 0x00ffffff;
|
|
}
|
|
else
|
|
{
|
|
stride++;
|
|
if(gos_vertices[j].rhw<fadeDetailStart)
|
|
{
|
|
gos_vertices[j].argb &= ((Stuff::Truncate_Float_To_Word((gos_vertices[j].rhw - fadeDetailEnd)*fadeMultiplicator)) << 24) | 0x00ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(stride==0)
|
|
{
|
|
detTextureVisible=false;
|
|
}
|
|
else
|
|
{
|
|
detTextureVisible=true;
|
|
}
|
|
|
|
if(db==false)
|
|
{
|
|
vt->Increase(2*numGOSVertices);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(db==false)
|
|
{
|
|
vt->Increase2UV(numGOSVertices);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(db==false)
|
|
{
|
|
vt->Increase(numGOSVertices);
|
|
}
|
|
}
|
|
#else // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if(db==false)
|
|
{
|
|
vt->Increase(numGOSVertices);
|
|
}
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
gos_indices = vt->GetActualIndexPool(db);
|
|
numGOSIndices = 0;
|
|
|
|
int ngi = 0;
|
|
for(i=0,j=0;i<numOfTriangles;j+=3,++i)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(db==false)
|
|
{
|
|
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
|
|
}
|
|
else
|
|
{
|
|
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
|
|
}
|
|
|
|
Verify(indexOffset[index[j]] < numGOSVertices);
|
|
gos_indices[ngi++] = indexOffset[index[j]];
|
|
Verify(indexOffset[index[j+2]] < numGOSVertices);
|
|
gos_indices[ngi++] = indexOffset[index[j+2]];
|
|
Verify(indexOffset[index[j+1]] < numGOSVertices);
|
|
gos_indices[ngi++] = indexOffset[index[j+1]];
|
|
}
|
|
numGOSIndices = (WORD)ngi;
|
|
|
|
Check_Object(vt);
|
|
if(db==false)
|
|
{
|
|
vt->IncreaseIndex(numGOSIndices);
|
|
}
|
|
|
|
visible = numGOSVertices ? (BYTE)1 : (BYTE)0;
|
|
|
|
Stop_Timer(Transform_Time);
|
|
}
|
|
|
|
static MLRClippingState theAnd, theOr, theTest;
|
|
|
|
// extern void _stdcall CheckVertices( gos_VERTEX* pVertexArray, DWORD NumberVertices, bool PointsLines );
|
|
// extern void _stdcall CheckVertices1( gos_VERTEX_2UV* pVertexArray, DWORD NumberVertices );
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Now it gets serious
|
|
int
|
|
CLASSNAME::TransformAndClip(Matrix4D *mat, MLRClippingState clippingFlags, GOSVertexPool *vt, FogData *fogData, DWORD paintMeColor, bool db)
|
|
{
|
|
Check_Object(this);
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#ifdef I_SAY_YES_TO_LIGHTING
|
|
if(actualColors==NULL || actualColors->GetLength() == 0 || gEnableSimpleLight>0
|
|
#ifdef LAB_ONLY
|
|
|| gShowBucketColors>0
|
|
#endif
|
|
)
|
|
{
|
|
return CLASSNAMENOCOLOR::TransformAndClip(mat, clippingFlags, vt, fogData, paintMeColor, db);
|
|
}
|
|
#else
|
|
if(colors.GetLength()==0
|
|
#ifdef LAB_ONLY
|
|
|| gShowBucketColors>0
|
|
#endif
|
|
)
|
|
{
|
|
return CLASSNAMENOCOLOR::TransformAndClip(mat, clippingFlags, vt, fogData, paintMeColor, db);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
int i, j, k, ret = 0;
|
|
WORD l;
|
|
int len;
|
|
int *cs;
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
Vector2DScalar terrainUV;
|
|
#endif // CALCULATEuvONtheFLY
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
{
|
|
MLR_RENDER("Transform::Clip::MLRTriangleClipping");
|
|
Start_Timer(Transform_Time);
|
|
|
|
Verify(clippingFlags.GetClippingState() != 0);
|
|
|
|
//
|
|
//--------------------------------------
|
|
// See if we don't have to draw anything
|
|
//--------------------------------------
|
|
//
|
|
if(numOfTriangles <= 0)
|
|
{
|
|
visible = 0;
|
|
|
|
Stop_Timer(Transform_Time);
|
|
|
|
return visible;
|
|
}
|
|
|
|
Verify(index.GetLength() > 0);
|
|
|
|
len = coords.GetLength();
|
|
|
|
if(visibleIndexedVerticesKey == false)
|
|
{
|
|
FindVisibleVertices();
|
|
}
|
|
|
|
Stuff::Vector4D *v4d = transformedCoords->GetData();
|
|
const Stuff::Point3D *p3d = coords.GetData();
|
|
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::MLRTriangleClipping");
|
|
Start_Timer(Clipping_Time);
|
|
|
|
int mask, k0, k1, ct=0;
|
|
Scalar a=0.0f;
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
bool textureAnimation = false;
|
|
Scalar deltaU=0.0f, deltaV=0.0f;
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
if(state.GetTextureHandle())
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
|
|
|
|
if(texture!=NULL)
|
|
{
|
|
MLRState::SetCurrentTextureSize(texture->GetImage()->GetWidth());
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
if(true==(textureAnimation = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU = (*textureMatrix)(3, 0);
|
|
deltaV = (*textureMatrix)(3, 1);
|
|
}
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
}
|
|
}
|
|
|
|
#if defined(I_SAY_YES_TO_DUAL_TEXTURES) || defined(I_SAY_YES_TO_DETAIL_TEXTURES)
|
|
gos_vertices2uv = vt->GetActualVertexPool2UV(db);
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
bool textureAnimation2 = false;
|
|
Scalar deltaU2=0.0f, deltaV2=0.0f;
|
|
|
|
if(state2.GetTextureHandle())
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[state2.GetTextureHandle()];
|
|
|
|
if(texture!=NULL && true==(textureAnimation2 = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU2 = (*textureMatrix)(3, 0);
|
|
deltaV2 = (*textureMatrix)(3, 1);
|
|
}
|
|
}
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES || I_SAY_YES_TO_DETAIL_TEXTURES
|
|
|
|
#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 // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
|
|
|
|
myNumberUsedClipVertex = 0;
|
|
myNumberUsedClipIndex = 0;
|
|
myNumberUsedClipLength = 0;
|
|
|
|
Verify(index.GetLength() > 0);
|
|
|
|
//
|
|
//------------------------
|
|
// Handle the indexed case
|
|
//------------------------
|
|
//
|
|
|
|
//
|
|
//-----------------------------------------------------------------
|
|
// Step through each polygon, making sure that we don't try to clip
|
|
// backfaced polygons
|
|
//-----------------------------------------------------------------
|
|
//
|
|
cs = (int *)clipPerVertex->GetData();
|
|
int index0, index1, index2;
|
|
|
|
#if defined (LAB_ONLY) && defined (HUNT_CLIP_ERROR2)
|
|
bool whats_up_with_that = false;
|
|
#endif
|
|
for(i=0,j=0;i<numOfTriangles;j+=3,++i)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
index0 = index[j];
|
|
index1 = index[j+1];
|
|
index2 = index[j+2];
|
|
//
|
|
//---------------------------------------------------------------
|
|
// 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 = cs[index0];
|
|
theOr = theAnd;
|
|
|
|
theAnd &= (cs[index1] & cs[index2]);
|
|
theOr |= (cs[index1] | cs[index2]);
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// 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 // LAB_ONLY
|
|
}
|
|
else if (theOr == 0)
|
|
{
|
|
ret++;
|
|
|
|
(*visibleIndexedVertices)[index0] = 1;
|
|
(*visibleIndexedVertices)[index1] = 1;
|
|
(*visibleIndexedVertices)[index2] = 1;
|
|
|
|
#ifdef LAB_ONLY
|
|
Set_Statistic(PolysClippedButInside, PolysClippedButInside+1);
|
|
#endif // LAB_ONLY
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------------------
|
|
// It is not a trivial case, so we must now do real clipping on the
|
|
// polygon
|
|
//-----------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
WORD numberVerticesPerPolygon = 0;
|
|
|
|
#if defined (LAB_ONLY) && defined (HUNT_CLIP_ERROR2)
|
|
if(whats_up_with_that == true)
|
|
{
|
|
for(k=j;k<j+3;k++)
|
|
{
|
|
SPEWALWAYS((HUNT_CLIP_ERROR2, "P: %f %f %f T: %f %f %f %f",
|
|
coords[index[k]].x,
|
|
coords[index[k]].y,
|
|
coords[index[k]].z,
|
|
(*transformedCoords)[index[k]].x,
|
|
(*transformedCoords)[index[k]].y,
|
|
(*transformedCoords)[index[k]].z,
|
|
(*transformedCoords)[index[k]].w
|
|
));
|
|
}
|
|
}
|
|
#endif
|
|
//
|
|
//---------------------------------------------------------------
|
|
// 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 // LAB_ONLY
|
|
|
|
for(k=j;k<j+3;k++)
|
|
{
|
|
k0 = index[k];
|
|
k1 = index[(k+1) < j+3 ? k+1 : j];
|
|
|
|
|
|
//
|
|
//----------------------------------------------------
|
|
// If this vertex is inside the viewing space, copy it
|
|
// directly to the clipping buffer
|
|
//----------------------------------------------------
|
|
//
|
|
int clipped_index =
|
|
myNumberUsedClipVertex + numberVerticesPerPolygon;
|
|
theTest = cs[k0];
|
|
|
|
if(theTest == 0)
|
|
{
|
|
firstIsIn = true;
|
|
(*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
Verify((*actualColors).GetLength() > 0);
|
|
(*clipExtraColors)[clipped_index] = (*actualColors)[k0];
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
CalculateUV(k0, (*clipExtraTexCoords)[clipped_index][0], (*clipExtraTexCoords)[clipped_index][1]);
|
|
#else // CALCULATEuvONtheFLY
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index] = texCoords[k0];
|
|
#endif // CALCULATEuvONtheFLY
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index] = texCoords[k0];
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
(*clipExtraTexCoords2)[clipped_index] = texCoords[k0+numVertices];
|
|
#endif
|
|
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*clipExtraTexCoords2)[clipped_index] = (*texCoords2)[k0];
|
|
(*clipExtraTexCoords3)[clipped_index] = (*texCoords3)[k0];
|
|
#endif
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<(MaxNumberOfExtraChannel<<1);n+=2,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
(*extraChannels[n+1])[clipped_index] = (*extraChannels[n])[k0];
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined (LAB_ONLY) && defined (HUNT_CLIP_ERROR2)
|
|
if(whats_up_with_that == true)
|
|
{
|
|
SPEWALWAYS((HUNT_CLIP_ERROR2, "CT: %f %f %f %f",
|
|
(*clipExtraCoords)[clipped_index].x,
|
|
(*clipExtraCoords)[clipped_index].y,
|
|
(*clipExtraCoords)[clipped_index].z,
|
|
(*clipExtraCoords)[clipped_index].w
|
|
));
|
|
}
|
|
#endif
|
|
|
|
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(cs[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(cs[k1] != 0)
|
|
{
|
|
Verify(cs[k1] == cs[k0]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------
|
|
// We now find the distance along the edge where the
|
|
// clipping plane will intersect
|
|
//--------------------------------------------------
|
|
//
|
|
mask = 1;
|
|
theTest |= cs[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
|
|
Verify((*actualColors).GetLength() > 0);
|
|
#if COLOR_AS_DWORD
|
|
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
|
|
(*actualColors)[k0],
|
|
(*actualColors)[k1],
|
|
a
|
|
);
|
|
#else // COLOR_AS_DWORD
|
|
(*clipExtraColors)[clipped_index].Lerp(
|
|
(*actualColors)[k0],
|
|
(*actualColors)[k1],
|
|
a
|
|
);
|
|
#endif // COLOR_AS_DWORD
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
//
|
|
//-----------------------------------------------------
|
|
// If there are texture uv's, we need to lerp them in a
|
|
// perspective correct manner
|
|
//-----------------------------------------------------
|
|
//
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
Vector2DScalar ctc[2];
|
|
|
|
CalculateUV(k0, ctc[0][0], ctc[0][1]);
|
|
CalculateUV(k1, ctc[1][0], ctc[1][1]);
|
|
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
ctc[0],
|
|
ctc[1],
|
|
a
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
texCoords[k0],
|
|
texCoords[k1],
|
|
a
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
texCoords[k0],
|
|
texCoords[k1],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
(*clipExtraTexCoords2)[clipped_index].Lerp
|
|
(
|
|
texCoords[k0+numVertices],
|
|
texCoords[k1+numVertices],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*clipExtraTexCoords2)[clipped_index].Lerp
|
|
(
|
|
(*texCoords2)[k0],
|
|
(*texCoords2)[k1],
|
|
a
|
|
);
|
|
|
|
(*clipExtraTexCoords3)[clipped_index].Lerp
|
|
(
|
|
(*texCoords3)[k0],
|
|
(*texCoords3)[k1],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<(MaxNumberOfExtraChannel<<1);n+=2,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
(*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
|
|
Verify((*actualColors).GetLength() > 0);
|
|
#if COLOR_AS_DWORD
|
|
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
|
|
(*actualColors)[k1],
|
|
(*actualColors)[k0],
|
|
a
|
|
);
|
|
#else // COLOR_AS_DWORD
|
|
(*clipExtraColors)[clipped_index].Lerp(
|
|
(*actualColors)[k1],
|
|
(*actualColors)[k0],
|
|
a
|
|
);
|
|
#endif // COLOR_AS_DWORD
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
//
|
|
//-----------------------------------------------------
|
|
// If there are texture uv's, we need to lerp them in a
|
|
// perspective correct manner
|
|
//-----------------------------------------------------
|
|
//
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
Vector2DScalar ctc[2];
|
|
|
|
CalculateUV(k1, ctc[0][0], ctc[0][1]);
|
|
CalculateUV(k0, ctc[1][0], ctc[1][1]);
|
|
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
ctc[0],
|
|
ctc[1],
|
|
a
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
texCoords[k1],
|
|
texCoords[k0],
|
|
a
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
Verify(texCoords.GetLength() > 0);
|
|
(*clipExtraTexCoords)[clipped_index].Lerp
|
|
(
|
|
texCoords[k1],
|
|
texCoords[k0],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
(*clipExtraTexCoords2)[clipped_index].Lerp
|
|
(
|
|
texCoords[k1+numVertices],
|
|
texCoords[k0+numVertices],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*clipExtraTexCoords2)[clipped_index].Lerp
|
|
(
|
|
(*texCoords2)[k1],
|
|
(*texCoords2)[k0],
|
|
a
|
|
);
|
|
(*clipExtraTexCoords3)[clipped_index].Lerp
|
|
(
|
|
(*texCoords3)[k1],
|
|
(*texCoords3)[k0],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<(MaxNumberOfExtraChannel<<1);n+=2,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
(*extraChannels[n+1])[clipped_index] = BYTE_Lerp (
|
|
(*extraChannels[n])[k1],
|
|
(*extraChannels[n])[k0],
|
|
a
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined (LAB_ONLY) && defined (HUNT_CLIP_ERROR2)
|
|
if(whats_up_with_that == true)
|
|
{
|
|
SPEWALWAYS((HUNT_CLIP_ERROR2, "CT: %f %f %f %f",
|
|
(*clipExtraCoords)[clipped_index].x,
|
|
(*clipExtraCoords)[clipped_index].y,
|
|
(*clipExtraCoords)[clipped_index].z,
|
|
(*clipExtraCoords)[clipped_index].w
|
|
));
|
|
}
|
|
#endif
|
|
|
|
|
|
//
|
|
//--------------------------------
|
|
// Bump the polygon's vertex count
|
|
//--------------------------------
|
|
//
|
|
numberVerticesPerPolygon++;
|
|
|
|
}
|
|
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
|
|
#ifdef _ARMOR
|
|
(*clipExtraLength)[myNumberUsedClipLength] &= ~0x8000;
|
|
#endif // _ARMOR
|
|
}
|
|
|
|
//
|
|
//---------------------------------------------------------------
|
|
// 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 // LAB_ONLY
|
|
ClipData2 srcPolygon, dstPolygon;
|
|
int dstBuffer = 1;
|
|
|
|
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
Verify((*actualColors).GetLength() > 0);
|
|
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
|
|
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
srcPolygon.extraChannel[n] = clipBuffer[dstBuffer].extraChannel[n].GetData();
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------
|
|
// unravel and copy the original data into the source buffer
|
|
//----------------------------------------------------------
|
|
//
|
|
BYTE maxF=0, minF=0xff;
|
|
for(k=j,l=0;k<j+3;k++,l++)
|
|
{
|
|
int indexK = index[k];
|
|
|
|
srcPolygon.coords[l] = (*transformedCoords)[indexK];
|
|
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
#if COLOR_AS_DWORD>0
|
|
DWORD2Color(srcPolygon.colors[l], (*actualColors)[indexK]);
|
|
#else
|
|
srcPolygon.colors[l] = (*actualColors)[indexK];
|
|
#endif
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
srcPolygon.texCoords[2*l] = texCoords[indexK];
|
|
srcPolygon.texCoords[2*l+1] = texCoords[indexK + numVertices];
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
CalculateUV(indexK, terrainUV[0], terrainUV[1]);
|
|
|
|
srcPolygon.texCoords[l] = terrainUV;
|
|
#else // CALCULATEuvONtheFLY
|
|
srcPolygon.texCoords[l] = texCoords[indexK];
|
|
#endif // CALCULATEuvONtheFLY
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
srcPolygon.texCoords[3*l] = texCoords[indexK];
|
|
srcPolygon.texCoords[3*l+1] = (*texCoords2)[indexK];
|
|
srcPolygon.texCoords[3*l+2] = (*texCoords3)[indexK];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
srcPolygon.texCoords[l] = texCoords[indexK];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
srcPolygon.clipPerVertex[l] = (*clipPerVertex)[indexK];
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
srcPolygon.extraChannel[n][l] = (*extraChannels[2*n])[indexK];
|
|
if(srcPolygon.extraChannel[n][l]<minF)
|
|
{
|
|
minF = srcPolygon.extraChannel[n][l];
|
|
}
|
|
if(srcPolygon.extraChannel[n][l]>maxF)
|
|
{
|
|
maxF = srcPolygon.extraChannel[n][l];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
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 // I_SAY_YES_TO_COLOR
|
|
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
|
|
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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';
|
|
}
|
|
|
|
DEBUG_STREAM << "TheOriginalOR: " << hex << theOr.GetClippingState() << dec << '\n';
|
|
#endif // HUNT_CLIP_ERROR
|
|
|
|
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 // HUNT_CLIP_ERROR
|
|
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 // HUNT_CLIP_ERROR
|
|
|
|
|
|
dstPolygon.clipPerVertex[dstPolygon.length] =
|
|
srcPolygon.clipPerVertex[k];
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
dstPolygon.colors[dstPolygon.length] =
|
|
srcPolygon.colors[k];
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#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 // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[3*dstPolygon.length] =
|
|
srcPolygon.texCoords[3*k];
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+1] =
|
|
srcPolygon.texCoords[3*k+1];
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+2] =
|
|
srcPolygon.texCoords[3*k+2];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[dstPolygon.length] =
|
|
srcPolygon.texCoords[k];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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 // HUNT_CLIP_ERROR
|
|
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 // I_SAY_YES_TO_COLOR
|
|
//
|
|
//-----------------------------------------------------
|
|
// 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 // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[3*dstPolygon.length].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k],
|
|
srcPolygon.texCoords[3*k1],
|
|
a
|
|
);
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+1].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k+1],
|
|
srcPolygon.texCoords[3*k1+1],
|
|
a
|
|
);
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+2].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k+2],
|
|
srcPolygon.texCoords[3*k1+2],
|
|
a
|
|
);
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[dstPolygon.length].Lerp
|
|
(
|
|
srcPolygon.texCoords[k],
|
|
srcPolygon.texCoords[k1],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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 // HUNT_CLIP_ERROR
|
|
|
|
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 // I_SAY_YES_TO_COLOR
|
|
//
|
|
//-----------------------------------------------------
|
|
// 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 // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[3*dstPolygon.length].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k1],
|
|
srcPolygon.texCoords[3*k],
|
|
a
|
|
);
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+1].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k1+1],
|
|
srcPolygon.texCoords[3*k+1],
|
|
a
|
|
);
|
|
|
|
dstPolygon.texCoords[3*dstPolygon.length+2].Lerp
|
|
(
|
|
srcPolygon.texCoords[3*k1+2],
|
|
srcPolygon.texCoords[3*k+2],
|
|
a
|
|
);
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
dstPolygon.texCoords[dstPolygon.length].Lerp
|
|
(
|
|
srcPolygon.texCoords[k1],
|
|
srcPolygon.texCoords[k],
|
|
a
|
|
);
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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 // I_SAY_YES_TO_COLOR
|
|
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
|
|
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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 // I_SAY_YES_TO_COLOR
|
|
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
|
|
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
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 // HUNT_CLIP_ERROR
|
|
|
|
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 // HUNT_CLIP_ERROR
|
|
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 // HUNT_CLIP_ERROR
|
|
|
|
(*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 // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[2*k];
|
|
(*clipExtraTexCoords2)[clipped_index] = srcPolygon.texCoords[2*k+1];
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[3*k];
|
|
(*clipExtraTexCoords2)[clipped_index] = srcPolygon.texCoords[3*k+1];
|
|
(*clipExtraTexCoords3)[clipped_index] = srcPolygon.texCoords[3*k+2];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[k];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
if(channelUse > 0)
|
|
{
|
|
int maskC = 1;
|
|
for(int n=0;n<MaxNumberOfExtraChannel;n++,maskC<<=1)
|
|
{
|
|
if(channelUse & maskC)
|
|
{
|
|
(*extraChannels[2*n+1])[clipped_index] = srcPolygon.extraChannel[n][k];
|
|
|
|
Verify((*extraChannels[2*n+1])[clipped_index]<=maxF);
|
|
Verify((*extraChannels[2*n+1])[clipped_index]>=minF);
|
|
}
|
|
}
|
|
}
|
|
#if defined (LAB_ONLY) && defined (HUNT_CLIP_ERROR2)
|
|
if(whats_up_with_that == true)
|
|
{
|
|
SPEWALWAYS((HUNT_CLIP_ERROR2, "CT: %f %f %f %f",
|
|
(*clipExtraCoords)[clipped_index].x,
|
|
(*clipExtraCoords)[clipped_index].y,
|
|
(*clipExtraCoords)[clipped_index].z,
|
|
(*clipExtraCoords)[clipped_index].w
|
|
));
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
numberVerticesPerPolygon = srcPolygon.length;
|
|
#if HUNT_CLIP_ERROR
|
|
DEBUG_STREAM << "---" << '\n';
|
|
#endif // HUNT_CLIP_ERROR
|
|
|
|
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
|
|
#ifdef _ARMOR
|
|
(*clipExtraLength)[myNumberUsedClipLength] |= 0x8000;
|
|
#endif // _ARMOR
|
|
}
|
|
myNumberUsedClipVertex += numberVerticesPerPolygon;
|
|
myNumberUsedClipLength++;
|
|
ret++;
|
|
|
|
// clip
|
|
|
|
// dont draw the original
|
|
(*testList)[i] = 0;
|
|
}
|
|
}
|
|
|
|
Check_Object(vt);
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
bool textureAnimation2 = false;
|
|
Scalar deltaU2=0.0f, deltaV2=0.0f;
|
|
|
|
if(textureNorm)
|
|
{
|
|
MLRTexture *texture = (*MLRTexturePool::Instance)[textureNorm];
|
|
|
|
if(texture!=NULL && true==(textureAnimation2 = texture->GetAnimateTexture()))
|
|
{
|
|
Stuff::AffineMatrix4D *textureMatrix = texture->GetTextureMatrix();
|
|
deltaU2 = (*textureMatrix)(3, 0);
|
|
deltaV2 = (*textureMatrix)(3, 1);
|
|
}
|
|
}
|
|
|
|
gos_vertices3uv = vt->GetActualVertexPool3UV(db);
|
|
#else
|
|
gos_vertices = vt->GetActualVertexPool(db);
|
|
#endif
|
|
numGOSVertices = 0;
|
|
gos_indices = vt->GetActualIndexPool(db);
|
|
numGOSIndices = 0;
|
|
|
|
k = coords.GetLength();
|
|
|
|
WORD strideIndex;
|
|
for(j=0,strideIndex=0;j<k;j++)
|
|
{
|
|
if((*visibleIndexedVertices)[j] == 0)
|
|
{
|
|
strideIndex++;
|
|
}
|
|
else
|
|
{
|
|
indexOffset[j] = static_cast<WORD>(j-strideIndex);
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
CalculateUV(j, terrainUV[0], terrainUV[1]);
|
|
#endif // CALCULATEuvONtheFLY
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == true && state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode)
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
&terrainUV-j,
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData(),
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData() + numVertices,
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
texCoords.GetData(),
|
|
texCoords.GetData() + numVertices,
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
}
|
|
|
|
// CheckVertices1( gos_vertices2uv+numGOSVertices, 1 );
|
|
}
|
|
else
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
&terrainUV-j,
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData(),
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
texCoords.GetData(),
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
(*texCoords2)[tex2count++] = texCoords[numVertices + j];
|
|
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
}
|
|
}
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef CALCULATEuvONtheFLY
|
|
CalculateUV(j, terrainUV[0], terrainUV[1]);
|
|
#endif // CALCULATEuvONtheFLY
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
if( MLRState::GetMultitextureLightMap() == true &&
|
|
state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode &&
|
|
gEnableDetailTexture==1
|
|
)
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
&terrainUV-j,
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData(),
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
&terrainUV-j,
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData(),
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
texCoords.GetData(),
|
|
texCoords.GetData(),
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
}
|
|
}
|
|
else
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
&gos_vertices[numGOSVertices],
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
&terrainUV-j,
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
texCoords.GetData(),
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#else // CALCULATEuvONtheFLY
|
|
GOSCopyData(
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
&gos_vertices3uv[numGOSVertices],
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
&gos_vertices[numGOSVertices],
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
transformedCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
actualColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
texCoords.GetData(),
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
(*texCoords2).GetData(),
|
|
(*texCoords3).GetData(),
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
j
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
#endif // CALCULATEuvONtheFLY
|
|
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel])[j];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
}
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
if(textureAnimation)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u1 += deltaU;
|
|
gos_vertices3uv[numGOSVertices].v1 += deltaV;
|
|
}
|
|
if(textureAnimation2)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u2 += deltaU2;
|
|
gos_vertices3uv[numGOSVertices].v2 += deltaV2;
|
|
}
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
if(textureAnimation)
|
|
{
|
|
gos_vertices[numGOSVertices].u += deltaU;
|
|
gos_vertices[numGOSVertices].v += deltaV;
|
|
}
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef LAB_ONLY
|
|
if(gShowClippedPolys)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices3uv[numGOSVertices].argb = 0xff0000ff;
|
|
gos_vertices3uv[numGOSVertices].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices].v1 = 0.0f;
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
gos_vertices[numGOSVertices].argb = 0xff0000ff;
|
|
gos_vertices[numGOSVertices].u = 0.0f;
|
|
gos_vertices[numGOSVertices].v = 0.0f;
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
#endif // LAB_ONLY
|
|
|
|
#ifdef I_SAY_YES_TO_WATER
|
|
if(channelUse & 1<<SpecularRedChannel)
|
|
{
|
|
gos_vertices[numGOSVertices].frgb &= 0xff000000;
|
|
BYTE b = (*extraChannels[2*SpecularRedChannel])[j];
|
|
gos_vertices[numGOSVertices].frgb += ((b<<16) + (b<<8) + b);
|
|
}
|
|
|
|
#endif // I_SAY_YES_TO_WATER
|
|
|
|
numGOSVertices++;
|
|
}
|
|
}
|
|
|
|
for(i=0,j=0;i<numOfTriangles;j+=3,++i)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(db==false)
|
|
{
|
|
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
|
|
}
|
|
else
|
|
{
|
|
Verify(3 + numGOSIndices < Limits::Max_Size_Of_Index_Buffer);
|
|
}
|
|
|
|
Verify(indexOffset[index[j]] < numGOSVertices);
|
|
gos_indices[numGOSIndices] = indexOffset[index[j]];
|
|
|
|
Verify(indexOffset[index[j+2]] < numGOSVertices);
|
|
gos_indices[numGOSIndices+1] = indexOffset[index[j+2]];
|
|
|
|
Verify(indexOffset[index[j+1]] < numGOSVertices);
|
|
gos_indices[numGOSIndices+2] = indexOffset[index[j+1]];
|
|
|
|
numGOSIndices += 3;
|
|
}
|
|
|
|
WORD stride;
|
|
if(myNumberUsedClipLength > 0)
|
|
{
|
|
for(i=0,j=0;i<myNumberUsedClipLength;i++)
|
|
{
|
|
#ifdef _ARMOR
|
|
stride = static_cast<WORD>((*clipExtraLength)[i] & 0x7fff);
|
|
#else // _ARMOR
|
|
stride = (*clipExtraLength)[i];
|
|
#endif // _ARMOR
|
|
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);
|
|
}
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == true && state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode)
|
|
{
|
|
GOSCopyTriangleData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
clipExtraCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
clipExtraColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
clipExtraTexCoords->GetData(),
|
|
clipExtraTexCoords2->GetData(),
|
|
j, j+k+1, j+k
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
// CheckVertices1( gos_vertices2uv+numGOSVertices, 3 );
|
|
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];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GOSCopyTriangleData(
|
|
&gos_vertices[numGOSVertices],
|
|
clipExtraCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
clipExtraColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
clipExtraTexCoords->GetData(),
|
|
j, j+k+1, j+k
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
|
|
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j];
|
|
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j+k+1];
|
|
(*texCoords2)[tex2count++] = (*clipExtraTexCoords2)[j+k];
|
|
|
|
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];
|
|
}
|
|
|
|
}
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if( MLRState::GetMultitextureLightMap() == true &&
|
|
state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode &&
|
|
gEnableDetailTexture==1
|
|
)
|
|
{
|
|
GOSCopyTriangleData(
|
|
&gos_vertices2uv[numGOSVertices],
|
|
clipExtraCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
clipExtraColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
clipExtraTexCoords->GetData(),
|
|
clipExtraTexCoords->GetData(),
|
|
j, j+k+1, j+k
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel+1])[j];
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices+1].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k+1];
|
|
*((BYTE *)&gos_vertices2uv[numGOSVertices+2].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k];
|
|
}
|
|
}
|
|
else
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
{
|
|
GOSCopyTriangleData(
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
&gos_vertices3uv[numGOSVertices],
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
&gos_vertices[numGOSVertices],
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
clipExtraCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_COLOR
|
|
clipExtraColors->GetData(),
|
|
#endif // I_SAY_YES_TO_COLOR
|
|
clipExtraTexCoords->GetData(),
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
clipExtraTexCoords2->GetData(),
|
|
clipExtraTexCoords3->GetData(),
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
j, j+k+1, j+k
|
|
#if FOG_HACK
|
|
, state.GetFogMode()
|
|
#endif // FOG_HACK
|
|
);
|
|
if(channelUse & 1<<FogChannel)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices].frgb + 3) = (*extraChannels[2*FogChannel+1])[j];
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices+1].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k+1];
|
|
*((BYTE *)&gos_vertices3uv[numGOSVertices+2].frgb + 3) = (*extraChannels[2*FogChannel+1])[j+k];
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
*((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];
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
}
|
|
#endif // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
#ifndef I_SAY_YES_TO_TERRAIN2
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
if(textureAnimation)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u1 += deltaU;
|
|
gos_vertices3uv[numGOSVertices].v1 += deltaV;
|
|
|
|
gos_vertices3uv[numGOSVertices+1].u1 += deltaU;
|
|
gos_vertices3uv[numGOSVertices+1].v1 += deltaV;
|
|
|
|
gos_vertices3uv[numGOSVertices+2].u1 += deltaU;
|
|
gos_vertices3uv[numGOSVertices+2].v1 += deltaV;
|
|
}
|
|
|
|
if(textureAnimation2)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].u2 += deltaU2;
|
|
gos_vertices3uv[numGOSVertices].v2 += deltaV2;
|
|
|
|
gos_vertices3uv[numGOSVertices+1].u2 += deltaU2;
|
|
gos_vertices3uv[numGOSVertices+1].v2 += deltaV2;
|
|
|
|
gos_vertices3uv[numGOSVertices+2].u2 += deltaU2;
|
|
gos_vertices3uv[numGOSVertices+2].v2 += deltaV2;
|
|
}
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
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;
|
|
}
|
|
#endif // I_SAY_YES_TO_BUMP_TEXTURE
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
|
|
#ifdef LAB_ONLY
|
|
if(gShowClippedPolys)
|
|
{
|
|
#ifdef I_SAY_YES_TO_BUMP_TEXTURE
|
|
if((*clipExtraLength)[i] & 0x8000)
|
|
{
|
|
gos_vertices3uv[numGOSVertices].argb = 0xffff0000;
|
|
gos_vertices3uv[numGOSVertices].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices].v1 = 0.0f;
|
|
|
|
gos_vertices3uv[numGOSVertices+1].argb = 0xffff0000;
|
|
gos_vertices3uv[numGOSVertices+1].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices+1].v1 = 0.0f;
|
|
|
|
gos_vertices3uv[numGOSVertices+2].argb = 0xffff0000;
|
|
gos_vertices3uv[numGOSVertices+2].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices+2].v1 = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
gos_vertices3uv[numGOSVertices].argb = 0xffff9999;
|
|
gos_vertices3uv[numGOSVertices].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices].v1 = 0.0f;
|
|
|
|
gos_vertices3uv[numGOSVertices+1].argb = 0xffff9999;
|
|
gos_vertices3uv[numGOSVertices+1].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices+1].v1 = 0.0f;
|
|
|
|
gos_vertices3uv[numGOSVertices+2].argb = 0xffff9999;
|
|
gos_vertices3uv[numGOSVertices+2].u1 = 0.0f;
|
|
gos_vertices3uv[numGOSVertices+2].v1 = 0.0f;
|
|
}
|
|
#else // I_SAY_YES_TO_BUMP_TEXTURE
|
|
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 // I_SAY_YES_TO_BUMP_TEXTURE
|
|
}
|
|
#endif // LAB_ONLY
|
|
|
|
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);
|
|
|
|
#ifdef I_SAY_YES_TO_WATER
|
|
if(channelUse & 1<<SpecularRedChannel)
|
|
{
|
|
gos_vertices[numGOSVertices].frgb &= 0xff000000;
|
|
BYTE b = (*extraChannels[2*SpecularRedChannel+1])[j];
|
|
gos_vertices[numGOSVertices].frgb += ((b<<16) + (b<<8) + b);
|
|
|
|
gos_vertices[numGOSVertices+1].frgb &= 0xff000000;
|
|
b = (*extraChannels[2*SpecularRedChannel+1])[j+k+1];
|
|
gos_vertices[numGOSVertices+1].frgb += ((b<<16) + (b<<8) + b);
|
|
|
|
gos_vertices[numGOSVertices+2].frgb &= 0xff000000;
|
|
b = (*extraChannels[2*SpecularRedChannel+1])[j+k];
|
|
gos_vertices[numGOSVertices+2].frgb += ((b<<16) + (b<<8) + b);
|
|
}
|
|
|
|
#endif // I_SAY_YES_TO_WATER
|
|
|
|
numGOSVertices += 3;
|
|
numGOSIndices += 3;
|
|
}
|
|
|
|
j += stride;
|
|
}
|
|
#if HUNT_CLIP_ERROR
|
|
DEBUG_STREAM << "***" << endl << endl;
|
|
#endif // HUNT_CLIP_ERROR
|
|
|
|
}
|
|
#ifdef LAB_ONLY
|
|
else
|
|
{
|
|
Trivial_Accepts++;
|
|
}
|
|
#endif
|
|
|
|
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == false || state.GetMultiTextureMode()==MLRState::MultiTextureOffMode)
|
|
{
|
|
Verify (tex2count == numGOSVertices);
|
|
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));
|
|
|
|
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
|
|
{
|
|
if(db==false)
|
|
{
|
|
vt->Increase2UV(numGOSVertices);
|
|
}
|
|
}
|
|
#else // I_SAY_YES_TO_DUAL_TEXTURES
|
|
#ifdef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if(gEnableDetailTexture==1)
|
|
{
|
|
if( MLRState::GetMultitextureLightMap() == true &&
|
|
state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode
|
|
)
|
|
{
|
|
for(i=0;i<numGOSVertices;i++)
|
|
{
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
gos_vertices2uv[i].u2 = gos_vertices2uv[i].u1*xScale;
|
|
gos_vertices2uv[i].v2 = gos_vertices2uv[i].v1*yScale;
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
gos_vertices2uv[i].u2 = gos_vertices2uv[i].u1*xScale + xOffset + deltaU2;
|
|
gos_vertices2uv[i].v2 = gos_vertices2uv[i].v1*yScale + yOffset + deltaV2;
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef UV_CHECK
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices2uv[i].u2>=-MLRState::GetMaxUV() && gos_vertices2uv[i].u2<=MLRState::GetMaxUV()) : 1);
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices2uv[i].v2>=-MLRState::GetMaxUV() && gos_vertices2uv[i].v2<=MLRState::GetMaxUV()) : 1);
|
|
#endif // UV_CHECK
|
|
if(gos_vertices2uv[i].rhw < fadeDetailEnd)
|
|
{
|
|
gos_vertices2uv[i].argb &= 0x00ffffff;
|
|
}
|
|
else
|
|
{
|
|
if(gos_vertices2uv[i].rhw<fadeDetailStart)
|
|
{
|
|
gos_vertices2uv[i].argb &= ((Stuff::Truncate_Float_To_Word((gos_vertices2uv[i].rhw - fadeDetailEnd)*fadeMultiplicator)) << 24) | 0x00ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(db==false)
|
|
{
|
|
vt->Increase2UV(numGOSVertices);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
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));
|
|
|
|
stride = 0;
|
|
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
|
|
{
|
|
#ifdef I_SAY_YES_TO_TERRAIN2
|
|
gos_vertices[j].u = gos_vertices[i].u*xScale;
|
|
gos_vertices[j].v = gos_vertices[i].v*yScale;
|
|
#else // I_SAY_YES_TO_TERRAIN2
|
|
gos_vertices[j].u = gos_vertices[i].u*xScale + xOffset + deltaU2;
|
|
gos_vertices[j].v = gos_vertices[i].v*yScale + yOffset + deltaV2;
|
|
#endif // I_SAY_YES_TO_TERRAIN2
|
|
#ifdef UV_CHECK
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices[j].u>=-MLRState::GetMaxUV() && gos_vertices[j].u<=MLRState::GetMaxUV()) : 1);
|
|
Verify( MLRState::GetHasMaxUVs() ? (gos_vertices[j].v>=-MLRState::GetMaxUV() && gos_vertices[j].v<=MLRState::GetMaxUV()) : 1);
|
|
#endif // UV_CHECK
|
|
|
|
if(gos_vertices[j].rhw < fadeDetailEnd)
|
|
{
|
|
gos_vertices[j].argb &= 0x00ffffff;
|
|
}
|
|
else
|
|
{
|
|
stride++;
|
|
if(gos_vertices[j].rhw<fadeDetailStart)
|
|
{
|
|
gos_vertices[j].argb &= ((Stuff::Truncate_Float_To_Word((gos_vertices[j].rhw - fadeDetailEnd)*fadeMultiplicator)) << 24) | 0x00ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(stride==0)
|
|
{
|
|
detTextureVisible=false;
|
|
}
|
|
else
|
|
{
|
|
detTextureVisible=true;
|
|
}
|
|
|
|
if(db==false)
|
|
{
|
|
vt->Increase(2*numGOSVertices);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(db==false)
|
|
{
|
|
vt->Increase(numGOSVertices);
|
|
}
|
|
}
|
|
#else // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
if(db==false)
|
|
{
|
|
vt->Increase(numGOSVertices);
|
|
}
|
|
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
|
|
#endif // // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
if(db==false)
|
|
{
|
|
vt->IncreaseIndex(numGOSIndices);
|
|
}
|
|
|
|
visible = numGOSVertices ? (BYTE)1 : (BYTE)0;
|
|
|
|
if(visible)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
|
|
#if 0 //def I_SAY_YES_TO_DUAL_TEXTURES
|
|
if(MLRState::GetMultitextureLightMap() == true && state.GetMultiTextureMode()!=MLRState::MultiTextureOffMode)
|
|
{
|
|
CheckVertices1( gos_vertices2uv, numGOSVertices );
|
|
}
|
|
else
|
|
{
|
|
CheckVertices( gos_vertices, numGOSVertices, false );
|
|
}
|
|
#endif // // I_SAY_YES_TO_DUAL_TEXTURES
|
|
|
|
|
|
Stop_Timer(Clipping_Time);
|
|
|
|
return ret;
|
|
}
|