|
|
/******************************Module*Header**********************************\
* * ******************* * * D3D SAMPLE CODE * * ******************* * * Module Name: d3dprim.c * * Content: D3D primitives rendering * * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved. \*****************************************************************************/
// For the mipmap LOD calculation
#define BIAS_SHIFT 1
#define CULL_HERE 1
#include <limits.h>
#include "glint.h"
#include "dma.h"
#include "tag.h"
//-----------------------------------------------------------------------------
//
// Specialized hardaware rendering functions for the Permedia3,
// for all primitve types
//
//-----------------------------------------------------------------------------
#define GET_FOG(x) ((x) & 0xff000000 )
#define GET_SPEC(x) ((x) & 0x00ffffff )
#define SEND_R3FVFVERTEX_XYZ(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_VTX | Num; \ MEMORY_BARRIER(); \ dmaPtr[1] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[2] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[3] = AS_ULONG(pv[Index]->sz); \ dmaPtr += 4; \ CHECK_FIFO(4); \ }
#define SEND_R3FVFVERTEX_XYZ_STQ(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ MEMORY_BARRIER(); \ dmaPtr[4] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[5] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[6] = AS_ULONG(pv[Index]->sz); \ dmaPtr += 7; \ CHECK_FIFO(7); \ }
#define SEND_R3FVFVERTEX_XYZ_FOG(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_SPECULAR | Num; \ MEMORY_BARRIER(); \ dmaPtr[1] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[2] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[3] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[4] = GET_FOG( FVFSPEC(pv[Index])->specular ); \ dmaPtr += 5; \ CHECK_FIFO(5); \ }
#define SEND_R3FVFVERTEX_XYZ_STQ_FOG(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_SPECULAR | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ MEMORY_BARRIER(); \ dmaPtr[4] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[5] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[6] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[7] = GET_FOG( FVFSPEC(pv[Index])->specular ); \ dmaPtr += 8; \ CHECK_FIFO(8); \ }
#define SEND_R3FVFVERTEX_XYZ_RGBA(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_COLOR | Num; \ MEMORY_BARRIER(); \ dmaPtr[1] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[2] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[3] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[4] = FVFCOLOR(pv[Index])->color; \ MEMORY_BARRIER(); \ dmaPtr += 5; \ CHECK_FIFO(5); \ } #define SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \ MEMORY_BARRIER(); \ dmaPtr[1] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[2] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[3] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[4] = FVFCOLOR(pv[Index])->color; \ MEMORY_BARRIER(); \ dmaPtr[5] = FVFSPEC(pv[Index])->specular; \ dmaPtr += 6; \ CHECK_FIFO(6); \ }
#define SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ MEMORY_BARRIER(); \ dmaPtr[4] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[5] = AS_ULONG(pv[Index]->sy); \ MEMORY_BARRIER(); \ dmaPtr[6] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[7] = FVFCOLOR(pv[Index])->color; \ MEMORY_BARRIER(); \ dmaPtr[8] = FVFSPEC(pv[Index])->specular; \ dmaPtr += 9; \ CHECK_FIFO(9); \ }
#define SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(Num, Index, offset) \
{ \ float TempY = Y_ADJUST(pv[Index]->sy); \ if (offset == TRUE) TempY += 1.0f; \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ MEMORY_BARRIER(); \ dmaPtr[4] = AS_ULONG(pv[Index]->sx); \ MEMORY_BARRIER(); \ dmaPtr[5] = AS_ULONG(TempY); \ MEMORY_BARRIER(); \ dmaPtr[6] = AS_ULONG(pv[Index]->sz); \ MEMORY_BARRIER(); \ dmaPtr[7] = FVFCOLOR(pv[Index])->color; \ MEMORY_BARRIER(); \ dmaPtr[8] = FVFSPEC(pv[Index])->specular; \ dmaPtr += 9; \ CHECK_FIFO(9); \ }
#define SEND_R3FVFVERTEX_STQ2(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_STQ_VTX | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tu2; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = tc[Index].tv2; \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ dmaPtr += 4; \ CHECK_FIFO(4); \ }
#if DX8_3DTEXTURES
#define SEND_R3FVFVERTEX_3DTEX(Num, Index) \
{ \ MEMORY_BARRIER(); \ dmaPtr[0] = GAMBIT_STQ_VTX | Num; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[1] = tc[Index].tw1; \ MEMORY_BARRIER(); \ *(float volatile*)&dmaPtr[2] = 0; /* Not used */ \ MEMORY_BARRIER(); \ dmaPtr[3] = q[Index]; \ dmaPtr += 4; \ CHECK_FIFO(4); \ } #endif // DX8_3DTEXTURES
#if DX8_3DTEXTURES
#define GET_TC_3DTEX( Index ) \
*(DWORD *)&tc[Index].tu1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tu; \ *(DWORD *)&tc[Index].tv1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tv; \ *(DWORD *)&tc[Index].tw1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tw; #endif // DX8_3DTEXTURES
#define GET_TC( Index ) \
*(DWORD *)&tc[Index].tu1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tu; \ *(DWORD *)&tc[Index].tv1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tv;
#if DX8_3DTEXTURES
#define GET_TC2_3DTEX( Index ) \
*(DWORD *)&tc[Index].tu2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tu; \ *(DWORD *)&tc[Index].tv2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tv; \ *(DWORD *)&tc[Index].tw2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tw; #endif // DX8_3DTEXTURES
#define GET_TC2( Index ) \
*(DWORD *)&tc[Index].tu2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tu; \ *(DWORD *)&tc[Index].tv2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tv;
#define GET_ONE_TEXCOORD(vtx) \
GET_TC(vtx); \ if( pContext->iTexStage[1] != -1 ) \ { \ GET_TC2(vtx); \ }
#define GET_TEXCOORDS() \
GET_TC(0); GET_TC(1); GET_TC(2); \ if( pContext->iTexStage[1] != -1 ) \ { \ GET_TC2(0); GET_TC2(1); GET_TC2(2); \ }
#if DX8_3DTEXTURES
#define SCALE_BY_Q_3DTEX( Index ) \
tc[Index].tu1 *= *(float *)&q[Index]; \ tc[Index].tv1 *= *(float *)&q[Index]; \ tc[Index].tw1 *= *(float *)&q[Index]; #endif // DX8_3DTEXTURES
#define SCALE_BY_Q( Index ) \
tc[Index].tu1 *= *(float *)&q[Index]; \ tc[Index].tv1 *= *(float *)&q[Index];
#if DX8_3DTEXTURES
#define SCALE_BY_Q2_3DTEX( Index ) \
tc[Index].tu2 *= *(float *)&q[Index]; \ tc[Index].tv2 *= *(float *)&q[Index]; \ tc[Index].tw2 *= *(float *)&q[Index]; #endif // DX8_3DTEXTURES
#define SCALE_BY_Q2( Index ) \
tc[Index].tu2 *= *(float *)&q[Index]; \ tc[Index].tv2 *= *(float *)&q[Index];
#define DRAW_LINE() \
MEMORY_BARRIER(); \ dmaPtr[0] = DrawLine01_Tag; \ MEMORY_BARRIER(); \ dmaPtr[1] = renderCmd; \ dmaPtr += 2; \ CHECK_FIFO(2)
#define DRAW_POINT() \
MEMORY_BARRIER(); \ dmaPtr[0] = DrawPoint_Tag; \ MEMORY_BARRIER(); \ dmaPtr[1] = renderCmd; \ dmaPtr += 2; \ CHECK_FIFO(2)
#define DRAW_LINE_01_OR_10( vtx ) \
MEMORY_BARRIER(); \ dmaPtr[0] = vtx ? DrawLine01_Tag \ : DrawLine10_Tag; \ MEMORY_BARRIER(); \ dmaPtr[1] = renderCmd; \ dmaPtr += 2; \ CHECK_FIFO(2)
#define DRAW_TRIANGLE() \
MEMORY_BARRIER(); \ dmaPtr[0] = DrawTriangle_Tag; \ MEMORY_BARRIER(); \ dmaPtr[1] = renderCmd; \ dmaPtr += 2; \ CHECK_FIFO(2)
//-----------------------------------------------------------------------------
// Easy edge flag renaming
//-----------------------------------------------------------------------------
#define SIDE_0 D3DTRIFLAG_EDGEENABLE1
#define SIDE_1 D3DTRIFLAG_EDGEENABLE2
#define SIDE_2 D3DTRIFLAG_EDGEENABLE3
#define ALL_SIDES ( SIDE_0 | SIDE_1 | SIDE_2 )
//-----------------------------------------------------------------------------
// Cycle vertex indices for triangle strips viz. 0 -> 1, 1 -> 2, 2 -> 0
// See Graphics Gems 3, Pg 69.
//-----------------------------------------------------------------------------
#define INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b) \
vtx_a = 0; \ vtx_b = 0 ^ 1; \ pContext->dwProvokingVertex = 1;
#define CONST_c (0 ^ 1 ^ 2)
#define CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b) \
vtx_a ^= vtx_b; \ vtx_b ^= CONST_c; \ pContext->dwProvokingVertex = vtx_b; \ vtx_b ^= vtx_a;
//-----------------------------------------------------------------------------
// Local typedef for temporary texture coordinate storage
//-----------------------------------------------------------------------------
typedef struct { float tu1; float tv1; #if DX8_3DTEXTURES
float tw1; #endif // DX8_3DTEXTURES
float tu2; float tv2; #if DX8_3DTEXTURES
float tw2; #endif // DX8_3DTEXTURES
} TEXCOORDS;
//-----------------------------------------------------------------------------
// Macros to access and validate command and vertex buffer data
// These checks need ALWAYS to be made for all builds, free and checked.
//-----------------------------------------------------------------------------
#define LP_FVF_VERTEX(lpBaseAddr, wIndex) \
(LPD3DTLVERTEX)((LPBYTE)(lpBaseAddr) + (wIndex) * pContext->FVFData.dwStride)
#define LP_FVF_NXT_VTX(lpVtx) \
(LPD3DTLVERTEX)((LPBYTE)(lpVtx) + pContext->FVFData.dwStride)
#define CHECK_DATABUF_LIMITS(pbError, dwVBLen, iIndex ) \
{ \ if (! (((LONG)(iIndex) >= 0) && \ ((LONG)(iIndex) <(LONG)dwVBLen))) \ { \ DISPDBG((ERRLVL,"D3D: Trying to read past Vertex Buffer limits " \ "%d limit= %d ",(LONG)(iIndex), (LONG)dwVBLen)); \ *pbError = TRUE; \ return; \ } \ }
//-----------------------------------------------------------------------------
// Define values for FVF defaults
//-----------------------------------------------------------------------------
const FVFCOLOR gc_FVFColorDefault = { 0xFFFFFFFF }; const FVFSPECULAR gc_FVFSpecDefault = { 0x00000000 }; const FVFTEXCOORDS gc_FVFTexCoordDefault = { 0.0f, 0.0f #if DX8_3DTEXTURES
, 0.0f #endif
};
//-----------------------------------------------------------------------------
// Macros and functions for texture coord adjustment on wrapping
//-----------------------------------------------------------------------------
#define SHIFT_SET_0 1
#define SHIFT_SET_1 2
#define TEXSHIFT 1
#if TEXSHIFT
#if 0
// 8.0f as a DWORD
#define TEX_SHIFT_LIMIT 0x41000000
#define FP_SIGN_MASK 0x7fffffff
#define TEXTURE_SHIFT( coord ) \
if(( *(DWORD *)&tc[0].##coord & FP_SIGN_MASK ) > TEX_SHIFT_LIMIT ) \ { \ myFtoi( &intVal, tc[0].##coord ); \ \ intVal &= ~1; \ \ tc[0].##coord -= intVal; \ tc[1].##coord -= intVal; \ tc[2].##coord -= intVal; \ \ FLUSH_DUE_TO_WRAP( coord, TRUE ); \ } #endif
#define TEX_SHIFT_LIMIT 4.0
#define TEXTURE_SHIFT( coord ) \
if((tc[0].##coord > TEX_SHIFT_LIMIT ) || \ (tc[0].##coord < -TEX_SHIFT_LIMIT ) ) \ { \ myFtoi( &intVal, tc[0].##coord ); \ \ intVal &= ~1; \ \ tc[0].##coord -= intVal; \ tc[1].##coord -= intVal; \ tc[2].##coord -= intVal; \ \ FLUSH_DUE_TO_WRAP( coord, TRUE ); \ }
#define WRAP_R3(par, wrapit, vertexSharing) if(wrapit) { \
float elp; \ float erp; \ float emp; \ elp=(float)myFabs(tc[1].##par-tc[0].##par); \ erp=(float)myFabs(tc[2].##par-tc[1].##par); \ emp=(float)myFabs(tc[0].##par-tc[2].##par); \ if( (elp > 0.5f) && (erp > 0.5f) ) \ { \ if (tc[1].##par < tc[2].##par) { tc[1].##par += 1.0f; } \ else { tc[2].##par += 1.0f; tc[0].##par += 1.0f; } \ FLUSH_DUE_TO_WRAP(par,vertexSharing); \ } \ else if( (erp > 0.5f) && (emp > 0.5f) ) \ { \ if (tc[2].##par < tc[0].##par) { tc[2].##par += 1.0f; } \ else { tc[0].##par += 1.0f; tc[1].##par += 1.0f; } \ FLUSH_DUE_TO_WRAP(par,vertexSharing); \ } \ else if( (emp > 0.5f) && (elp > 0.5f) ) \ { \ if(tc[0].##par < tc[1].##par) { tc[0].##par += 1.0f; } \ else { tc[1].##par += 1.0f; tc[2].##par += 1.0f; } \ FLUSH_DUE_TO_WRAP(par,vertexSharing); \ } \ else \ { \ DONT_FLUSH_DUE_TO_WRAP(par,vertexSharing); \ } \ } else { \ DONT_FLUSH_DUE_TO_WRAP(par,vertexSharing); \ } //-----------------------------------------------------------------------------
//
// __TextureShift
//
//-----------------------------------------------------------------------------
void __TextureShift( P3_D3DCONTEXT *pContext, TEXCOORDS tc[], DWORD shiftMask ) { int intVal;
if( shiftMask & SHIFT_SET_0 ) { if( pContext->TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] != D3DTADDRESS_CLAMP ) { TEXTURE_SHIFT( tu1 ); }
if( pContext->TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] != D3DTADDRESS_CLAMP ) { TEXTURE_SHIFT( tv1 ); } }
if( shiftMask & SHIFT_SET_1 ) { if( pContext->TextureStageState[1].m_dwVal[D3DTSS_ADDRESSU] != D3DTADDRESS_CLAMP ) { TEXTURE_SHIFT( tu2 ); }
if( pContext->TextureStageState[1].m_dwVal[D3DTSS_ADDRESSV] != D3DTADDRESS_CLAMP ) { TEXTURE_SHIFT( tv2 ); } } } // __TextureShift
#endif //TEXSHIFT
//-----------------------------------------------------------------------------
//
// __BackfaceCullNoTexture
//
//-----------------------------------------------------------------------------
int _inline __BackfaceCullNoTexture( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[] ) { DWORD Flags = pContext->Flags; float PixelArea;
PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) - ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
if (CULLED(pContext,PixelArea)) { return 1; } pContext->R3flushDueToTexCoordAdjust = 0;
return 0; } // __BackfaceCullNoTexture
//-----------------------------------------------------------------------------
//
// __BackfaceCullSingleTex
//
//-----------------------------------------------------------------------------
int _inline __BackfaceCullSingleTex( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], TEXCOORDS tc[] ) { DWORD Flags = pContext->Flags; float PixelArea;
PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) - ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
if (CULLED(pContext,PixelArea)) { return 1; }
pContext->R3flushDueToTexCoordAdjust = 0;
#if TEXSHIFT
__TextureShift( pContext, tc, SHIFT_SET_0 ); #endif
return 0; } // __BackfaceCullSingleTex
//-----------------------------------------------------------------------------
//
// __BackfaceCullAndMipMap
//
//-----------------------------------------------------------------------------
int _inline __BackfaceCullAndMipMap( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], TEXCOORDS tc[] ) { DWORD Flags = pContext->Flags; float PixelArea; int iNewMipLevel; P3_SURF_INTERNAL* pTexture; P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
P3_DMA_DEFS();
PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) - ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
if (CULLED(pContext,PixelArea)) { return 1; }
// 39 for vertex data, 2 for triangle and 4 for possible LOD change
// for the three vertex case - the one vertex case will check for
// too much but this shouldn't be a problem.
P3_DMA_GET_BUFFER_ENTRIES( 4 );
pContext->R3flushDueToTexCoordAdjust = 0;
if( Flags & SURFACE_TEXTURING ) { float TextureArea, textureAreaFactor; int maxLevel;
pTexture = pContext->pCurrentTexture[TEXSTAGE_0];
// Setup LOD of texture # 0 (if necessary)
if( pContext->bTex0Valid && ( pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MIPFILTER] != D3DTFP_NONE ) && pTexture->bMipMap ) { maxLevel = pTexture->iMipLevels - 1; textureAreaFactor = pTexture->fArea * pContext->MipMapLODBias[TEXSTAGE_0];
TextureArea = (((tc[0].tu1 - tc[2].tu1) * (tc[1].tv1 - tc[2].tv1)) - ((tc[1].tu1 - tc[2].tu1) * (tc[0].tv1 - tc[2].tv1))) * textureAreaFactor;
// Ensure that both of these values are positive from now on.
*(signed long *)&PixelArea &= ~(1 << 31); *(signed long *)&TextureArea &= ~(1 << 31);
FIND_PERMEDIA_MIPLEVEL();
DISPDBG((DBGLVL,"iNewMipLevel = %x",iNewMipLevel));
SEND_P3_DATA( LOD, iNewMipLevel << 8 ); }
pTexture = pContext->pCurrentTexture[TEXSTAGE_1];
// Setup LOD of texture # 1 (if necessary)
if( pContext->bTex1Valid && ( pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MIPFILTER] != D3DTFP_NONE ) && pTexture->bMipMap ) { ASSERTDD( pContext->bTex0Valid, "Second texture valid when first isn't" );
maxLevel = pTexture->iMipLevels - 1; textureAreaFactor = pTexture->fArea * pContext->MipMapLODBias[TEXSTAGE_1];
TextureArea = (((tc[0].tu2 - tc[2].tu2) * (tc[1].tv2 - tc[2].tv2)) - ((tc[1].tu2 - tc[2].tu2) * (tc[0].tv2 - tc[2].tv2))) * textureAreaFactor;
// Ensure that both of these values are positive from now on.
*(signed long *)&PixelArea &= ~(1 << 31); *(signed long *)&TextureArea &= ~(1 << 31);
FIND_PERMEDIA_MIPLEVEL();
SEND_P3_DATA( LOD1, iNewMipLevel << 8 ); }
if( pContext->RenderStates[D3DRENDERSTATE_WRAP0] ) { WRAP_R3( tu1, pContext->RenderStates[D3DRENDERSTATE_WRAP0] & D3DWRAP_U, TRUE ); WRAP_R3( tv1, pContext->RenderStates[D3DRENDERSTATE_WRAP0] & D3DWRAP_V, TRUE ); } else { #if TEXSHIFT
__TextureShift( pContext, tc, SHIFT_SET_0 ); #endif
}
if( pContext->RenderStates[D3DRENDERSTATE_WRAP1] ) { WRAP_R3( tu2, pContext->RenderStates[D3DRENDERSTATE_WRAP1] & D3DWRAP_U, TRUE ); WRAP_R3( tv2, pContext->RenderStates[D3DRENDERSTATE_WRAP1] & D3DWRAP_V, TRUE ); } else { #if TEXSHIFT
__TextureShift( pContext, tc, SHIFT_SET_1 ); #endif
} }
P3_DMA_COMMIT_BUFFER();
return 0; } // __BackfaceCullAndMipMap
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_NoTexture
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_NoTexture( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; ULONG renderCmd = pContext->RenderCommand;
P3_DMA_DEFS();
#if CULL_HERE
if( __BackfaceCullNoTexture( pContext, pv )) return 1; #endif
P3_DMA_GET_BUFFER_ENTRIES( 9 );
if( pContext->Flags & SURFACE_GOURAUD ) { // 9 DWORDS.
SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx); } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_FOGENABLE ) { // 8 DWORDS.
SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag + (vtx*16), vtx); } else { // 7 DWORDS.
SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag + (vtx*16), vtx); }
// 2 DWORDS.
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
RENDER_TRAPEZOID(renderCmd);
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return 0; } // __ProcessTri_1Vtx_NoTexture
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_NoTexture
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_NoTexture( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; ULONG renderCmd = pContext->RenderCommand;
P3_DMA_DEFS();
#if CULL_HERE
if( __BackfaceCullNoTexture( pContext, pv )) return 1; #endif
P3_DMA_GET_BUFFER_ENTRIES( 20 );
if( pContext->Flags & SURFACE_GOURAUD ) { SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V2FloatS_Tag, 2); } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_FOGENABLE ) { SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_FOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_FOG(V2FloatS_Tag, 2); } else { SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ(V2FloatS_Tag, 2); }
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
RENDER_TRAPEZOID(renderCmd);
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return 0; } // __ProcessTri_3Vtx_NoTexture
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_PerspSingleTexGouraud
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_PerspSingleTexGouraud( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; TEXCOORDS tc[3]; DWORD q[3]; ULONG renderCmd = pContext->RenderCommand; #if DX8_3DTEXTURES
P3_SURF_INTERNAL* pTexture = pContext->pCurrentTexture[TEXSTAGE_0]; BOOL b3DTexture = (pTexture ? pTexture->b3DTexture : FALSE); #endif // DX8_3DTEXTURES
P3_DMA_DEFS();
// We need to refresh all texture coords as they will have been modified
// by the scale by Q and potentially D3D wrapping or TextureShift.
#if DX8_3DTEXTURES
if (b3DTexture) { GET_TC_3DTEX(0); GET_TC_3DTEX(1); GET_TC_3DTEX(2); } else { GET_TC(0); GET_TC(1); GET_TC(2); } #else
GET_TC(0); GET_TC(1); GET_TC(2); #endif // DX8_3DTEXTURES
#if CULL_HERE
if( __BackfaceCullSingleTex( pContext, pv, tc )) return 1; #endif
P3_DMA_GET_BUFFER_ENTRIES( 15 );
q[vtx] = *(DWORD *)&(pv[vtx]->rhw);
#if DX8_3DTEXTURES
if (b3DTexture) { SCALE_BY_Q_3DTEX( vtx ); } else { SCALE_BY_Q( vtx ); } #else
SCALE_BY_Q( vtx ); #endif // DX8_3DTEXTURES
#if DX8_3DTEXTURES
if (b3DTexture) { SEND_R3FVFVERTEX_3DTEX(V0FloatS1_Tag + (vtx*16), vtx); } #endif // DX8_3DTEXTURES
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx);
RENDER_TRAPEZOID(renderCmd);
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return pContext->R3flushDueToTexCoordAdjust; } // __ProcessTri_1Vtx_PerspSingleTexGouraud
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_PerspSingleTexGouraud
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_PerspSingleTexGouraud( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; TEXCOORDS tc[3]; DWORD q[3]; int forcedQ = 0; ULONG renderCmd = pContext->RenderCommand; #if DX8_3DTEXTURES
P3_SURF_INTERNAL* pTexture = pContext->pCurrentTexture[TEXSTAGE_0]; BOOL b3DTexture = (pTexture ? pTexture->b3DTexture : FALSE); #endif // DX8_3DTEXTURES
P3_DMA_DEFS();
#if DX8_3DTEXTURES
if (b3DTexture) { GET_TC_3DTEX(0); GET_TC_3DTEX(1); GET_TC_3DTEX(2); } else { GET_TC(0); GET_TC(1); GET_TC(2); } #else
GET_TC(0); GET_TC(1); GET_TC(2); #endif // DX8_3DTEXTURES
#if CULL_HERE
if( __BackfaceCullSingleTex( pContext, pv, tc )) return 1; #endif
P3_DMA_GET_BUFFER_ENTRIES( 26 );
q[0] = *(DWORD *)&(pv[0]->rhw); q[1] = *(DWORD *)&(pv[1]->rhw); q[2] = *(DWORD *)&(pv[2]->rhw);
// Check for equal Q's
if((( q[0] ^ q[1] ) | ( q[1] ^ q[2] )) == 0 ) { // Force to 1.0f
forcedQ = q[0] = q[1] = q[2] = 0x3f800000; } else { #if DX8_3DTEXTURES
if (b3DTexture) { SCALE_BY_Q_3DTEX( 0 ); SCALE_BY_Q_3DTEX( 1 ); SCALE_BY_Q_3DTEX( 2 ); } else { SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); SCALE_BY_Q( 2 ); } #else
SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); SCALE_BY_Q( 2 ); #endif // DX8_3DTEXTURES
}
#if DX8_3DTEXTURES
if (b3DTexture) { SEND_R3FVFVERTEX_3DTEX(V0FloatS1_Tag, 0); } #endif // DX8_3DTEXTURES
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0);
#if DX8_3DTEXTURES
if (b3DTexture) { SEND_R3FVFVERTEX_3DTEX(V1FloatS1_Tag, 1); } #endif // DX8_3DTEXTURES
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1);
P3_DMA_COMMIT_BUFFER(); P3_DMA_GET_BUFFER_ENTRIES( 15 ); #if DX8_3DTEXTURES
if (b3DTexture) { SEND_R3FVFVERTEX_3DTEX(V2FloatS1_Tag, 2); } #endif // DX8_3DTEXTURES
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V2FloatS_Tag, 2);
RENDER_TRAPEZOID(renderCmd);
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return ( pContext->R3flushDueToTexCoordAdjust | forcedQ ); } // __ProcessTri_3Vtx_PerspSingleTexGouraud
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_Generic
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_Generic( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; TEXCOORDS tc[3]; DWORD q[3]; ULONG renderCmd = pContext->RenderCommand;
P3_DMA_DEFS();
// We need to refresh all texture coords as they will have been modified
// by the scale by Q and potentially D3D wrapping or TextureShift.
GET_TEXCOORDS();
if( __BackfaceCullAndMipMap( pContext, pv, tc )) return 1;
if( Flags & SURFACE_PERSPCORRECT ) { q[vtx] = *(DWORD *)&(pv[vtx]->rhw); SCALE_BY_Q( vtx ); }
// Send vertex data including check for flat shading
P3_DMA_GET_BUFFER_ENTRIES( 16 );
if( pContext->Flags & SURFACE_GOURAUD ) { // 9 DWORDS.
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx); } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_FOGENABLE ) { // 8 DWORDS.
SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag + (vtx*16), vtx); } else { // 7 DWORDS.
SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag + (vtx*16), vtx); }
// 2 DWORDS.
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
// Send the second set of texture coordinates including scale-by-q
if( pContext->iTexStage[1] != -1 && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1])) { DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
if( Flags & SURFACE_PERSPCORRECT ) { SCALE_BY_Q2( vtx ); }
// 4 DWORDS.
SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag + (vtx*16), vtx); }
RENDER_TRAPEZOID(renderCmd);
// 2 DWORDS.
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return pContext->R3flushDueToTexCoordAdjust; } // __ProcessTri_1Vtx_Generic
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_Generic
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_Generic( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; TEXCOORDS tc[3]; DWORD q[3]; int forcedQ = 0; ULONG renderCmd = pContext->RenderCommand;
P3_DMA_DEFS();
GET_TEXCOORDS();
if( __BackfaceCullAndMipMap( pContext, pv, tc )) return 1; if( Flags & SURFACE_PERSPCORRECT ) { q[0] = *(DWORD *)&(pv[0]->rhw); q[1] = *(DWORD *)&(pv[1]->rhw); q[2] = *(DWORD *)&(pv[2]->rhw);
// Check for equal Q's
if((( q[0] ^ q[1] ) | ( q[1] ^ q[2] )) == 0 ) { // Force to 1.0f
forcedQ = q[0] = q[1] = q[2] = 0x3f800000; } else { SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); SCALE_BY_Q( 2 ); } } else { q[0] = q[1] = q[2] = 0x3f800000; }
// Send vertex data including check for flat shading
// Worst case 27 DWORDS
P3_DMA_GET_BUFFER_ENTRIES(29);
if( pContext->Flags & SURFACE_GOURAUD ) { if( Flags & SURFACE_TEXTURING ) { // 9 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V2FloatS_Tag, 2); } else { // 6 DWORDs each.
SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V2FloatS_Tag, 2); } } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_TEXTURING ) { if( Flags & SURFACE_FOGENABLE ) { // 8 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_STQ_FOG(V2FloatS_Tag, 2); } else { // 7 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_STQ(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_STQ(V2FloatS_Tag, 2); } } else { if( Flags & SURFACE_FOGENABLE ) { // 5 DWORDs each.
SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_FOG(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ_FOG(V2FloatS_Tag, 2); } else { // 4 DWORDs each.
SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ(V1FloatS_Tag, 1); SEND_R3FVFVERTEX_XYZ(V2FloatS_Tag, 2); } }
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
// Send the second set of texture coordinates including scale-by-q
if( pContext->iTexStage[1] != -1 && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1])) { DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
if( Flags & SURFACE_PERSPCORRECT ) { SCALE_BY_Q2( 0 ); SCALE_BY_Q2( 1 ); SCALE_BY_Q2( 2 ); }
// 12 DWORDS
P3_DMA_COMMIT_BUFFER(); P3_DMA_GET_BUFFER_ENTRIES(14); // 4 DWORDs each.
SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, 0); SEND_R3FVFVERTEX_STQ2(V1FloatS1_Tag, 1); SEND_R3FVFVERTEX_STQ2(V2FloatS1_Tag, 2); }
RENDER_TRAPEZOID(renderCmd);
DRAW_TRIANGLE();
P3_DMA_COMMIT_BUFFER();
return ( pContext->R3flushDueToTexCoordAdjust | forcedQ ); } // __ProcessTri_3Vtx_Generic
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_Wire
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_Wire( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_Wire")); return 1; } // __ProcessTri_1Vtx_Wire
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_Wire
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_Wire( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; TEXCOORDS tc[3]; int i; DWORD q[3]; ULONG renderCmd = pContext->RenderCommand; const int edges[] = { SIDE_0, SIDE_1, SIDE_2 };
P3_DMA_DEFS();
GET_TEXCOORDS();
if( __BackfaceCullAndMipMap( pContext, pv, tc )) return 1;
RENDER_LINE(renderCmd);
if( Flags & SURFACE_PERSPCORRECT ) { q[0] = *(DWORD *)&(pv[0]->rhw); q[1] = *(DWORD *)&(pv[1]->rhw); q[2] = *(DWORD *)&(pv[2]->rhw);
SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); SCALE_BY_Q( 2 );
if(pContext->iTexStage[1] != -1 ) { SCALE_BY_Q2( 0 ); SCALE_BY_Q2( 1 ); SCALE_BY_Q2( 2 ); } }
// Send vertex data including check for flat shading
for( i = 0; i < 3; i++ ) { int v0, v1;
v0 = i; v1 = i + 1;
if( v1 == 3 ) v1 = 0;
if( WireEdgeFlags & edges[i] ) { P3_DMA_GET_BUFFER_ENTRIES(30); if( pContext->Flags & SURFACE_GOURAUD ) { // 9 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, v0); SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, v1); } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_FOGENABLE ) { // 6 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, v0); SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, v1); } else { // 7 DWORDs each.
SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, v0); SEND_R3FVFVERTEX_XYZ_STQ(V1FloatS_Tag, v1); }
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
// Send the second set of texture coordinates
if( pContext->iTexStage[1] != -1 && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1] )) { // 4 DWORDs each.
SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, v0); SEND_R3FVFVERTEX_STQ2(V1FloatS1_Tag, v1); }
DRAW_LINE();
P3_DMA_COMMIT_BUFFER(); } }
return 1; } // __ProcessTri_3Vtx_Wire
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_Point
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_Point( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_Wire")); return 1; } // __ProcessTri_1Vtx_Point
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_Point
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_Point( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags ) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; TEXCOORDS tc[3]; int i; DWORD q[3]; ULONG renderCmd = pContext->RenderCommand; const int edges[] = { SIDE_0, SIDE_1, SIDE_2 };
P3_DMA_DEFS();
GET_TEXCOORDS();
if( __BackfaceCullAndMipMap( pContext, pv, tc )) return 1;
RENDER_POINT(renderCmd);
if( Flags & SURFACE_PERSPCORRECT ) { q[0] = *(DWORD *)&(pv[0]->rhw); q[1] = *(DWORD *)&(pv[1]->rhw); q[2] = *(DWORD *)&(pv[2]->rhw);
SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); SCALE_BY_Q( 2 );
if(pContext->iTexStage[1] != -1) { SCALE_BY_Q2( 0 ); SCALE_BY_Q2( 1 ); SCALE_BY_Q2( 2 ); } }
// Send vertex data including check for flat shading
for( i = 0; i < 3; i++ ) { int v0, v1;
v0 = i; v1 = i + 1;
if( v1 == 3 ) v1 = 0;
if( WireEdgeFlags & edges[i] ) { P3_DMA_GET_BUFFER_ENTRIES( 16 ); if( pContext->Flags & SURFACE_GOURAUD ) { SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, v0); } else { DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
if( Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
CLAMP8888( Col0, Col0, Spec0 ); }
if( Flags & SURFACE_FOGENABLE ) { SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, v0); } else { SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, v0); }
SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
// Send the second set of texture coordinates
if( pContext->iTexStage[1] != -1 && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1])) { DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, v0); }
DRAW_POINT();
P3_DMA_COMMIT_BUFFER(); } }
return 1; } // __ProcessTri_3Vtx_Point
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_TriangleList
//
// Render D3DDP2OP_TRIANGLELIST triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_TriangleList( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex, i; D3DTLVERTEX *pv[3];
DBG_ENTRY(_D3D_R3_DP2_TriangleList);
dwIndex = ((D3DHAL_DP2TRIANGLELIST*)lpPrim)->wVStart;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); pv[1] = LP_FVF_NXT_VTX(pv[0]); pv[2] = LP_FVF_NXT_VTX(pv[1]);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + 3*dwPrimCount - 1);
pContext->dwProvokingVertex = 0; for( i = 0; i < dwPrimCount; i++ ) { pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
pv[0] = LP_FVF_NXT_VTX(pv[2]); pv[1] = LP_FVF_NXT_VTX(pv[0]); pv[2] = LP_FVF_NXT_VTX(pv[1]); }
DBG_EXIT(_D3D_R3_DP2_TriangleList,0); } // _D3D_R3_DP2_TriangleList
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_TriangleFan
//
// Render a D3DDP2OP_TRIANGLEFAN triangle
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_TriangleFan( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex, i; D3DTLVERTEX *pv[3]; int vtx, lastVtx, bCulled; SAVE_CULLING_STATE(pContext); DBG_ENTRY(_D3D_R3_DP2_TriangleFan);
lastVtx = vtx = 2;
dwIndex = ((D3DHAL_DP2TRIANGLEFAN*)lpPrim)->wVStart;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); pv[1] = LP_FVF_NXT_VTX(pv[0]); pv[2] = LP_FVF_NXT_VTX(pv[1]);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + dwPrimCount + 1);
pContext->dwProvokingVertex = 1; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
for( i = 1; i < dwPrimCount; i++ ) { vtx ^= 3; // 2 -> 1, 1 -> 2
FLIP_CCW_CW_CULLING(pContext);
pv[vtx] = LP_FVF_NXT_VTX(pv[lastVtx]); pContext->dwProvokingVertex = lastVtx; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; if( bCulled ) bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); else bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
lastVtx = vtx; }
RESTORE_CULLING_STATE(pContext);
DBG_EXIT(_D3D_R3_DP2_TriangleFan,0); } // _D3D_R3_DP2_TriangleFan
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_TriangleFanImm
//
// Render D3DDP2OP_TRIANGLEFAN_IMM triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_TriangleFanImm( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[3]; DWORD i, dwEdgeFlags, eFlags; int vtx, lastVtx, bCulled; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_TriangleFanImm);
lastVtx = vtx = 2;
// Edge flags are used for wireframe fillmode
dwEdgeFlags = ((D3DHAL_DP2TRIANGLEFAN_IMM *)lpPrim)->dwEdgeFlags; lpPrim += sizeof(D3DHAL_DP2TRIANGLEFAN_IMM);
// Vertices in an IMM instruction are stored in the
// command buffer and are DWORD aligned
lpPrim = (LPBYTE)((ULONG_PTR)( lpPrim + 3 ) & ~3 );
pv[0] = (LPD3DTLVERTEX)lpPrim; pv[1] = LP_FVF_NXT_VTX(pv[0]); pv[2] = LP_FVF_NXT_VTX(pv[1]);
// since data is in the command buffer, we've already verified it as valid
// Build up edge flags for the next single primitive
eFlags = ( dwEdgeFlags & 1 ) ? SIDE_0 : 0; eFlags |= ( dwEdgeFlags & 2 ) ? SIDE_1 : 0; dwEdgeFlags >>= 2;
pContext->dwProvokingVertex = 1; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; bCulled = (*pContext->pRendTri_3V)( pContext, pv, eFlags);
for( i = 1; i < dwPrimCount; i++ ) { // 2 -> 1, 1 -> 2
vtx ^= 3; FLIP_CCW_CW_CULLING(pContext); pv[vtx] = LP_FVF_NXT_VTX(pv[lastVtx]);
if( i == ( dwPrimCount - 1 )) { eFlags = ( dwEdgeFlags & 1 ) ? SIDE_1 : 0; eFlags |= ( dwEdgeFlags & 2 ) ? SIDE_2 : 0; } else { eFlags = ( dwEdgeFlags & 1 ) ? SIDE_1 : 0; dwEdgeFlags >>= 1; } pContext->dwProvokingVertex = lastVtx; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; if( bCulled ) bCulled = (*pContext->pRendTri_3V)( pContext, pv, eFlags); else bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
lastVtx = vtx; }
RESTORE_CULLING_STATE(pContext);
DBG_EXIT(_D3D_R3_DP2_TriangleFanImm,0); } // _D3D_R3_DP2_TriangleFanImm
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_TriangleStrip
//
// Render D3DDP2OP_TRIANGLESTRIP triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_TriangleStrip( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex, i; D3DTLVERTEX *pv[3]; int vtx_a, vtx_b, lastVtx, bCulled; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_TriangleStrip);
dwIndex = ((D3DHAL_DP2TRIANGLEFAN*)lpPrim)->wVStart;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); pv[1] = LP_FVF_NXT_VTX(pv[0]); pv[2] = LP_FVF_NXT_VTX(pv[1]);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + dwPrimCount + 1);
pContext->dwProvokingVertex = 0; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
lastVtx = 2; INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
for( i = 1; i < dwPrimCount; i++ ) { FLIP_CCW_CW_CULLING(pContext); pv[vtx_a] = LP_FVF_NXT_VTX(pv[lastVtx]);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
if( bCulled ) bCulled = (*pContext->pRendTri_3V)( pContext, pv,ALL_SIDES); else bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx_a );
lastVtx = vtx_a; CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b); }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_TriangleStrip,0); } // _D3D_R3_DP2_TriangleStrip
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleStrip
//
// Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleStrip( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; WORD wVStart; D3DTLVERTEX *pv[3]; int vtx_a, vtx_b, bCulled; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip);
wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[0]; dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[1]; dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
pContext->dwProvokingVertex = 0; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); lpPrim += sizeof(WORD);
INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
for( i = 1; i < dwPrimCount; i++ ) { FLIP_CCW_CW_CULLING(pContext); dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2]; pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
if( bCulled ) bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); else bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx_a );
lpPrim += sizeof(WORD);
CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b); }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip,0); } // _D3D_R3_DP2_IndexedTriangleStrip
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleFan
//
// Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleFan( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; WORD wVStart; D3DTLVERTEX *pv[3]; int vtx, lastVtx, bCulled; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan);
wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[0]; dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[1]; dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
lastVtx = vtx = 2; pv[0] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex2);
pContext->dwProvokingVertex = 1; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); lpPrim += sizeof(WORD);
for( i = 1; i < dwPrimCount; i++ ) { // 2 -> 1, 1 -> 2
vtx ^= 3; FLIP_CCW_CW_CULLING(pContext); dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2]; pv[vtx] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex2); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwIndex2);
pContext->dwProvokingVertex = lastVtx; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; if( bCulled ) bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); else bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
lastVtx = vtx; lpPrim += sizeof(WORD); }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan,0); } // _D3D_R3_DP2_IndexedTriangleFan
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleList
//
// Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleList( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i, primData; WORD wFlags; D3DTLVERTEX *pv[3];
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList);
pContext->dwProvokingVertex = 0; for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV1; dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV2; dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV3; wFlags = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wFlags;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
lpPrim += sizeof(D3DHAL_DP2INDEXEDTRIANGLELIST);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
(*pContext->pRendTri_3V)( pContext, pv, wFlags); }
DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList,0); } // _D3D_R3_DP2_IndexedTriangleList
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleList2
//
// Render D3DDP2OP_INDEXEDTRIANGLELIST2 triangles
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleList2( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; WORD wVStart; D3DTLVERTEX *pv[3];
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList2); wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
pContext->dwProvokingVertex = 0; for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV1; dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV2; dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV3;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex2);
lpPrim += sizeof(D3DHAL_DP2INDEXEDTRIANGLELIST2);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
(*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); }
DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList2,0); } // _D3D_R3_DP2_IndexedTriangleList2
//-----------------------------------------------------------------------------
//
// __ProcessLine
//
// Render a single line
//
//-----------------------------------------------------------------------------
void __ProcessLine( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], D3DTLVERTEX *pProvokingVtx) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; TEXCOORDS tc[2]; DWORD q[2]; ULONG renderCmd = pContext->RenderCommand;
P3_DMA_DEFS();
RENDER_LINE(renderCmd);
GET_TC(0); GET_TC(1);
P3_DMA_GET_BUFFER_ENTRIES(22);
if (pContext->RenderStates[D3DRENDERSTATE_LINEPATTERN]) { // if we are line stippling then reset rendering for each line
SEND_P3_DATA( UpdateLineStippleCounters , 0); }
if( Flags & SURFACE_PERSPCORRECT ) { q[0] = *(DWORD *)&(pv[0]->rhw); q[1] = *(DWORD *)&(pv[1]->rhw);
SCALE_BY_Q( 0 ); SCALE_BY_Q( 1 ); } else { q[0] = q[1] = 0; }
if (Flags & SURFACE_GOURAUD) { SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1); } else { DWORD Col0 = FVFCOLOR(pProvokingVtx)->color; SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, 0); SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, 1);
if( pContext->Flags & SURFACE_SPECULAR ) { DWORD Spec0 = GET_SPEC( FVFSPEC(pProvokingVtx)->specular ); CLAMP8888( Col0, Col0, Spec0 ); } SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0), RGBA_GETGREEN(Col0), RGBA_GETRED(Col0), RGBA_GETALPHA(Col0))); }
DRAW_LINE();
P3_DMA_COMMIT_BUFFER(); } // __ProcessLine
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_LineList
//
// Render D3DDP2OP_LINELIST lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_LineList( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; WORD wVStart; DWORD i; DBG_ENTRY(_D3D_R3_DP2_LineList);
wVStart = ((D3DHAL_DP2LINELIST*)lpPrim)->wVStart;
pv[0] = LP_FVF_VERTEX(lpVertices, wVStart); pv[1] = LP_FVF_NXT_VTX(pv[0]);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (LONG)wVStart + 2*dwPrimCount - 1)
for( i = 0; i < dwPrimCount; i++ ) { __ProcessLine(pContext, pv, pv[0]);
pv[0] = LP_FVF_NXT_VTX(pv[1]); pv[1] = LP_FVF_NXT_VTX(pv[0]); }
DBG_EXIT(_D3D_R3_DP2_LineList,0); } // _D3D_R3_DP2_LineList
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_LineListImm
//
// Render D3DDP2OP_LINELIST_IMM lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_LineListImm( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD i;
DBG_ENTRY(_D3D_R3_DP2_LineListImm);
pv[0] = (LPD3DTLVERTEX)lpPrim; pv[1] = LP_FVF_NXT_VTX(pv[0]); // since data is in the command buffer, we've already verified it as valid
for( i = 0; i < dwPrimCount; i++ ) { __ProcessLine(pContext, pv, pv[0]);
pv[0] = LP_FVF_NXT_VTX(pv[1]); pv[1] = LP_FVF_NXT_VTX(pv[0]); }
DBG_EXIT(_D3D_R3_DP2_LineListImm,0); } // _D3D_R3_DP2_LineListImm
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_LineStrip
//
// Render D3DDP2OP_LINESTRIP lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_LineStrip( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; WORD wVStart; DWORD i;
DBG_ENTRY(_D3D_R3_DP2_LineStrip);
wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; pv[0] = LP_FVF_VERTEX(lpVertices, wVStart); pv[1] = LP_FVF_NXT_VTX(pv[0]);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount);
for( i = 0; i < dwPrimCount; i++ ) { __ProcessLine(pContext, pv, pv[0]);
pv[0] = pv[1]; pv[1] = LP_FVF_NXT_VTX(pv[1]); }
DBG_EXIT(_D3D_R3_DP2_LineStrip,0); } // _D3D_R3_DP2_LineStrip
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineList
//
// Render D3DDP2OP_INDEXEDLINELIST lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineList( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD primData, dwIndex0, dwIndex1, i;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineList); for( i = 0; i < dwPrimCount; i++ ) { primData = *(DWORD *)lpPrim; dwIndex0 = ( primData >> 0 ) & 0xffff; dwIndex1 = ( primData >> 16 );
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1);
lpPrim += sizeof(D3DHAL_DP2INDEXEDLINELIST);
__ProcessLine(pContext, pv, pv[0]); }
DBG_EXIT(_D3D_R3_DP2_IndexedLineList,0); } // _D3D_R3_DP2_IndexedLineList
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineList2
//
// Render D3DDP2OP_INDEXEDLINELIST2 lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineList2( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD primData, i; WORD wVStart, dwIndex0, dwIndex1;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineList2);
wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
for( i = 0; i < dwPrimCount; i++ ) { primData = *(DWORD *)lpPrim; dwIndex0 = ( (WORD)(primData >> 0) ) & 0xffff; dwIndex1 = ( (WORD)(primData >> 16) );
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0 + wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1 + wVStart);
lpPrim += sizeof(D3DHAL_DP2INDEXEDLINELIST);
__ProcessLine(pContext, pv, pv[0]); }
DBG_EXIT(_D3D_R3_DP2_IndexedLineList2,0); } // _D3D_R3_DP2_IndexedLineList2
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineStrip
//
// Render D3DDP2OP_INDEXEDLINESTRIP lines
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineStrip( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; WORD wVStart, dwIndex, *pwIndx; DWORD i;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip);
wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart; lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
lpPrim += sizeof(D3DHAL_DP2STARTVERTEX); pwIndx = (WORD *)lpPrim;
dwIndex = *pwIndx++; pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
for( i = 0; i < dwPrimCount; i++ ) { dwIndex = *pwIndx++; pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
__ProcessLine(pContext, pv, pv[0]);
pv[0] = pv[1]; } DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip,0); } // _D3D_R3_DP2_IndexedLineStrip
//-----------------------------------------------------------------------------
//
// __ProcessPoints
//
// Render a set points specified by adjacent FVF vertices
//
//-----------------------------------------------------------------------------
void __ProcessPoints( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], DWORD dwCount) { P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay; DWORD Flags = pContext->Flags; DWORD q[1]; TEXCOORDS tc[1]; ULONG renderCmd = pContext->RenderCommand; DWORD j; D3DTLVERTEX *ptmpV;
P3_DMA_DEFS();
ptmpV = pv[0]; RENDER_LINE(renderCmd);
q[0] = 0; for( j = 0; j < dwCount; j++ ) { P3_DMA_GET_BUFFER_ENTRIES( 20 );
GET_TC(0);
if( Flags & SURFACE_PERSPCORRECT ) { q[0] = *(DWORD *)&(pv[0]->rhw);
SCALE_BY_Q( 0 ); }
SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(V0FloatS_Tag, 0, FALSE); SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(V1FloatS_Tag, 0, TRUE);
DRAW_LINE();
P3_DMA_COMMIT_BUFFER(); pv[0] = LP_FVF_NXT_VTX(pv[0]); }
pv[0] = ptmpV;
} // __ProcessPoints
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_Points
//
// Render D3DDP2OP_POINTS points
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_Points( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[1]; WORD wVStart, wCount; DWORD i;
DBG_ENTRY(_D3D_R3_DP2_Points);
for( i = 0; i < dwPrimCount; i++ ) { wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart; wCount = ((D3DHAL_DP2POINTS*)lpPrim)->wCount; lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + wCount - 1);
pv[0] = LP_FVF_VERTEX(lpVertices, 0); __ProcessPoints(pContext, pv, wCount);
lpPrim += sizeof(D3DHAL_DP2POINTS); }
DBG_EXIT(_D3D_R3_DP2_Points,0);
} // _D3D_R3_DP2_Points
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_Points_DWCount
//
// Render D3DDP2OP_POINTS points for DX8 case
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_Points_DWCount( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[1]; WORD wVStart; DWORD i;
DBG_ENTRY(_D3D_R3_DP2_Points_DWCount);
wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart; lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount - 1);
pv[0] = LP_FVF_VERTEX(lpVertices, 0); __ProcessPoints(pContext, pv, dwPrimCount);
DBG_EXIT(_D3D_R3_DP2_Points_DWCount,0);
} // _D3D_R3_DP2_Points_DWCount
#if DX8_POINTSPRITES
#define SPRITETEXCOORDMAX 1.0f
//Size of maximum FVF that we can get. Used for temporary storage
typedef BYTE P3FVFMAXVERTEX[ 3 * sizeof( D3DVALUE ) + // Position coordinates
5 * 4 + // D3DFVF_XYZB5
sizeof( D3DVALUE ) + // FVF_TRANSFORMED
3 * sizeof( D3DVALUE ) + // Normals
sizeof( DWORD ) + // RESERVED1
sizeof( DWORD ) + // Diffuse color
sizeof( D3DCOLOR ) + // Specular color
sizeof( D3DVALUE ) + // Point sprite size
4 * 8 * sizeof( D3DVALUE ) // 8 sets of 4D texture coordinates
];
//-----------------------------------------------------------------------------
//
// __Render_One_PointSprite
//
// Render a point sprite with FVF vertexes when the point sprite enable is on
//
// Note: this is not the most optimized implementation possible for
// pointprites on this hw. We are merely following the definition.
// Later implementation will be optimized.
//-----------------------------------------------------------------------------
void __Render_One_PointSprite( P3_D3DCONTEXT *pContext, D3DTLVERTEX *lpVertex) { // notice these are BYTE[], so its not necessary to write &fvfVUL to
// get the address of fvfVUL (just write fvfVUL)
P3FVFMAXVERTEX fvfVUL, fvfVUR, fvfVLL, fvfVLR ;
D3DVALUE fPntSize, fPntSizeHalf, fD2, fD, fScalePntSize, fFac; D3DTLVERTEX *pv[3]; FVFOFFSETS OrigFVF; BOOL bTexturingWOTexCoords = FALSE; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(__Render_One_PointSprite);
// Get point sprite size , if FVF data comes with it, grab it from there
if (pContext->FVFData.dwPntSizeOffset) { fPntSize = FVFPSIZE(lpVertex)->psize; DISPDBG((DBGLVL,"FVF Data fPntSize = %d",(LONG)(fPntSize*1000.0f) )); } else { fPntSize = pContext->PntSprite.fSize; DISPDBG((DBGLVL,"RS fPntSize = %d",(LONG)(fPntSize*1000.0f) )); }
// We don't need to compute the point size according to the scale
// factors and viewport size, etc as we are not a TnL driver.
// See the spec for deatils
// Clamp fPntSize to limits defined by the driver caps (dvMaxPointSize)
// and the D3DRS_POINTSIZE_MIN and D3DRS_POINTSIZE_MAX renderstates
fPntSize = max(pContext->PntSprite.fSizeMin, fPntSize); fPntSize = min( min(pContext->PntSprite.fSizeMax, P3_MAX_POINTSPRITE_SIZE), fPntSize);
// Divide by 2 to get the amount by which to modify vertex coords
fPntSizeHalf = fPntSize * 0.5f;
// Initialize square vertex values
memcpy( fvfVUL, lpVertex, pContext->FVFData.dwStride); memcpy( fvfVUR, lpVertex, pContext->FVFData.dwStride); memcpy( fvfVLL, lpVertex, pContext->FVFData.dwStride); memcpy( fvfVLR, lpVertex, pContext->FVFData.dwStride);
// Make this a square of size fPntSize
((D3DTLVERTEX *)fvfVUL)->sx -= fPntSizeHalf; ((D3DTLVERTEX *)fvfVUL)->sy -= fPntSizeHalf;
((D3DTLVERTEX *)fvfVUR)->sx += fPntSizeHalf; ((D3DTLVERTEX *)fvfVUR)->sy -= fPntSizeHalf;
((D3DTLVERTEX *)fvfVLL)->sx -= fPntSizeHalf; ((D3DTLVERTEX *)fvfVLL)->sy += fPntSizeHalf;
((D3DTLVERTEX *)fvfVLR)->sx += fPntSizeHalf; ((D3DTLVERTEX *)fvfVLR)->sy += fPntSizeHalf;
// This is for the case in which PntSprite.bEnabled is false
// and we are texturing even if we have no tex coord data in
// the pointsprite vertexes
bTexturingWOTexCoords = (pContext->FVFData.dwNonTexStride == pContext->FVFData.dwStride ) && (!pContext->bTexDisabled);
if (pContext->PntSprite.bEnabled || bTexturingWOTexCoords) { // Remember orig FVF offsets in order to fake our own texcoords
OrigFVF = pContext->FVFData; // We "create" new texturing info in our data in order to
// process vertexes even without texturing coord info
// This is OK since we are using P3FVFMAXVERTEX as the type
// of our temporary data structures for each vertex so we
// can't overflow.
// If stage 0 texture is used
pContext->FVFData.dwTexCount = 1; pContext->FVFData.dwTexOffset[0] = pContext->FVFData.dwTexCoordOffset[0] = pContext->FVFData.dwNonTexStride; // If stage 1 texture is used
// we can use the same tex coord set since they are equal
pContext->FVFData.dwTexOffset[1] = pContext->FVFData.dwTexCoordOffset[0];
if (pContext->PntSprite.bEnabled) { // Set up texture coordinates according to spec
FVFTEX(fvfVUL, 0)->tu = 0.0f; FVFTEX(fvfVUL, 0)->tv = 0.0f; FVFTEX(fvfVUR, 0)->tu = SPRITETEXCOORDMAX; FVFTEX(fvfVUR, 0)->tv = 0.0f; FVFTEX(fvfVLL, 0)->tu = 0.0f; FVFTEX(fvfVLL, 0)->tv = SPRITETEXCOORDMAX; FVFTEX(fvfVLR, 0)->tu = SPRITETEXCOORDMAX; FVFTEX(fvfVLR, 0)->tv = SPRITETEXCOORDMAX; } else { // if we got here then PntSprite.bEnabled is false
// so just make the tex coords == (0,0)
FVFTEX(fvfVUL, 0)->tu = 0.0f; FVFTEX(fvfVUL, 0)->tv = 0.0f; FVFTEX(fvfVUR, 0)->tu = 0.0f; FVFTEX(fvfVUR, 0)->tv = 0.0f; FVFTEX(fvfVLL, 0)->tu = 0.0f; FVFTEX(fvfVLL, 0)->tv = 0.0f; FVFTEX(fvfVLR, 0)->tu = 0.0f; FVFTEX(fvfVLR, 0)->tv = 0.0f; }
#if DX8_3DTEXTURES
// Allow for the case of 3D texturing
FVFTEX(fvfVUL, 0)->tw = 0.0f; FVFTEX(fvfVUR, 0)->tw = 0.0f; FVFTEX(fvfVLL, 0)->tw = 0.0f; FVFTEX(fvfVLR, 0)->tw = 0.0f; #endif
}
// Make sure Culling doesn't prevent pointsprites from rendering
SET_CULLING_TO_NONE(pContext); // culling state was previously saved
// here we are going to send the required quad
pv[0] = (D3DTLVERTEX*)fvfVUL; pv[1] = (D3DTLVERTEX*)fvfVUR; pv[2] = (D3DTLVERTEX*)fvfVLL; __ProcessTri_3Vtx_Generic(pContext, pv, ALL_SIDES);
pv[0] = (D3DTLVERTEX*)fvfVLL; pv[1] = (D3DTLVERTEX*)fvfVUR; pv[2] = (D3DTLVERTEX*)fvfVLR; __ProcessTri_3Vtx_Generic(pContext, pv, ALL_SIDES);
// Restore original Culling settings
RESTORE_CULLING_STATE(pContext);
// Restore original FVF offsets
if (pContext->PntSprite.bEnabled || bTexturingWOTexCoords) { pContext->FVFData = OrigFVF; }
DBG_EXIT(__Render_One_PointSprite, 0); } // __Render_One_PointSprite
//-----------------------------------------------------------------------------
//
// __ProcessTri_1Vtx_PointSprite
//
//-----------------------------------------------------------------------------
int __ProcessTri_1Vtx_PointSprite( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int vtx ) { DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_PointSprite")); return 1; } // __ProcessTri_1Vtx_PointSprite
//-----------------------------------------------------------------------------
//
// __ProcessTri_3Vtx_PointSprite
//
//-----------------------------------------------------------------------------
int __ProcessTri_3Vtx_PointSprite( P3_D3DCONTEXT *pContext, D3DTLVERTEX *pv[], int WireEdgeFlags ) { #if CULL_HERE
if( __BackfaceCullNoTexture( pContext, pv )) return 1; #endif
__Render_One_PointSprite(pContext, pv[0]); __Render_One_PointSprite(pContext, pv[1]); __Render_One_PointSprite(pContext, pv[2]);
return 1; } // __ProcessTri_3Vtx_PointSprite
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_PointsSprite_DWCount
//
// Render D3DDP2OP_POINTS points sprites
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_PointsSprite_DWCount( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[1]; WORD wVStart; DWORD j;
DBG_ENTRY(_D3D_R3_DP2_PointsSprite_DWCount);
wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart; lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
// Check first & last vertex
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount - 1);
pContext->dwProvokingVertex = 0; for( j = 0; j < dwPrimCount; j++ ) { pv[0] = LP_FVF_VERTEX(lpVertices, j);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
__Render_One_PointSprite(pContext, pv[0]); }
DBG_EXIT(_D3D_R3_DP2_PointsSprite_DWCount,0);
} // _D3D_R3_DP2_PointsSprite_DWCount
#endif // DX8_POINTSPRITES
#if DX8_MULTSTREAMS
// Macro to render a single triangle depending on the current Fillmode.
// Notice that for proper line rendering we require one more element in pv (4)
#define RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bVtxInvalid, vtx_a)\
{ \ if (dwFillMode == D3DFILL_SOLID) \ { \ if( bVtxInvalid ) \ bVtxInvalid = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); \ else \ bVtxInvalid = (*pContext->pRendTri_1V)( pContext, pv, vtx_a ); \ } \ else if (dwFillMode == D3DFILL_WIREFRAME) \ { \ if(!__BackfaceCullNoTexture( pContext, pv )) \ { \ pv[3] = pv[0]; \ __ProcessLine(pContext, &pv[0], pv[pContext->dwProvokingVertex]);\ __ProcessLine(pContext, &pv[1], pv[pContext->dwProvokingVertex]);\ __ProcessLine(pContext, &pv[2], pv[pContext->dwProvokingVertex]);\ } \ } \ else \ /*#if DX8_POINTSPRITES*/ \ if(IS_POINTSPRITE_ACTIVE(pContext)) \ { \ __ProcessTri_3Vtx_PointSprite( pContext, pv, ALL_SIDES ); \ } \ else \ /*#endif*/ \ { \ if(!__BackfaceCullNoTexture( pContext, pv )) \ { \ __ProcessPoints( pContext, &pv[0], 1); \ __ProcessPoints( pContext, &pv[1], 1); \ __ProcessPoints( pContext, &pv[2], 1); \ } \ } \ }
#define INIT_RENDER_ONE_TRIANGLE(pContext, dwFillMode, pv,VtxInvalid) \
{ \ int vtx_a_local = 0; \ VtxInvalid= 1; \ RENDER_ONE_TRIANGLE_CYCLE(pContext, \ dwFillMode, \ pv, \ VtxInvalid, \ vtx_a_local); \ }
#define RENDER_ONE_TRIANGLE(pContext, dwFillMode, pv) \
{ \ int vtx_a = 0, VtxInvalid= 1; \ RENDER_ONE_TRIANGLE_CYCLE(pContext, \ dwFillMode, \ pv, \ VtxInvalid, \ vtx_a); \ }
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineList_MS_16IND
//
// Render D3DDP2OP_INDEXEDLINELIST lines
// 16 bit index streams are assumed
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineList_MS_16IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; WORD *pwIndx; DWORD dwIndex0, dwIndex1, i;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineList_MS_16IND); pwIndx = (WORD *)lpPrim;
for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = *pwIndx++; dwIndex1 = *pwIndx++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
__ProcessLine( pContext, pv, pv[0]); }
DBG_EXIT(_D3D_R3_DP2_IndexedLineList_MS_16IND,0); } // _D3D_R3_DP2_IndexedLineList_MS_16IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineStrip_MS_16IND
//
// Render D3DDP2OP_INDEXEDLINESTRIP lines
// 16 bit index streams are assumed
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineStrip_MS_16IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD dwIndex, i; WORD *pwIndx;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip_MS_32IND);
pwIndx = (WORD *)lpPrim; dwIndex = *pwIndx++; pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
for( i = 0; i < dwPrimCount; i++ ) { dwIndex = *pwIndx++; pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
__ProcessLine(pContext, pv, pv[0]);
pv[0] = pv[1]; }
DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip_MS_16IND,0); } // _D3D_R3_DP2_IndexedLineStrip_MS_16IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleList_MS_16IND
//
// Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
// 16 bit index streams are assumed
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleList_MS_16IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; D3DTLVERTEX *pv[4]; WORD *pwIndexData; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList_MS_16IND);
DISPDBG((DBGLVL,"pContext = 0x%x dwPrimCount=%d lpPrim=0x%x lpVertices=0x%x " "IdxOffset=%d dwVertexBufferLen=%d ", pContext,(DWORD)dwPrimCount,lpPrim,lpVertices, IdxOffset, dwVertexBufferLen));
pwIndexData = (WORD *)lpPrim;
pContext->dwProvokingVertex = 0; for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = *pwIndexData++; dwIndex1 = *pwIndexData++; dwIndex2 = *pwIndexData++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv); }
DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList_MS_16IND,0); } // _D3D_R3_DP2_IndexedTriangleList_MS_16IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND
//
// Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
// 16 bit index streams are assumed
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; D3DTLVERTEX *pv[4]; int vtx_a, vtx_b, bCulled; WORD *pwIndexData; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE]; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip_MS_16IND);
pwIndexData = (WORD *)lpPrim;
dwIndex0 = *pwIndexData++; dwIndex1 = *pwIndexData++; dwIndex2 = *pwIndexData++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->dwProvokingVertex = 0; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled); lpPrim += sizeof(WORD);
INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
for( i = 1; i < dwPrimCount; i++ ) { FLIP_CCW_CW_CULLING(pContext); dwIndex2 = *pwIndexData++; pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bCulled, vtx_a); CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b); }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip_MS_16IND,0); } // _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleFan_MS_16IND
//
// Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles in
// 16 bit index streams are assumed
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleFan_MS_16IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i; D3DTLVERTEX *pv[4]; int vtx, lastVtx, bCulled; WORD *pwIndexData; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE]; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan_MS_16IND);
pwIndexData = (WORD *)lpPrim; dwIndex0 = *pwIndexData++; dwIndex1 = *pwIndexData++; dwIndex2 = *pwIndexData++;
lastVtx = vtx = 2; pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->dwProvokingVertex = 1; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled); lpPrim += sizeof(WORD);
for( i = 1; i < dwPrimCount; i++ ) { // 2 -> 1, 1 -> 2
vtx ^= 3; FLIP_CCW_CW_CULLING(pContext); dwIndex2 = *pwIndexData++; pv[vtx] = LP_FVF_VERTEX(lpVertices, dwIndex2); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->dwProvokingVertex = lastVtx;
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bCulled, vtx);
lastVtx = vtx;
}
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan_MS_16IND,0); } // _D3D_R3_DP2_IndexedTriangleFan_MS_16IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineList_MS_32IND
//
// Render D3DDP2OP_INDEXEDLINELIST lines
// Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineList_MS_32IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD *pdwIndx, dwIndex0, dwIndex1, i;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineList_MS_32IND); pdwIndx = (DWORD *)lpPrim;
for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = *pdwIndx++; dwIndex1 = *pdwIndx++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
__ProcessLine(pContext, pv, pv[0]); }
DBG_EXIT(_D3D_R3_DP2_IndexedLineList_MS_32IND,0); } // _D3D_R3_DP2_IndexedLineList_MS_32IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedLineStrip_MS_32IND
//
// Render D3DDP2OP_INDEXEDLINESTRIP lines
// Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedLineStrip_MS_32IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { D3DTLVERTEX *pv[2]; DWORD dwIndex, *pdwIndx, i;
DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip_MS_32IND);
pdwIndx = (DWORD *)lpPrim;
dwIndex = *pdwIndx++; pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
for( i = 0; i < dwPrimCount; i++ ) { dwIndex = *pdwIndx++; pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
__ProcessLine(pContext, pv, pv[0]);
pv[0] = pv[1]; }
DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip_MS_32IND,0); } // _D3D_R3_DP2_IndexedLineStrip_MS_32IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleList_MS_32IND
//
// Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
// Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleList_MS_32IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, *pdwIndexData, i; D3DTLVERTEX *pv[4]; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList_MS_32IND);
DISPDBG((DBGLVL,"pContext = 0x%x dwPrimCount=%d lpPrim=0x%x lpVertices=0x%x " "IdxOffset=%d dwVertexBufferLen=%d ", pContext,(DWORD)dwPrimCount,lpPrim,lpVertices,IdxOffset, dwVertexBufferLen));
pdwIndexData = (DWORD *)lpPrim;
pContext->dwProvokingVertex = 0; for( i = 0; i < dwPrimCount; i++ ) { dwIndex0 = *pdwIndexData++; dwIndex1 = *pdwIndexData++; dwIndex2 = *pdwIndexData++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv); }
DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList_MS_32IND,0); } // _D3D_R3_DP2_IndexedTriangleList_MS_32IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND
//
// Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
// Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i, *pdwIndexData; D3DTLVERTEX *pv[4]; int vtx_a, vtx_b, bCulled; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE]; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip_MS_32IND);
pdwIndexData = (DWORD *)lpPrim;
dwIndex0 = *pdwIndexData++; dwIndex1 = *pdwIndexData++; dwIndex2 = *pdwIndexData++;
pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->dwProvokingVertex = 0; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled); lpPrim += sizeof(WORD);
INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
for( i = 1; i < dwPrimCount; i++ ) { FLIP_CCW_CW_CULLING(pContext); dwIndex2 = *pdwIndexData++; pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2); pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bCulled, vtx_a); CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b); }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip_MS_32IND,0); } // _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND
//-----------------------------------------------------------------------------
//
// _D3D_R3_DP2_IndexedTriangleFan_MS_32IND
//
// Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles
// Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
//
//-----------------------------------------------------------------------------
void _D3D_R3_DP2_IndexedTriangleFan_MS_32IND( P3_D3DCONTEXT *pContext, DWORD dwPrimCount, LPBYTE lpPrim, LPD3DTLVERTEX lpVertices, INT IdxOffset, DWORD dwVertexBufferLen, BOOL *pbError) { DWORD dwIndex0, dwIndex1, dwIndex2, i, *pdwIndexData; D3DTLVERTEX *pv[4]; int vtx, lastVtx, bCulled; DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE]; SAVE_CULLING_STATE(pContext);
DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan_MS_32IND);
pdwIndexData = (DWORD *)lpPrim; dwIndex0 = *pdwIndexData++; dwIndex1 = *pdwIndexData++; dwIndex2 = *pdwIndexData++;
lastVtx = vtx = 2; pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0); pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1); pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
pContext->dwProvokingVertex = 1; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex]; INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled); lpPrim += sizeof(WORD);
for( i = 1; i < dwPrimCount; i++ ) { // 2 -> 1, 1 -> 2
vtx ^= 3; FLIP_CCW_CW_CULLING(pContext); dwIndex2 = *pdwIndexData++; pv[vtx] = LP_FVF_VERTEX(lpVertices, dwIndex2); CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
pContext->dwProvokingVertex = lastVtx; pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bCulled, vtx);
lastVtx = vtx; }
RESTORE_CULLING_STATE(pContext); DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan_MS_32IND,0); } // _D3D_R3_DP2_IndexedTriangleFan_MS_32IND
#endif // DX8_MULTSTREAMS
//-----------------------------------------------------------------------------
//
// _D3D_R3_PickVertexProcessor
//
// Pick appropriate triangle rendering functions based on texturing
//
//-----------------------------------------------------------------------------
void _D3D_R3_PickVertexProcessor( P3_D3DCONTEXT *pContext ) { DWORD Flags = pContext->Flags;
DBG_ENTRY(_D3D_R3_PickVertexProcessor);
if (pContext->RenderStates[D3DRENDERSTATE_FILLMODE] == D3DFILL_WIREFRAME) { // Wireframe mode renderers
pContext->pRendTri_1V = __ProcessTri_1Vtx_Wire; pContext->pRendTri_3V = __ProcessTri_3Vtx_Wire; } else if (pContext->RenderStates[D3DRENDERSTATE_FILLMODE] == D3DFILL_POINT) { #if DX8_DDI
if(IS_POINTSPRITE_ACTIVE(pContext)) { // Point sprite mode renderers
pContext->pRendTri_1V = __ProcessTri_1Vtx_PointSprite; pContext->pRendTri_3V = __ProcessTri_3Vtx_PointSprite; } else #endif
{ // Point mode renderers
pContext->pRendTri_1V = __ProcessTri_1Vtx_Point; pContext->pRendTri_3V = __ProcessTri_3Vtx_Point; } } else #if !defined(_WIN64)
// We avoid this path in IA64 as something is wrongly fed into the chip
if( ( Flags & SURFACE_PERSPCORRECT ) && ( Flags & SURFACE_GOURAUD ) && (pContext->bTex0Valid) && (!pContext->bTex1Valid) ) { // Solid mode renderes for single textured-gouraud shaded-persp corr
if(( pContext->RenderStates[D3DRENDERSTATE_WRAP0] ) || ( pContext->RenderStates[D3DRENDERSTATE_WRAP1] )) { pContext->pRendTri_1V = __ProcessTri_1Vtx_Generic; pContext->pRendTri_3V = __ProcessTri_3Vtx_Generic; } else { pContext->pRendTri_1V = __ProcessTri_1Vtx_PerspSingleTexGouraud; pContext->pRendTri_3V = __ProcessTri_3Vtx_PerspSingleTexGouraud; } } else #endif !defined(_WIN64)
{ // Solid mode renderers for textured triangles
if( pContext->bTex0Valid || pContext->bTex1Valid ) { pContext->pRendTri_1V = __ProcessTri_1Vtx_Generic; pContext->pRendTri_3V = __ProcessTri_3Vtx_Generic; } else { // Solid mode renderers for non-textured triangles
pContext->pRendTri_1V = __ProcessTri_1Vtx_NoTexture; pContext->pRendTri_3V = __ProcessTri_3Vtx_NoTexture; } }
DBG_EXIT(_D3D_R3_PickVertexProcessor,0); } // _D3D_R3_PickVertexProcessor
|