📄 mlrtriangleclipping.hpp
字号:
//===========================================================================//
// Copyright (C) Microsoft Corporation. All rights reserved. //
//===========================================================================//
#if !defined(MLR_MLRCLIPTRICK_HPP)
#include <MLR\MLRClipTrick.hpp>
#endif
extern DWORD gEnableTextureSort, gShowClippedPolys, gEnableDetailTexture;
extern unsigned short *indexOffset; // [MidLevelRenderer::Max_Number_Vertices_Per_Mesh]
#define HUNT_CLIP_ERROR 0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CLASSNAME::TransformNoClip(Matrix4D *mat, GOSVertexPool *vt, bool db)
{
Check_Object(this);
Check_Object(vt);
Verify(index.GetLength() > 0);
Start_Timer(Transform_Time);
// unsigned short stride;
int stride;
bool textureAnimation = false;
Scalar deltaU=0.0f, deltaV=0.0f;
if(state.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
Check_Object(texture);
textureAnimation = texture->GetAnimateTexture();
if(textureAnimation)
{
Stuff::AffineMatrix4D &textureMatrix = texture->GetTextureMatrix();
deltaU = textureMatrix(3, 0);
deltaV = textureMatrix(3, 1);
}
}
int i, j;
#ifdef I_SAY_YES_TO_TERRAIN
Scalar terrainUV[2];
#endif // I_SAY_YES_TO_TERRAIN
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
int m;
gos_PushCurrentHeap(StaticHeap);
int tex2count[Limits::Max_Number_Of_Multitextures];
gos_PopCurrentHeap();
for(m=0;m<currentNrOfPasses;m++)
{
tex2count[m] = 0;
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
int numVertices = GetNumVertices();
gos_vertices = vt->GetActualVertexPool(db);
#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);
Verify(coords.GetLength() == visibleIndexedVertices.GetLength());
if(visibleIndexedVerticesKey == false)
{
FindVisibleVertices();
}
#ifdef _ARMOR
memset(indexOffset, 0xff, Limits::Max_Number_Vertices_Per_Mesh*sizeof(unsigned short));
#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 < 2*Limits::Max_Number_Vertices_Per_Mesh);
}
#endif // LAB_ONLY
*(int *)(&indexOffset[j]) = (j - stride);
#ifdef I_SAY_YES_TO_TERRAIN
terrainUV[0] = borderPixelFun + (coords[j].x - minX)*xUVFac;
terrainUV[1] = borderPixelFun + (coords[j].z - minZ)*zUVFac;
#endif // I_SAY_YES_TO_TERRAIN
#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 = 0xffffffff;
#endif // I_SAY_YES_TO_COLOR
}
else
{
gos_vertices[numGOSVertices].GOSTransformNoClip(
coords[j],
*mat,
&texCoords[j][0]
#if FOG_HACK
,state.GetFogMode()
#endif // FOG_HACK
);
(*texCoords2)[tex2count++] = texCoords[numVertices + j];
}
#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
detailTexCoords[0] = texCoords[j][0]*xScale;
detailTexCoords[1] = texCoords[j][1]*yScale;
#else
detailTexCoords[0] = texCoords[j][0]*xScale + xOffset;
detailTexCoords[1] = texCoords[j][1]*yScale + yOffset;
#endif
Verify( MLRState::GetHasMaxUVs() ? (detailTexCoords[0]>=-MLRState::GetMaxUV() && detailTexCoords[0]<=MLRState::GetMaxUV()) : 1);
Verify( MLRState::GetHasMaxUVs() ? (detailTexCoords[1]>=-MLRState::GetMaxUV() && detailTexCoords[1]<=MLRState::GetMaxUV()) : 1);
gos_vertices2uv[numGOSVertices].GOSTransformNoClip(
coords[j],
*mat,
&texCoords[j][0],
&detailTexCoords[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 = 0xffffffff;
#endif // I_SAY_YES_TO_COLOR
if(gos_vertices[j].rhw < fadeDetailEnd)
{
gos_vertices[j].argb &= 0x00ffffff;
}
else
{
if(gos_vertices[j].rhw<fadeDetailStart)
{
gos_vertices[j].argb &= ((Stuff::Truncate_Float_To_Word((gos_vertices[j].rhw - fadeDetailEnd)*fadeMultiplicator)) << 24) | 0x00ffffff;
}
}
}
else
#endif // I_SAY_YES_TO_DETAIL_TEXTURES
{
gos_vertices[numGOSVertices].GOSTransformNoClip(
coords[j],
*mat,
#ifdef I_SAY_YES_TO_TERRAIN
terrainUV
#else // I_SAY_YES_TO_TERRAIN
&texCoords[j][0]
#endif // I_SAY_YES_TO_TERRAIN
#if FOG_HACK
, state.GetFogMode()
#endif // FOG_HACK
);
#ifdef I_SAY_YES_TO_COLOR
#if COLOR_AS_DWORD
gos_vertices[numGOSVertices].argb = (*actualColors)[j];
#else // COLOR_AS_DWORD
gos_vertices[numGOSVertices].argb = GOSCopyColor(&(*actualColors)[j]);
#endif // COLOR_AS_DWORD
#else // I_SAY_YES_TO_COLOR
gos_vertices[numGOSVertices].argb = 0xffffffff;
#endif // I_SAY_YES_TO_COLOR
}
#endif // I_SAY_YES_TO_DUAL_TEXTURES
if(textureAnimation)
{
gos_vertices[numGOSVertices].u += deltaU;
gos_vertices[numGOSVertices].v += deltaV;
}
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
for(m=1;m<currentNrOfPasses;m++)
{
extraMultiTexCoords[m][tex2count[m]++] = multiTexCoordsPointers[m][j];
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
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 (2*numGOSVertices < 2*Limits::Max_Number_Vertices_Per_Mesh);
}
if(state2.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
Verify(texture);
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
{
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 (2*numGOSVertices < 2*Limits::Max_Number_Vertices_Per_Mesh );
}
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;
gos_vertices[j].v = gos_vertices[i].v*yScale + yOffset;
#endif
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);
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
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
for(m=1;m<currentNrOfPasses;m++)
{
Verify (tex2count[m] == numGOSVertices);
if(db==false)
{
Verify (vt->GetLast() + numGOSVertices < vt->GetLength());
}
else
{
Verify (numGOSVertices < 2*Limits::Max_Number_Vertices_Per_Mesh);
}
memcpy(gos_vertices + numGOSVertices, gos_vertices, numGOSVertices * sizeof(GOSVertex));
for(i=0,j=numGOSVertices;i<numGOSVertices;i++,j++)
{
gos_vertices[j].u = extraMultiTexCoords[m][i][0];
gos_vertices[j].v = extraMultiTexCoords[m][i][1];
}
if(db==false)
{
vt->Increase(numGOSVertices);
}
}
#endif // I_SAY_YES_TO_MULTI_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 < 2*Limits::Max_Number_Vertices_Per_Mesh);
}
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 = (unsigned short)ngi;
Check_Object(vt);
if(db==false)
{
vt->IncreaseIndex(numGOSIndices);
}
visible = numGOSVertices ? (unsigned char)1 : (unsigned char)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, bool db)
{
Check_Object(this);
Start_Timer(Transform_Time);
Verify(numOfTriangles == testList.GetLength());
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);
unsigned short l;
int i, j, k, ret = 0;
int len = coords.GetLength();
if(visibleIndexedVerticesKey == false)
{
FindVisibleVertices();
}
Stuff::Vector4D *v4d = transformedCoords->GetData();
Stuff::Point3D *p3d = coords.GetData();
int *cs = (int *)clipPerVertex->GetData();
unsigned char *viv = visibleIndexedVertices.GetData();
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -