|
|
//----------------------------------------------------------------------------
//
// drawprim.cpp
//
// Implements DrawOnePrimitive, DrawOneIndexedPrimitive and
// DrawPrimitives.
//
// Copyright (C) Microsoft Corporation, 1997.
//
//----------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
//----------------------------------------------------------------------------
//
// DoDrawOnePrimitive
//
// Draw one list of primitives. It's called by both RastDrawOnePrimitive and
// RastDrawPrimitives.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoDrawOnePrimitive(ReferenceRasterizer *pCtx, UINT16 FvfStride, PUINT8 pVtx, D3DPRIMITIVETYPE PrimType, UINT cVertices) { INT i; PUINT8 pV0, pV1, pV2; HRESULT hr;
switch (PrimType) { case D3DPT_POINTLIST: for (i = (INT)cVertices; i > 0; i--) { pCtx->DrawPoint(pVtx); pVtx += FvfStride; } break;
case D3DPT_LINELIST: for (i = (INT)cVertices / 2; i > 0; i--) { pV0 = pVtx; pVtx += FvfStride; pV1 = pVtx; pVtx += FvfStride; pCtx->DrawLine(pV0, pV1); } break; case D3DPT_LINESTRIP: { pV1 = pVtx;
// Disable last-pixel setting for shared verties and store prestate.
pCtx->StoreLastPixelState(TRUE);
// Initial pV0.
for (i = (INT)cVertices - 1; i > 1; i--) { pV0 = pV1; pVtx += FvfStride; pV1 = pVtx; pCtx->DrawLine(pV0, pV1); }
// Restore last-pixel setting.
pCtx->StoreLastPixelState(FALSE);
// Draw last line with last-pixel setting from state.
if (i == 1) { pV0 = pVtx + FvfStride; pCtx->DrawLine(pV1, pV0); } } break;
case D3DPT_TRIANGLELIST: for (i = (INT)cVertices; i > 0; i -= 3) { pV0 = pVtx; pVtx += FvfStride; pV1 = pVtx; pVtx += FvfStride; pV2 = pVtx; pVtx += FvfStride; pCtx->DrawTriangle(pV0, pV1, pV2); } break; case D3DPT_TRIANGLESTRIP: { // Get initial vertex values.
pV1 = pVtx; pVtx += FvfStride; pV2 = pVtx; pVtx += FvfStride;
for (i = (INT)cVertices - 2; i > 1; i -= 2) { pV0 = pV1; pV1 = pV2; pV2 = pVtx; pVtx += FvfStride; pCtx->DrawTriangle(pV0, pV1, pV2);
pV0 = pV1; pV1 = pV2; pV2 = pVtx; pVtx += FvfStride; pCtx->DrawTriangle(pV0, pV2, pV1); }
if (i > 0) { pV0 = pV1; pV1 = pV2; pV2 = pVtx; pCtx->DrawTriangle(pV0, pV1, pV2); } } break; case D3DPT_TRIANGLEFAN: { pV2 = pVtx; pVtx += FvfStride; // Preload initial pV0.
pV1 = pVtx; pVtx += FvfStride; for (i = (INT)cVertices - 2; i > 0; i--) { pV0 = pV1; pV1 = pVtx; pVtx += FvfStride; pCtx->DrawTriangle(pV0, pV1, pV2); } } break;
default: DPFM(0, DRV, ("Refrast Error: Unknown or unsupported primitive type " "requested of DrawOnePrimitive")); return DDERR_INVALIDPARAMS; } return D3D_OK; }
//----------------------------------------------------------------------------
//
// DoDrawOneIndexedPrimitive
//
// Draw one list of indexed primitives. It's called by
// RastDrawOneIndexedPrimitive.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoDrawOneIndexedPrimitive(ReferenceRasterizer *pCtx, UINT16 FvfStride, PUINT8 pVtx, LPWORD puIndices, D3DPRIMITIVETYPE PrimType, UINT cIndices) { INT i; PUINT8 pV0, pV1, pV2; HRESULT hr;
switch(PrimType) { case D3DPT_POINTLIST: for (i = (INT)cIndices; i > 0; i--) { pV0 = pVtx + FvfStride * (*puIndices++); pCtx->DrawPoint(pV0); } break;
case D3DPT_LINELIST: for (i = (INT)cIndices / 2; i > 0; i--) { pV0 = pVtx + FvfStride * (*puIndices++); pV1 = pVtx + FvfStride * (*puIndices++); pCtx->DrawLine(pV0, pV1); } break; case D3DPT_LINESTRIP: { // Disable last-pixel setting for shared verties and store prestate.
pCtx->StoreLastPixelState(TRUE); // Initial pV1.
pV1 = pVtx + FvfStride * (*puIndices++); for (i = (INT)cIndices - 1; i > 1; i--) { pV0 = pV1; pV1 = pVtx + FvfStride * (*puIndices++); pCtx->DrawLine(pV0, pV1); } // Restore last-pixel setting.
pCtx->StoreLastPixelState(FALSE);
// Draw last line with last-pixel setting from state.
if (i == 1) { pV0 = pVtx + FvfStride * (*puIndices); pCtx->DrawLine(pV1, pV0); } } break;
case D3DPT_TRIANGLELIST: for (i = (INT)cIndices; i > 0; i -= 3) { pV0 = pVtx + FvfStride * (*puIndices++); pV1 = pVtx + FvfStride * (*puIndices++); pV2 = pVtx + FvfStride * (*puIndices++); pCtx->DrawTriangle(pV0, pV1, pV2); } break; case D3DPT_TRIANGLESTRIP: { // Get initial vertex values.
pV1 = pVtx + FvfStride * (*puIndices++); pV2 = pVtx + FvfStride * (*puIndices++);
for (i = (INT)cIndices - 2; i > 1; i -= 2) { pV0 = pV1; pV1 = pV2; pV2 = pVtx + FvfStride * (*puIndices++); pCtx->DrawTriangle(pV0, pV1, pV2);
pV0 = pV1; pV1 = pV2; pV2 = pVtx + FvfStride * (*puIndices++); pCtx->DrawTriangle(pV0, pV2, pV1); }
if (i > 0) { pV0 = pV1; pV1 = pV2; pV2 = pVtx + FvfStride * (*puIndices++); pCtx->DrawTriangle(pV0, pV1, pV2); } } break; case D3DPT_TRIANGLEFAN: { pV2 = pVtx + FvfStride * (*puIndices++); // Preload initial pV0.
pV1 = pVtx + FvfStride * (*puIndices++); for (i = (INT)cIndices - 2; i > 0; i--) { pV0 = pV1; pV1 = pVtx + FvfStride * (*puIndices++); pCtx->DrawTriangle(pV0, pV1, pV2); } } break;
default: DPFM(0, DRV, ("Refrast Error: Unknown or unsupported primitive type " "requested of DrawOneIndexedPrimitive")); return DDERR_INVALIDPARAMS; } return D3D_OK; }
//----------------------------------------------------------------------------
//
// DoDrawOneEdgeFlagTriangleFan
//
// Draw one list of triangle fans. It's called by both RastDrawOnePrimitive and
// RastDrawPrimitives.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoDrawOneEdgeFlagTriangleFan(ReferenceRasterizer *pCtx, UINT16 FvfStride, PUINT8 pVtx, UINT cVertices, UINT32 dwEdgeFlags) { INT i; PUINT8 pV0, pV1, pV2; HRESULT hr;
pV2 = pVtx; pVtx += FvfStride; pV0 = pVtx; pVtx += FvfStride; pV1 = pVtx; pVtx += FvfStride; WORD wFlags = 0; if(dwEdgeFlags & 0x2) wFlags |= D3DTRIFLAG_EDGEENABLE1; if(dwEdgeFlags & 0x1) wFlags |= D3DTRIFLAG_EDGEENABLE3; if(cVertices == 3) { if(dwEdgeFlags & 0x4) wFlags |= D3DTRIFLAG_EDGEENABLE2; pCtx->DrawTriangle(pV0, pV1, pV2, wFlags); return D3D_OK; } pCtx->DrawTriangle(pV0, pV1, pV2, wFlags); UINT32 dwMask = 0x4; for (i = (INT)cVertices - 4; i > 0; i--) { pV0 = pV1; pV1 = pVtx; pVtx += FvfStride; if(dwEdgeFlags & dwMask) { pCtx->DrawTriangle(pV0, pV1, pV2, D3DTRIFLAG_EDGEENABLE1); } else { pCtx->DrawTriangle(pV0, pV1, pV2, 0); } dwMask <<= 1; } pV0 = pV1; pV1 = pVtx; wFlags = 0; if(dwEdgeFlags & dwMask) wFlags |= D3DTRIFLAG_EDGEENABLE1; dwMask <<= 1; if(dwEdgeFlags & dwMask) wFlags |= D3DTRIFLAG_EDGEENABLE2; pCtx->DrawTriangle(pV0, pV1, pV2, wFlags);
return D3D_OK; }
#define DDS_LCL(x) ((LPDDRAWI_DDRAWSURFACE_INT)(x))->lpLcl
//----------------------------------------------------------------------------
//
// RendPoint
//
// Draw lists of points. Called by RastRenderPrimitive() for drawing points.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoRendPoints(ReferenceRasterizer *pCtx, LPD3DINSTRUCTION pIns, LPD3DTLVERTEX pVtx, LPD3DPOINT pPt) { INT i; LPD3DTLVERTEX pV;
for (i = pIns->wCount; i > 0; i--) { INT iPts; for (iPts = pPt->wCount, pV = pVtx + pPt->wFirst; iPts > 0; iPts --, pV ++) { HRESULT hr; pCtx->DrawPoint((PUINT8)pV); } } return D3D_OK; }
//----------------------------------------------------------------------------
//
// RendLine
//
// Draw a list of lines. Called by RastRenderPrimitive() for drawing lines.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoRendLines(ReferenceRasterizer *pCtx, LPD3DINSTRUCTION pIns, LPD3DTLVERTEX pVtx, LPD3DLINE pLine) { INT i; LPD3DTLVERTEX pV0, pV1;
for (i = pIns->wCount; i > 0; i --) { HRESULT hr; pV0 = pVtx + pLine->v1; pV1 = pVtx + pLine->v2; pLine = (LPD3DLINE)((PINT8)pLine + pIns->bSize); pCtx->DrawLine((PUINT8)pV0, (PUINT8)pV1); } return D3D_OK; }
//----------------------------------------------------------------------------
//
// RendTriangle
//
// Draw a list of triangles. Called by RastRenderPrimitive() for drawing
// triangles.
//
//----------------------------------------------------------------------------
HRESULT FASTCALL DoRendTriangles(ReferenceRasterizer *pCtx, LPD3DINSTRUCTION pIns, LPD3DTLVERTEX pVtx, LPD3DTRIANGLE pTri) { LPD3DTLVERTEX pV0, pV1, pV2; INT i; for (i = pIns->wCount; i > 0; i --) { HRESULT hr; pV0 = pVtx + pTri->v1; pV1 = pVtx + pTri->v2; pV2 = pVtx + pTri->v3; pCtx->DrawTriangle((PUINT8)pV0, (PUINT8)pV1, (PUINT8)pV2, pTri->wFlags); pTri = (LPD3DTRIANGLE)((PINT8)pTri + pIns->bSize); } return D3D_OK; }
|