322 lines
10 KiB
C++
322 lines
10 KiB
C++
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: drawprim.hpp
|
|
* Content: DrawPrimitive common defines
|
|
*
|
|
***************************************************************************/
|
|
|
|
#ifndef _DRAWPRIM_H_
|
|
#define _DRAWPRIM_H_
|
|
|
|
#define MAX_DX6_VERTICES ((1<<16) - 1)
|
|
#ifdef WIN95
|
|
#define LOWVERTICESNUMBER 128
|
|
#else
|
|
#define LOWVERTICESNUMBER 96
|
|
#endif
|
|
#define D3D_MAX_TLVBUF_CHANGES 5
|
|
|
|
// All vertices from lpDevI->lpVout are copied to the output buffer, expanding
|
|
// to D3DTLVERTEX.
|
|
// The output buffer is lpAddress if it is not NULL, otherwise it is TLVbuf
|
|
//
|
|
//---------------------------------------------------------------------
|
|
#define FVF_TRANSFORMED(dwFVF) ((dwFVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)
|
|
#define FVF_TEXCOORD_NUMBER(dwFVF) \
|
|
(((dwFVF) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
|
|
//---------------------------------------------------------------------
|
|
// Computes size in bytes of the position component of a vertex
|
|
//
|
|
__inline DWORD GetPositionSizeFVF(DWORD fvf)
|
|
{
|
|
DWORD size = 3 << 2;
|
|
switch (fvf & D3DFVF_POSITION_MASK)
|
|
{
|
|
case D3DFVF_XYZRHW: size += 4; break;
|
|
case D3DFVF_XYZB1: size += 1*4; break;
|
|
case D3DFVF_XYZB2: size += 2*4; break;
|
|
case D3DFVF_XYZB3: size += 3*4; break;
|
|
case D3DFVF_XYZB4: size += 4*4; break;
|
|
case D3DFVF_XYZB5: size += 5*4; break;
|
|
}
|
|
return size;
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// Computes vertex size in bytes for a the vertex ID excluding size of
|
|
// texture oordinates
|
|
//
|
|
__inline DWORD GetVertexSizeFVF(DWORD fvf)
|
|
{
|
|
DWORD size = GetPositionSizeFVF(fvf);
|
|
if (fvf & D3DFVF_NORMAL)
|
|
size += 3*4;
|
|
if (fvf & D3DFVF_PSIZE)
|
|
size += 4;
|
|
|
|
if (fvf & D3DFVF_DIFFUSE)
|
|
size+= 4;
|
|
if (fvf & D3DFVF_SPECULAR)
|
|
size += 4;
|
|
|
|
if (fvf & D3DFVF_FOG)
|
|
size += 4;
|
|
|
|
return size;
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// Entry is texture count. Clears all texture format bits in the FVF DWORD,
|
|
// that correspond to the texture count
|
|
// for this count
|
|
const DWORD g_TextureFormatMask[9] = {
|
|
~0x0000FFFF,
|
|
~0x0003FFFF,
|
|
~0x000FFFFF,
|
|
~0x003FFFFF,
|
|
~0x00FFFFFF,
|
|
~0x03FFFFFF,
|
|
~0x0FFFFFFF,
|
|
~0x3FFFFFFF,
|
|
~0xFFFFFFFF
|
|
};
|
|
//---------------------------------------------------------------------
|
|
// Computes vertex size in bytes from the vertex ID
|
|
//
|
|
// Texture formats size 00 01 10 11
|
|
const BYTE g_TextureSize[4] = {2*4, 3*4, 4*4, 4};
|
|
|
|
//---------------------------------------------------------------------
|
|
// Index is number of floats in a texture coordinate set.
|
|
// Value is texture format bits
|
|
//
|
|
const DWORD g_dwTextureFormat[5] = {0, 3, 0, 1, 2};
|
|
|
|
//---------------------------------------------------------------------
|
|
// Returns total size of texture coordinates
|
|
// Computes dwTextureCoordSize[] array - size of every texture coordinate set
|
|
//
|
|
inline DWORD ComputeTextureCoordSize(DWORD dwFVF, DWORD *dwTextureCoordSize)
|
|
{
|
|
DWORD dwNumTexCoord = FVF_TEXCOORD_NUMBER(dwFVF);
|
|
DWORD dwTextureCoordSizeTotal;
|
|
|
|
// Compute texture coordinate size
|
|
DWORD dwTextureFormats = dwFVF >> 16;
|
|
if (dwTextureFormats == 0)
|
|
{
|
|
dwTextureCoordSizeTotal = (BYTE)dwNumTexCoord * 2 * 4;
|
|
for (DWORD i=0; i < dwNumTexCoord; i++)
|
|
{
|
|
dwTextureCoordSize[i] = 4*2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwOffset = 0;
|
|
dwTextureCoordSizeTotal = 0;
|
|
for (DWORD i=0; i < dwNumTexCoord; i++)
|
|
{
|
|
BYTE dwSize = g_TextureSize[dwTextureFormats & 3];
|
|
dwTextureCoordSize[i] = dwSize;
|
|
dwTextureCoordSizeTotal += dwSize;
|
|
dwTextureFormats >>= 2;
|
|
}
|
|
}
|
|
return dwTextureCoordSizeTotal;
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// Computes vertex in bytes for the given FVF
|
|
//
|
|
inline DWORD ComputeVertexSizeFVF(DWORD dwFVF)
|
|
{
|
|
DWORD dwTextureFormats = dwFVF >> 16;
|
|
DWORD dwNumTexCoord = FVF_TEXCOORD_NUMBER(dwFVF);
|
|
DWORD size = GetVertexSizeFVF(dwFVF);
|
|
if (dwTextureFormats == 0)
|
|
{
|
|
size += (BYTE)dwNumTexCoord * 2 * 4;
|
|
}
|
|
else
|
|
{
|
|
for (DWORD i=0; i < dwNumTexCoord; i++)
|
|
{
|
|
size += g_TextureSize[dwTextureFormats & 3];
|
|
dwTextureFormats >>= 2;
|
|
}
|
|
}
|
|
return size;
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// Computes the number of primtives and also updates the stats accordingly
|
|
// Input: lpDevI->primType
|
|
// dwNumVertices
|
|
// Output: lpDevI->dwNumPrimitives
|
|
// return value = dwNumPrimitives
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "GetNumPrim"
|
|
|
|
inline __declspec(nothrow) void GetNumPrim(LPD3DHAL lpDevI, DWORD dwNumVertices)
|
|
{
|
|
D3DFE_PROCESSVERTICES* pv = lpDevI->m_pv;
|
|
pv->dwNumPrimitives = 0;
|
|
switch (pv->primType)
|
|
{
|
|
case D3DPT_POINTLIST:
|
|
pv->dwNumPrimitives = dwNumVertices;
|
|
break;
|
|
case D3DPT_LINELIST:
|
|
pv->dwNumPrimitives = dwNumVertices >> 1;
|
|
break;
|
|
case D3DPT_LINESTRIP:
|
|
if (dwNumVertices < 2)
|
|
return;
|
|
pv->dwNumPrimitives = dwNumVertices - 1;
|
|
break;
|
|
case D3DPT_TRIANGLEFAN:
|
|
case D3DPT_TRIANGLESTRIP:
|
|
if (dwNumVertices < 3)
|
|
return;
|
|
pv->dwNumPrimitives = dwNumVertices - 2;
|
|
break;
|
|
case D3DPT_TRIANGLELIST:
|
|
#ifdef _X86_
|
|
{
|
|
DWORD tmp;
|
|
__asm
|
|
{
|
|
mov eax, 0x55555555 // fractional part of 1.0/3.0
|
|
mul dwNumVertices
|
|
add eax, 0x80000000 // Rounding
|
|
adc edx, 0
|
|
mov tmp, edx
|
|
}
|
|
pv->dwNumPrimitives = tmp;
|
|
}
|
|
#else
|
|
pv->dwNumPrimitives = dwNumVertices / 3;
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------
|
|
// Sets front-end flags every time fog state is changed
|
|
//
|
|
inline void CD3DHal::SetFogFlags(void)
|
|
{
|
|
// Call ForceFVFRecompute only if fog enable state has been changed
|
|
BOOL bFogWasEnabled = m_pv->dwDeviceFlags & D3DDEV_FOG;
|
|
if (m_pv->lighting.fog_mode != D3DFOG_NONE &&
|
|
this->rstates[D3DRENDERSTATE_FOGENABLE])
|
|
{
|
|
m_pv->dwDeviceFlags |= D3DDEV_FOG;
|
|
if (!bFogWasEnabled)
|
|
ForceFVFRecompute();
|
|
}
|
|
else
|
|
{
|
|
m_pv->dwDeviceFlags &= ~D3DDEV_FOG;
|
|
if (bFogWasEnabled)
|
|
ForceFVFRecompute();
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Computes dwFlags bits which depend on the output FVF
|
|
//
|
|
inline void UpdateFlagsForOutputFVF(D3DFE_PROCESSVERTICES* lpDevI)
|
|
{
|
|
if (lpDevI->dwDeviceFlags & D3DDEV_LIGHTING &&
|
|
lpDevI->dwVIDOut & (D3DFVF_DIFFUSE | D3DFVF_SPECULAR))
|
|
{
|
|
lpDevI->dwFlags |= D3DPV_LIGHTING;
|
|
}
|
|
if (lpDevI->dwDeviceFlags & D3DDEV_FOG && lpDevI->dwVIDOut & D3DFVF_SPECULAR)
|
|
{
|
|
lpDevI->dwFlags |= D3DPV_FOG;
|
|
}
|
|
if (!(lpDevI->dwVIDOut & D3DFVF_DIFFUSE))
|
|
lpDevI->dwFlags |= D3DPV_DONOTCOPYDIFFUSE;
|
|
if (!(lpDevI->dwVIDOut & D3DFVF_SPECULAR))
|
|
lpDevI->dwFlags |= D3DPV_DONOTCOPYSPECULAR;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Restore indices in the texture stages which were re-mapped for texture
|
|
// transforms
|
|
// We have to do restore if
|
|
// - Set or Get render state is issued with _WRAP parameter
|
|
// - Set or Get texture stage is issued with TEXCOORDINDEX as a parameter
|
|
//
|
|
extern void RestoreTextureStages(LPD3DHAL pDevI);
|
|
//---------------------------------------------------------------------
|
|
// the function works when there are texture transforms.
|
|
// It computes number of output texture coordinates, texture coordinate size and format.
|
|
// It prepares texture stages to re-map texture coordinates
|
|
//
|
|
void EvalTextureTransforms(LPD3DHAL pDevI, DWORD dwTexTransform,
|
|
DWORD *pdwOutTextureSize, DWORD *pdwOutTextureFormat);
|
|
//----------------------------------------------------------------------
|
|
// Sets texture transform pointer for every input texture coordinate set
|
|
//
|
|
void SetupTextureTransforms(LPD3DHAL pDevI);
|
|
//----------------------------------------------------------------------
|
|
inline BOOL TextureTransformEnabled(LPD3DHAL pDevI)
|
|
{
|
|
return __TEXTURETRANSFORMENABLED(pDevI->m_pv);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Having primitive type as index, this array returns two coefficients("a" and
|
|
// "b") to compute number of vertices as NumPrimitives*a + b
|
|
//
|
|
extern DWORD g_PrimToVerCount[7][2];
|
|
//-----------------------------------------------------------------------------
|
|
inline UINT GETVERTEXCOUNT(D3DPRIMITIVETYPE primType, UINT dwNumPrimitives)
|
|
{
|
|
return g_PrimToVerCount[primType][0] * dwNumPrimitives +
|
|
g_PrimToVerCount[primType][1];
|
|
}
|
|
extern void setIdentity(D3DMATRIXI * m);
|
|
extern void MatrixProduct(D3DMATRIXI *d, D3DMATRIXI *a, D3DMATRIXI *b);
|
|
extern LIGHT_VERTEX_FUNC_TABLE lightVertexTable;
|
|
extern void MatrixProduct(D3DMATRIXI *result, D3DMATRIXI *a, D3DMATRIXI *b);
|
|
void D3DFE_UpdateLights(LPD3DHAL lpDevI);
|
|
//---------------------------------------------------------------------
|
|
// Updates lighting and computes process vertices flags
|
|
//
|
|
extern void DoUpdateState(LPD3DHAL lpDevI);
|
|
//----------------------------------------------------------------------
|
|
inline void UpdateClipStatus(CD3DHal* pDev)
|
|
{
|
|
pDev->m_ClipStatus.ClipUnion |= pDev->m_pv->dwClipUnion;
|
|
pDev->m_ClipStatus.ClipIntersection &= pDev->m_pv->dwClipIntersection;
|
|
}
|
|
//----------------------------------------------------------------------
|
|
// This is a list of all rstates that which are for the vertex processing only.
|
|
// In the software vertex processing mode these render states are not passed
|
|
// to the driver. The are passed when we switch to the hardware vertex processing mode
|
|
//
|
|
const D3DRENDERSTATETYPE rsVertexProcessingList[] = {
|
|
D3DRS_RANGEFOGENABLE,
|
|
D3DRS_LIGHTING,
|
|
D3DRS_AMBIENT,
|
|
D3DRS_FOGVERTEXMODE,
|
|
D3DRS_COLORVERTEX,
|
|
D3DRS_LOCALVIEWER,
|
|
D3DRS_NORMALIZENORMALS,
|
|
D3DRS_DIFFUSEMATERIALSOURCE,
|
|
D3DRS_SPECULARMATERIALSOURCE,
|
|
D3DRS_AMBIENTMATERIALSOURCE,
|
|
D3DRS_EMISSIVEMATERIALSOURCE,
|
|
D3DRS_VERTEXBLEND,
|
|
D3DRS_CLIPPLANEENABLE,
|
|
D3DRS_SOFTWAREVERTEXPROCESSING,
|
|
D3DRS_POINTSCALEENABLE,
|
|
D3DRS_POINTSCALE_A,
|
|
D3DRS_POINTSCALE_B,
|
|
D3DRS_POINTSCALE_C,
|
|
D3DRS_INDEXEDVERTEXBLENDENABLE,
|
|
D3DRS_TWEENFACTOR
|
|
};
|
|
|
|
#endif _DRAWPRIM_H_
|