📄 tomsd3dlib.h
字号:
// Rellocate some vertices.
// Return is TRUE on success.
bool ReallocVertices ( int iNumVertices )
{
ASSERT ( dwFVFType != 0 );
ASSERT ( iSizeOfVertex > 0 );
pvCurrentVert = realloc ( pvCurrentVert, iNumVertices * iSizeOfVertex );
if ( pvCurrentVert != NULL )
{
return ( TRUE );
}
else
{
return ( FALSE );
}
}
// Free the vertices.
void FreeVertices ( void )
{
if ( pvCurrentVert != NULL )
{
free ( pvCurrentVert );
pvCurrentVert = NULL;
}
}
// Individual vertex component pointer getters.
D3DVECTOR &Position ( void )
{
ASSERT ( iOffsetPosition != -1 );
return ( *(D3DVECTOR *)( (char *)pvCurrentVert + iOffsetPosition ) );
}
float &X ( void )
{
ASSERT ( iOffsetPosition != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 0 * sizeof ( float ) ) );
}
float &Y ( void )
{
ASSERT ( iOffsetPosition != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 1 * sizeof ( float ) ) );
}
float &Z ( void )
{
ASSERT ( iOffsetPosition != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetPosition + 2 * sizeof ( float ) ) );
}
float &RHW ( void )
{
ASSERT ( iOffsetRHW != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetRHW ) );
}
float &BlendWeight ( int iWeightNum )
{
ASSERT ( iOffsetBlendWeights != -1 );
ASSERT ( iWeightNum < iNumBlendWeights );
#if DXVERSION==8
// The last weight isn't a weight, it's indices, when LASTBETA_UBYTE4 is set.
ASSERT ( ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) == 0 ) || ( iWeightNum < iNumBlendWeights - 1 ) );
#endif
return ( *(float *)( (char *)pvCurrentVert + iOffsetBlendWeights + iWeightNum * sizeof ( float ) ) );
}
#if DXVERSION==8
DWORD &BlendIndices ( void )
{
ASSERT ( iOffsetBlendWeights != -1 );
ASSERT ( iNumBlendWeights > 0 );
ASSERT ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) != 0 );
// Last "blend weight" is the packed indices.
return ( *(DWORD *)( (char *)pvCurrentVert + iOffsetBlendWeights + ( iNumBlendWeights - 1 ) * sizeof ( float ) ) );
}
BYTE &BlendIndex ( int iIndexNum )
{
ASSERT ( iOffsetBlendWeights != -1 );
ASSERT ( iNumBlendWeights > 0 );
ASSERT ( ( dwFVFType & D3DFVF_LASTBETA_UBYTE4 ) != 0 );
// Last "blend weight" is the packed indices.
ASSERT ( iIndexNum < 4 );
return ( *(BYTE *)( (char *)pvCurrentVert + iOffsetBlendWeights + iIndexNum + ( iNumBlendWeights - 1 ) * sizeof ( float ) ) );
}
#endif
D3DVECTOR &Normal ( void )
{
ASSERT ( iOffsetNormal != -1 );
return ( *(D3DVECTOR *)( (char *)pvCurrentVert + iOffsetNormal ) );
}
float &NX ( void )
{
ASSERT ( iOffsetNormal != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 0 * sizeof ( float ) ) );
}
float &NY ( void )
{
ASSERT ( iOffsetNormal != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 1 * sizeof ( float ) ) );
}
float &NZ ( void )
{
ASSERT ( iOffsetNormal != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetNormal + 2 * sizeof ( float ) ) );
}
float &Psize ( void )
{
ASSERT ( iOffsetPsize != -1 );
return ( *(float *)( (char *)pvCurrentVert + iOffsetPsize ) );
}
DWORD &Colour ( int iColourNum ) // Counted from 0.
{
// Only two colours at max ATM.
ASSERT ( iColourNum < 2 );
ASSERT ( iOffsetColour[iColourNum] != -1 );
return ( *(DWORD *)( (char *)pvCurrentVert + iOffsetColour[iColourNum] ) );
}
DWORD &Diff ( void )
{
return ( Colour ( 0 ) );
}
DWORD &Spec ( void )
{
return ( Colour ( 1 ) );
}
D3DTEXCOORD &TexCoord ( int iTexCoordNum ) // Counted from 0.
{
ASSERT ( iTexCoordNum < iNumTexCoords );
ASSERT ( iOffsetTexCoord[iTexCoordNum] != -1 );
return ( *(D3DTEXCOORD *)( (char *)pvCurrentVert + iOffsetTexCoord[iTexCoordNum] ) );
}
float &U0 ( void )
{
return ( TexCoord(0).fU );
}
float &V0 ( void )
{
return ( TexCoord(0).fV );
}
float &U1 ( void )
{
return ( TexCoord(1).fU );
}
float &V1 ( void )
{
return ( TexCoord(1).fV );
}
// Now some more nice overloaded operators.
// Conversion to void*
operator void*()
{
return ( (void *)pvCurrentVert );
}
// Subscript - may be positive or negative.
// NOTE! This is awesomely inefficient unless the compiler is smart. :-(
MyFVFPointer operator[] ( const int iOffset )
{
MyFVFPointer ret = *this;
ret.pvCurrentVert = GetVertex ( iOffset );
return ret;
}
// Addition.
MyFVFPointer &operator+= ( const int iOffset )
{
pvCurrentVert = GetVertex ( iOffset );
return ( *this );
}
// Subtraction.
MyFVFPointer &operator-= ( const int iOffset )
{
pvCurrentVert = GetVertex ( -iOffset );
return ( *this );
}
// Next (prefix).
MyFVFPointer &operator++ ( void )
{
pvCurrentVert = GetVertex ( 1 );
return ( *this );
}
// Prev (prefix).
MyFVFPointer &operator-- ( void )
{
pvCurrentVert = GetVertex ( -1 );
return ( *this );
}
};
// Fill the matViewport matrix from the
// viewport data in vpViewport.
// Very useful for concatenating the whole
// vertex transform pipeline.
// TomF.
#if DXVERSION==8
static void MakeMatrixFromViewport ( D3DMATRIX &matViewport, D3DVIEWPORT8 &vpViewport )
#else
static void MakeMatrixFromViewport ( D3DMATRIX &matViewport, D3DVIEWPORT7 &vpViewport )
#endif
{
#if DXVERSION==8
float fHalfWidth = vpViewport.Width * 0.5f;
float fHalfHeight = vpViewport.Height * -0.5f;
#else
float fHalfWidth = vpViewport.dwWidth * 0.5f;
float fHalfHeight = vpViewport.dwHeight * -0.5f;
#endif
matViewport._11 = fHalfWidth;
matViewport._12 = 0.0f;
matViewport._13 = 0.0f;
matViewport._14 = 0.0f;
matViewport._21 = 0.0f;
matViewport._22 = fHalfHeight;
matViewport._23 = 0.0f;
matViewport._24 = 0.0f;
#if DXVERSION==8
matViewport._31 = 0.0f;
matViewport._32 = 0.0f;
matViewport._33 = vpViewport.MaxZ - vpViewport.MinZ;
matViewport._34 = 0.0f;
matViewport._41 = vpViewport.X + fHalfWidth;
matViewport._42 = vpViewport.Y - fHalfHeight;
matViewport._43 = vpViewport.MinZ;
matViewport._44 = 1.0f;
#else
matViewport._31 = 0.0f;
matViewport._32 = 0.0f;
matViewport._33 = vpViewport.dvMaxZ - vpViewport.dvMinZ;
matViewport._34 = 0.0f;
matViewport._41 = vpViewport.dwX + fHalfWidth;
matViewport._42 = vpViewport.dwY - fHalfHeight;
matViewport._43 = vpViewport.dvMinZ;
matViewport._44 = 1.0f;
#endif
}
// Multi-format support. Not very fast, but useful. TomF.
struct FloatColour
{
float fA, fR, fG, fB;
FloatColour operator+( FloatColour fc )
{
fc.fA += this->fA;
fc.fR += this->fR;
fc.fG += this->fG;
fc.fB += this->fB;
return fc;
}
FloatColour operator*( float fScale )
{
FloatColour fc;
fc.fA = this->fA * fScale;
fc.fR = this->fR * fScale;
fc.fG = this->fG * fScale;
fc.fB = this->fB * fScale;
return fc;
}
};
#if DXVERSION>=8
// Fake up the essential DDPIXELFORMAT data from DX8 FORMAT info.
struct DX8PIXELFORMAT
{
DWORD dwFlags;
DWORD dwRBitMask;
DWORD dwGBitMask;
DWORD dwBBitMask;
DWORD dwRGBAlphaBitMask;
};
// Make these up, as they are not in DX8.
#define DDPF_RGB 0x1
#define DDPF_ALPHAPIXELS 0x2
#endif //#if DXVERSION==8
#if DXVERSION>=8
static FloatColour ConvertPixelDataToFloat ( DWORD dwSrc, const DX8PIXELFORMAT &ddpfSrc )
#else
static FloatColour ConvertPixelDataToFloat ( DWORD dwSrc, const DDPIXELFORMAT &ddpfSrc )
#endif
{
FloatColour fc;
ASSERT ( ( ddpfSrc.dwFlags & DDPF_RGB ) != 0 );
fc.fR = ( (float)( dwSrc & ddpfSrc.dwRBitMask ) / (float)ddpfSrc.dwRBitMask );
fc.fG = ( (float)( dwSrc & ddpfSrc.dwGBitMask ) / (float)ddpfSrc.dwGBitMask );
fc.fB = ( (float)( dwSrc & ddpfSrc.dwBBitMask ) / (float)ddpfSrc.dwBBitMask );
fc.fA = ( (float)( dwSrc & ddpfSrc.dwRGBAlphaBitMask ) / (float)ddpfSrc.dwRGBAlphaBitMask );
return fc;
}
#if DXVERSION>=8
static DWORD ConvertFloatToPixelData ( const FloatColour &fc, const DX8PIXELFORMAT &ddpfDst )
#else
static DWORD ConvertFloatToPixelData ( const FloatColour &fc, const DDPIXELFORMAT &ddpfDst )
#endif
{
ASSERT ( ( ddpfDst.dwFlags & DDPF_RGB ) != 0 );
DWORD dwRes = 0;
dwRes |= ( (DWORD)( fc.fR * (float)( ddpfDst.dwRBitMask ) ) & ddpfDst.dwRBitMask );
dwRes |= ( (DWORD)( fc.fG * (float)( ddpfDst.dwGBitMask ) ) & ddpfDst.dwGBitMask );
dwRes |= ( (DWORD)( fc.fB * (float)( ddpfDst.dwBBitMask ) ) & ddpfDst.dwBBitMask );
dwRes |= ( (DWORD)( fc.fA * (float)( ddpfDst.dwRGBAlphaBitMask ) ) & ddpfDst.dwRGBAlphaBitMask );
return dwRes;
}
// Convert between two different formats. Both must be RGB.
#if DXVERSION>=8
static DWORD ConvertPixelData ( const DX8PIXELFORMAT &ddpfDst, DWORD dwSrc, const DX8PIXELFORMAT &ddpfSrc )
#else
static DWORD ConvertPixelData ( const DDPIXELFORMAT &ddpfDst, DWORD dwSrc, const DDPIXELFORMAT &ddpfSrc )
#endif
{
FloatColour fc = ConvertPixelDataToFloat ( dwSrc, ddpfSrc );
return ConvertFloatToPixelData ( fc, ddpfDst );
}
#if DXVERSION>=8
static const DX8PIXELFORMAT ddpfR8G8B8A8 = {
DDPF_ALPHAPIXELS | DDPF_RGB, // dwFlags
0x00FF0000, // dwRBitMask,
0x0000FF00, // dwGBitMask,
0x000000FF, // dwBBitMask,
0xFF000000 // dwRGBAlphaBitMask
};
#else
static const DDPIXELFORMAT ddpfR8G8B8A8 = {
sizeof ( DDPIXELFORMAT ), // dwSize
DDPF_ALPHAPIXELS | DDPF_RGB, // dwFlags
0, // dwFourCC
32, // dwRGBBitCount,
0x00FF0000, // dwRBitMask,
0x0000FF00, // dwGBitMask,
0x000000FF, // dwBBitMask,
0xFF000000 // dwRGBAlphaBitMask
};
#endif
// Convert from the given pixel format to A8R8G8B8
#if DXVERSION>=8
static DWORD ConvertPixelToA8R8G8B8 ( const DX8PIXELFORMAT &ddpf, DWORD dwSrc )
#else
static DWORD ConvertPixelToA8R8G8B8 ( const DDPIXELFORMAT &ddpf, DWORD dwSrc )
#endif
{
return ConvertPixelData ( ddpfR8G8B8A8, dwSrc, ddpf );
}
// Convert from A8R8G8B8 to the given pixel format.
#if DXVERSION>=8
static DWORD ConvertPixelFromA8R8G8B8 ( const DX8PIXELFORMAT &ddpf, DWORD dwSrc )
#else
static DWORD ConvertPixelFromA8R8G8B8 ( const DDPIXELFORMAT &ddpf, DWORD dwSrc )
#endif
{
return ConvertPixelData ( ddpf, dwSrc, ddpfR8G8B8A8 );
}
// An attempt at a "universal" blitter that handles any texture formats,
// and handles different filtering modes. Adapt as needed.
// Filter types.
enum UblitFilter
{
UBLIT_FILTER_POINT,
UBLIT_FILTER_BILINEAR,
};
#if DXVERSION==7
// Returns TRUE if successful, FALSE otherwise.
BOOL UniversalBlit ( LPDIRECTDRAWSURFACEn pddsSrc, LPDIRECTDRAWSURFACEn pddsDst,
UblitFilter ufMin = UBLIT_FILTER_POINT,
UblitFilter ufMag = UBLIT_FILTER_POINT );
#endif
#if DXVERSION==7
// Given a locked DD surface and its surface desc, returns the pixel data at the given coords.
// Clamps to the surface's size in X and Y.
DWORD SamplePoint ( int iX, int iY, DDSURFACEDESC2 &ddsdSrc );
#else
// Given a locked DD surface and its surface desc, returns the pixel data at the given coords.
// Clamps to the surface's size in X and Y.
DWORD SamplePoint ( int iX, int iY, int iBitsPerPixel, D3DSURFACE_DESC &ddsdSrc, D3DLOCKED_RECT &locked_rect );
#endif
#endif //#ifndef TOMSD3DLIB_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -