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.
 
 
 
 
 
 

314 lines
8.3 KiB

//----------------------------------------------------------------------------
//
// point.cpp
//
// Point processing.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "rgb_pch.h"
#pragma hdrstop
#include "d3dutil.h"
#include "setup.hpp"
#include "attrs_mh.h"
#include "tstp_mh.h"
#include "walk_mh.h"
#include "rsdbg.hpp"
DBG_DECLARE_FILE();
void
PrimProcessor::FillPointSpan(LPD3DTLVERTEX pV0, PD3DI_RASTSPAN pSpan)
{
FLOAT fZ;
FLOAT fZScale;
pSpan->uPix = 1;
pSpan->uX = (UINT16)m_StpCtx.iX;
pSpan->uY = (UINT16)m_StpCtx.iY;
pSpan->pSurface = m_StpCtx.pCtx->pSurfaceBits +
m_StpCtx.iX * m_StpCtx.pCtx->iSurfaceStep +
m_StpCtx.iY * m_StpCtx.pCtx->iSurfaceStride;
if (m_StpCtx.uFlags & PRIMSF_Z_USED)
{
pSpan->pZ = m_StpCtx.pCtx->pZBits +
m_StpCtx.iX * m_StpCtx.pCtx->iZStep +
m_StpCtx.iY * m_StpCtx.pCtx->iZStride;
if (m_StpCtx.pCtx->iZBitCount == 16)
{
fZScale = Z16_SCALE;
}
else
{
fZScale = Z32_SCALE;
}
// fZ may be used later so set if from the vertex Z.
fZ = pV0->dvSZ;
pSpan->uZ = FTOI(fZ * fZScale);
}
if (m_StpCtx.uFlags & PRIMSF_TEX_USED)
{
FLOAT fW;
FLOAT fUoW, fVoW;
// Mipmapping doesn't have any meaning.
RSASSERT((m_StpCtx.uFlags & PRIMSF_LOD_USED) == 0);
if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
{
if (FLOAT_EQZ(pV0->dvRHW))
{
fW = g_fZero;
}
else
{
fW = g_fOne / pV0->dvRHW;
}
pSpan->iW = FTOI(fW * W_SCALE);
fUoW = pV0->dvTU * pV0->dvRHW;
fVoW = pV0->dvTV * pV0->dvRHW;
pSpan->iOoW = FTOI(pV0->dvRHW * OOW_SCALE);
}
else
{
fUoW = pV0->dvTU;
fVoW = pV0->dvTV;
}
pSpan->iLOD = 0;
pSpan->iDLOD = 0;
pSpan->UVoW[0].iUoW = FTOI(fUoW * TEX_SCALE);
pSpan->UVoW[0].iVoW = FTOI(fVoW * TEX_SCALE);
}
if (m_StpCtx.uFlags & PRIMSF_TEX2_USED)
{
for (INT32 i = 1; i < (INT32)m_StpCtx.pCtx->cActTex; i++)
{
if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
{
pSpan->UVoW[i].iUoW =
FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTU *
pV0->dvRHW * TEX_SCALE);
pSpan->UVoW[i].iVoW =
FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTV *
pV0->dvRHW * TEX_SCALE);
}
else
{
pSpan->UVoW[i].iUoW =
FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTU * TEX_SCALE);
pSpan->UVoW[i].iVoW =
FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTV * TEX_SCALE);
}
}
}
if (m_StpCtx.uFlags & PRIMSF_DIFF_USED)
{
pSpan->uB = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcColor) <<
COLOR_SHIFT;
pSpan->uG = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcColor) <<
COLOR_SHIFT;
pSpan->uR = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcColor) <<
COLOR_SHIFT;
pSpan->uA = (UINT)RGBA_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
COLOR_SHIFT;
}
else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED)
{
pSpan->iIdx = (INT32)CI_MASKALPHA(m_StpCtx.pFlatVtx->dcColor) <<
INDEX_COLOR_FIXED_SHIFT;
pSpan->iIdxA = (INT32)CI_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
INDEX_COLOR_SHIFT;
}
if (m_StpCtx.uFlags & PRIMSF_SPEC_USED)
{
pSpan->uBS = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcSpecular) <<
COLOR_SHIFT;
pSpan->uGS = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcSpecular) <<
COLOR_SHIFT;
pSpan->uRS = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcSpecular) <<
COLOR_SHIFT;
}
if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED)
{
if (m_StpCtx.uFlags & PRIMSF_GLOBAL_FOG_USED)
{
// Make sure that fZ has been set.
RSASSERT(m_StpCtx.uFlags & PRIMSF_Z_USED);
pSpan->uFog = (UINT16)ComputeTableFog(m_StpCtx.pCtx->pdwRenderState, fZ);
}
else
{
pSpan->uFog = (UINT16)(
FTOI((FLOAT)RGBA_GETALPHA(pV0->dcSpecular) *
FOG_255_SCALE));
}
}
}
// Determine whether any of the given values are less than zero or greater
// than one. Negative zero counts as less than zero so this check will
// produce some false positives but that's OK.
#define NEEDS_NORMALIZE1(fV0) \
(ASUINT32(fV0) > INT32_FLOAT_ONE)
//----------------------------------------------------------------------------
//
// PrimProcessor::NormalizePointRHW
//
// D3DTLVERTEX.dvRHW can be anything, but our internal structures only
// allow for it being in the range [0, 1]. This function clamps
// the RHW to the proper range.
//
//----------------------------------------------------------------------------
void
PrimProcessor::NormalizePointRHW(LPD3DTLVERTEX pV0)
{
// Save original value.
m_dvV0RHW = pV0->dvRHW;
// Produce a warning when a value is out of the desired range.
#if DBG
if (FLOAT_LTZ(pV0->dvRHW))
{
RSDPF(("Point RHW out of range %f,%f",
pV0->dvRHW));
}
#endif
if (pV0->dvRHW < NORMALIZED_RHW_MIN)
{
pV0->dvRHW = NORMALIZED_RHW_MIN;
}
else if (pV0->dvRHW > NORMALIZED_RHW_MAX)
{
pV0->dvRHW = NORMALIZED_RHW_MAX;
}
}
//----------------------------------------------------------------------------
//
// PrimProcessor::Point
//
// Provides a point for processing.
//
//----------------------------------------------------------------------------
HRESULT
PrimProcessor::Point(LPD3DTLVERTEX pV0,
LPD3DTLVERTEX pFlatVtx)
{
HRESULT hr;
hr = DD_OK;
#if DBG
hr = ValidateVertex(pV0);
if (hr != DD_OK)
{
return hr;
}
#endif
// Clear per-point flags.
m_StpCtx.uFlags &= ~(PRIMF_ALL | PTF_ALL);
RSDPFM((RSM_FLAGS, "m_uPpFlags: 0x%08X, m_StpCtx.uFlags: 0x%08X",
m_uPpFlags, m_StpCtx.uFlags));
// Round coordinates to integer.
m_StpCtx.iX = IFLOORF(pV0->dvSX + g_fHalf);
m_StpCtx.iY = IFLOORF(pV0->dvSY + g_fHalf);
RSDPFM((RSM_POINTS, "Point\n"));
RSDPFM((RSM_POINTS, " V0 (%f,%f,%f) (%d,%d)\n",
pV0->dvSX, pV0->dvSY, pV0->dvSZ,
m_StpCtx.iX, m_StpCtx.iY));
// Clip test.
if (m_StpCtx.iX < m_StpCtx.pCtx->Clip.left ||
m_StpCtx.iX >= m_StpCtx.pCtx->Clip.right ||
m_StpCtx.iY < m_StpCtx.pCtx->Clip.top ||
m_StpCtx.iY >= m_StpCtx.pCtx->Clip.bottom)
{
return DD_OK;
}
//
// Fill out a one-pixel span for the point.
// Since the prim deltas are irrelevant for the span,
// the span is appended to whatever primitive happens
// to be available in the buffer.
//
PD3DI_RASTSPAN pSpan;
UINT cSpans = 1;
hr = AppendPrim();
if (hr != DD_OK)
{
return hr;
}
hr = AllocSpans(&cSpans, &pSpan);
if (hr != DD_OK)
{
return hr;
}
m_StpCtx.pPrim->uSpans++;
BOOL bNorm;
// USED checks cannot be combined since TEX_USED is a multibit check.
if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) &&
(m_StpCtx.uFlags & PRIMSF_PERSP_USED) &&
(m_uPpFlags & PPF_NORMALIZE_RHW) &&
NEEDS_NORMALIZE1(pV0->dvRHW))
{
NormalizePointRHW(pV0);
bNorm = TRUE;
}
else
{
bNorm = FALSE;
}
// Remember flat color controlling vertex for setup, if flat shaded.
if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
{
m_StpCtx.pFlatVtx = pFlatVtx;
}
else
{
m_StpCtx.pFlatVtx = pV0;
}
FillPointSpan(pV0, pSpan);
if (bNorm)
{
pV0->dvRHW = m_dvV0RHW;
}
return DD_OK;
}