Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

790 lines
29 KiB

/*============================ ==============================================;
*
* Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
*
* File: pvvid.mcp
* Content: The implementation of the geometry inner loop
*
***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
#define DEBUG_PIPELINE
#include "light.h"
#include "clipper.h"
#include "drawprim.hpp"
#include "pvvid.h"
include(`pvvid.mh') dnl
#ifdef DEBUG_PIPELINE
DWORD g_DebugFlags = 0;
#endif // DEBUG_PIPELINE
//--------------------------------------------------------------------------
// Input:
// v - input vertex in the model space
// le - vertex, transformed to the camera space
// Output:
// Alpha component of pv->lighting.outSpecular is set
//
void ComputeFog(LPD3DFE_PROCESSVERTICES pv, D3DVECTOR &v, D3DLIGHTINGELEMENT *le)
{
D3DVALUE dist;
if (pv->lighting.dwLightingFlags & __LIGHT_VERTEXTRANSFORMED)
{
// Vertex is already transformed to the camera space
if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
dist = SQRTF(le->dvPosition.x*le->dvPosition.x +
le->dvPosition.y*le->dvPosition.y +
le->dvPosition.z*le->dvPosition.z);
else
dist = le->dvPosition.z;
}
else
if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
{
D3DVECTOR veye;
d_TransformVertexToCameraSpace(2, (&v), (&veye));
dist = SQRTF(veye.x*veye.x + veye.y*veye.y + veye.z*veye.z);
}
else
{
if (pv->dwNumVerBlends == 0)
{
dist = v.x*pv->mWV._13 + v.y*pv->mWV._23 + v.z*pv->mWV._33 + pv->mWV._43;
}
else
{
D3DVECTOR veye;
d_TransformVertexToCameraSpace(2, (&v), (&veye));
dist = veye.z;
}
}
ComputeFogFactor(pv, dist, &pv->lighting.outSpecular);
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture
//
void TransformTexture1_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 2 texture coordinates
//
void TransformTexture1_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 3 texture coordinates
//
void TransformTexture1_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
pOut[2] = pIn[0] * m->_13 + m->_23;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 4 texture coordinates
//
void TransformTexture1_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
pOut[2] = pIn[0] * m->_13 + m->_23;
pOut[3] = pIn[0] * m->_14 + m->_24;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture
//
void TransformTexture2_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 1 texture coordinate
//
void TransformTexture2_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 3 texture coordinate
//
void TransformTexture2_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 4 texture coordinate
//
void TransformTexture2_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture
//
void TransformTexture3_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 1 texture coordinate
//
void TransformTexture3_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 2 texture coordinates
//
void TransformTexture3_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 4 texture coordinates
//
void TransformTexture3_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture
//
void TransformTexture4_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 1 texture coordinate
//
void TransformTexture4_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 2 texture coordinates
//
void TransformTexture4_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 3 texture coordinates
//
void TransformTexture4_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
DWORD dwCount,
DWORD dwInpStride,
DWORD dwOutStride)
{
for (; dwCount; dwCount--)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
}
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture.
//
void TransformTexture1_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 2 texture coordinates
//
void TransformTexture1_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 3 texture coordinates
//
void TransformTexture1_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
pOut[2] = pIn[0] * m->_13 + m->_23;
}
//---------------------------------------------------------------------
// Transform 1-dimensional texture. Output 4 texture coordinates
//
void TransformTexture1_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + m->_21;
pOut[1] = pIn[0] * m->_12 + m->_22;
pOut[2] = pIn[0] * m->_13 + m->_23;
pOut[3] = pIn[0] * m->_14 + m->_24;
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture
//
void TransformTexture2_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 1 texture coordinate
//
void TransformTexture2_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 3 texture coordinates
//
void TransformTexture2_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
}
//---------------------------------------------------------------------
// Transform 2-dimensional texture. Output 4 texture coordinates
//
void TransformTexture2_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 3 texture coordinates
//
void TransformTexture3_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 1 texture coordinates
//
void TransformTexture3_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 2 texture coordinates
//
void TransformTexture3_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
}
//---------------------------------------------------------------------
// Transform 3-dimensional texture. Output 4 texture coordinates
//
void TransformTexture3_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 4 texture coordinates
//
void TransformTexture4_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 1 texture coordinates
//
void TransformTexture4_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 2 texture coordinates
//
void TransformTexture4_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
}
//---------------------------------------------------------------------
// Transform 4-dimensional texture. Output 3 texture coordinates
//
void TransformTexture4_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
{
pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
}
//---------------------------------------------------------------------
// Index is:
// bits 0-1 - (number of input texture coordinates - 1)
// bits 2-3 - (number of output texture coordinates - 1)
//
PFN_TEXTURETRANSFORM g_pfnTextureTransform[16] =
{
TransformTexture1_1,
TransformTexture2_1,
TransformTexture3_1,
TransformTexture4_1,
TransformTexture1_2,
TransformTexture2_2,
TransformTexture3_2,
TransformTexture4_2,
TransformTexture1_3,
TransformTexture2_3,
TransformTexture3_3,
TransformTexture4_3,
TransformTexture1_4,
TransformTexture2_4,
TransformTexture3_4,
TransformTexture4_4
};
//---------------------------------------------------------------------
PFN_TEXTURETRANSFORMLOOP g_pfnTextureTransformLoop[16] =
{
TransformTexture1_1Loop,
TransformTexture2_1Loop,
TransformTexture3_1Loop,
TransformTexture4_1Loop,
TransformTexture1_2Loop,
TransformTexture2_2Loop,
TransformTexture3_2Loop,
TransformTexture4_2Loop,
TransformTexture1_3Loop,
TransformTexture2_3Loop,
TransformTexture3_3Loop,
TransformTexture4_3Loop,
TransformTexture1_4Loop,
TransformTexture2_4Loop,
TransformTexture3_4Loop,
TransformTexture4_4Loop
};
//---------------------------------------------------------------------
// This function should be called every time FVF ID is changed
// All pv flags, input and output FVF id should be set before calling the
// function.
static DWORD POSITION_SIZE[16] =
{
0, 0, 3*4, 0, 4*4, 0, 4*4, 0, 5*4, 0, 6*4, 0, 7*4, 0, 8*4, 0
};
//---------------------------------------------------------------------
// This function is called only when the input FVF is changed
//
void UpdateGeometryLoopData(LPD3DFE_PROCESSVERTICES pv)
{
// Compute input offsets
if (!(pv->dwDeviceFlags & D3DDEV_STRIDE))
{
DWORD i = POSITION_SIZE[pv->dwVIDIn & D3DFVF_POSITION_MASK];
pv->normalOffset = i;
if (pv->dwVIDIn & D3DFVF_NORMAL)
i += sizeof(D3DVECTOR);
if (pv->dwVIDIn & D3DFVF_RESERVED1)
i += sizeof(D3DVALUE);
pv->diffuseOffset = i;
if (pv->dwVIDIn & D3DFVF_DIFFUSE)
i += sizeof(DWORD);
pv->specularOffset = i;
if (pv->dwVIDIn & D3DFVF_SPECULAR)
i += sizeof(DWORD);
pv->texOffset = i;
}
ComputeOutputVertexOffsets(pv);
// For pre-DX6 drivers we have to copy only one texture coordinate index
// to the output
pv->dwDeviceFlags &= ~D3DDEV_NOFVFANDNOTEXTURE;
if (!(pv->dwDeviceFlags & D3DDEV_FVF || pv->dwFlags & D3DPV_VBCALL))
{
if (pv->nTexCoord)
{
for (DWORD k=0; k < pv->dwTextureIndexToCopy; k++)
pv->texOffset += pv->dwInpTextureCoordSize[k];
}
else
{
// For non-FVF drivers we have to fill texture coordinates with
// zeros.
pv->dwDeviceFlags |= D3DDEV_NOFVFANDNOTEXTURE;
}
}
}
//--------------------------------------------------------------------------
// Transforms, lights vertices. Computes clip codes
//
// The following fields from pv are used:
// dwFlags
// dwNumVertices
// all pointer and strides
// position.lpvStrides
// dwVIDIn
// dwVIDOut
// lpvOut
// lpClipFlags
// nTexCoord
// Returns:
// returns dwClipIntersection or 0 (if D3DDEV_DONOTCLIP is set)
// Side effects:
// dwClipUnion, dwClipIntersection are set only if D3DDEV_DONOTCLIP is not set
// rExtents is updated if D3DDEV_DONOTUPDATEEXTENTS is not set
//
#undef DPF_MODNAME
#define DPF_MODNAME "ProcessVerticesGen"
DWORD ProcessVerticesGen(LPD3DFE_PROCESSVERTICES pv)
{
D3DFE_CLIPCODE *hout = pv->lpClipFlags;
D3DTLVERTEX *out = (D3DTLVERTEX*)pv->lpvOut;
D3DMATRIXI *m = &pv->mCTM;
d_Setup()
for (DWORD i = pv->dwNumVertices; i; i--)
{
D3DLIGHTINGELEMENT EyeSpaceData;
float x, y, z, w;
// Transform vertex to the clipping space
d_TransformVertex(2, in, m, x, y, z, w)
if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
{
DWORD clip;
// Compute clip code
d_ComputeClipCode(3)
if (clip == 0)
{
dwClipIntersection = 0;
*hout++ = 0;
w = D3DVAL(1)/w;
}
else
{
if (dwDeviceFlags & D3DDEV_GUARDBAND)
{
// We do guardband check in the projection space, so
// we transform X and Y of the vertex there
d_ComputeClipCodeGB(5)
if ((clip & ~__D3DCLIP_INGUARDBAND) == 0)
{
// If vertex is inside the guardband we have to compute
// screen coordinates
w = D3DVAL(1)/w;
*hout++ = (D3DFE_CLIPCODE)clip;
dwClipIntersection &= clip;
dwClipUnion |= clip;
goto l_DoScreenCoord;
}
}
if (pv->dwFlags & D3DPV_ONEPASSCLIPPING)
{
pv->dwFirstClippedVertex = pv->dwNumVertices - i;
return 0;
}
dwClipIntersection &= clip;
dwClipUnion |= clip;
*hout++ = (D3DFE_CLIPCODE)clip;
// If vertex is outside the frustum we can not compute screen
// coordinates
out->sx = x;
out->sy = y;
out->sz = z;
out->rhw = w;
goto l_DoLighting;
}
}
else
{
// We have to check this only for DONOTCLIP case, because otherwise
// the vertex with "we = 0" will be clipped and screen coordinates
// will not be computed
// "clip" is not zero, if "w" is zero.
if (!FLOAT_EQZ(w))
w = D3DVAL(1)/w;
else
w = __HUGE_PWR2;
}
l_DoScreenCoord:
d_ComputeScreenCoordinates(2, x, y, z, w, out)
l_DoLighting:
d_DoLightingAndFog(2, in, inNormal, inDiffuse, inSpecular, out);
D3DVALUE *pOutTexture = (D3DVALUE*)((BYTE*)out + pv->texOffsetOut);
d_CopyTextureCoordUpdateInputPointers(2, pOutTexture);
NEXT(out, dwOutVerSize, D3DTLVERTEX);
}
d_UpdateExtents()
pv->dwClipIntersection = dwClipIntersection;
pv->dwClipUnion = dwClipUnion;
return dwClipIntersection;
}
//---------------------------------------------------------------------
extern DWORD ProcessVerticesLoop(D3DFE_PROCESSVERTICES *pv);
//---------------------------------------------------------------------
DWORD D3DFE_PVFUNCS::ProcessVertices(LPD3DFE_PROCESSVERTICES pv)
{
CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
#ifdef DEBUG_PIPELINE
if (g_DebugFlags & __DEBUG_MULTILOOP)
return ProcessVerticesGen(pv);
#endif
if (pv->dwFlags & D3DPV_LIGHTING || pv->dwDeviceFlags & D3DDEV_TEXTURETRANSFORM)
return ProcessVerticesLoop(pv);
else
return ProcessVerticesGen(pv);
}
//---------------------------------------------------------------------
HRESULT D3DFE_PVFUNCS::ProcessPrimitive(LPD3DFE_PROCESSVERTICES pv)
{
CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
#ifdef DEBUG_PIPELINE
if (!(g_DebugFlags & __DEBUG_ONEPASS))
#endif
if (!(pv->dwDeviceFlags & D3DDEV_DONOTCLIP))
{ // We can do optimized processing of non-indexed primitives that
// require clipping
switch (pv->primType)
{
case D3DPT_TRIANGLELIST : return ProcessTriangleList(pv);
case D3DPT_TRIANGLESTRIP: return ProcessTriangleStrip(pv);
case D3DPT_TRIANGLEFAN : return ProcessTriangleFan(pv);
case D3DPT_LINELIST : return ProcessLineList(pv);
case D3DPT_LINESTRIP : return ProcessLineStrip(pv);
}
}
this->ProcessVertices(pv);
if (pv->dwClipIntersection)
{
// all vertices were offscreen
return D3D_OK;
}
// This should not be required as we should be able to change
// the parameter of DoDrawPrimtive and all it's children to pv
return (DoDrawPrimitive(pv));
}
//---------------------------------------------------------------------
HRESULT D3DFE_PVFUNCS::ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
{
this->ProcessVertices(pv);
if (pv->dwClipIntersection)
{
// all vertices were offscreen
return D3D_OK;
}
return (DoDrawIndexedPrimitive(pv));
}
//---------------------------------------------------------------------
D3DFE_PROCESSVERTICES::D3DFE_PROCESSVERTICES()
{
for (DWORD i=0; i < D3DDP_MAXTEXCOORD; i++)
{
// Set texture size array to default for pre-DX7 drivers
this->dwTextureCoordSize[i] = 4*2;
}
for (i = 0; i < VER_IN_BATCH-1; i++)
{
clipVer[i].next = &clipVer[i+1];
}
clipVer[VER_IN_BATCH-1].next = clipVer;
this->dwFlags = 0;
this->dwDeviceFlags = 0;
this->dwFlags2 = 0;
this->dwMaxUserClipPlanes = 0;
#ifdef DEBUG_PIPELINE
GetD3DRegValue(REG_DWORD, "DebugFlags", &g_DebugFlags, 4);
#endif
}
//---------------------------------------------------------------------
void DIRECT3DDEVICEI::CheckClipStatus(D3DVALUE * pPositions,
DWORD dwStride,
DWORD dwNumVertices,
DWORD *pdwClipUnion,
DWORD *pdwClipIntersection)
{
#define pv this
D3DVECTOR *p = (D3DVECTOR*)pPositions;
D3DMATRIXI *m = &this->mCTM;
DWORD dwClipUnion = 0;
DWORD dwClipIntersection = ~0;
for (DWORD i = dwNumVertices; i; i--)
{
D3DVALUE x, y, z, w;
DWORD clip;
// Transform vertex to the clipping space
x = p->x*m->_11 + p->y*m->_21 + p->z*m->_31 + m->_41;
y = p->x*m->_12 + p->y*m->_22 + p->z*m->_32 + m->_42;
z = p->x*m->_13 + p->y*m->_23 + p->z*m->_33 + m->_43;
w = p->x*m->_14 + p->y*m->_24 + p->z*m->_34 + m->_44;
d_ComputeClipCode(2)
p = (D3DVECTOR*)((BYTE*)p + dwStride);
dwClipUnion |= clip;
dwClipIntersection &= clip;
}
*pdwClipIntersection = dwClipIntersection;
*pdwClipUnion = dwClipUnion;
#undef pv
}