📄 tomsd3dlib.h
字号:
/* Copyright (C) Tom Forsyth, 2001.
* All rights reserved worldwide.
*
* This software is provided "as is" without express or implied
* warranties. You may freely copy and compile this source into
* applications you distribute provided that the copyright text
* below is included in the resulting source code, for example:
* "Portions Copyright (C) Tom Forsyth, 2001"
*/
// Useful D3D-related stuff.
#ifndef TOMSD3DLIB_INCLUDED
#define TOMSD3DLIB_INCLUDED
#ifndef DXVERSION
#error Please define DXVERSION to be 7 or 8 or something.
#endif
#if DXVERSION==7
#define DIRECT3D_VERSION 0x0700
#define DIRECTINPUT_VERSION 0x0700
#elif DXVERSION==8
#define DIRECT3D_VERSION 0x0800
// Let the header file tell you what the latest version is.
//#define DIRECTINPUT_VERSION 0x0800
#else
#error Define DXVERSION to be 7 or 8. No other versions supported ATM.
#endif
#define STRICT
#define D3D_OVERLOADS
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <dinput.h>
//#include "D3DApp.h"
//#include "D3DTextr.h"
#include "DXUtil.h"
//#include "D3DMath.h"
//#include "D3DFile.h"
#if DXVERSION==8
#include "D3D8types.h"
#include "D3dx8core.h"
#else
#include "D3Dtypes.h"
#endif
#include "TomsLib.h"
#include "TomsD3DLib.h"
//#define TRACE sizeof
#if DXVERSION==7
#define LPDIRECTDRAWSURFACEn LPDIRECTDRAWSURFACE7
#define LPDIRECTDRAWn LPDIRECTDRAW7
#define LPDIRECT3DDEVICEn LPDIRECT3DDEVICE7
#define D3DDEVICEDESCn D3DDEVICEDESC7
#define DDSURFACEDESCn DDSURFACEDESC2
#elif DXVERSION==8
#define LPDIRECTDRAWSURFACEn LPDIRECT3DSURFACE8
#define LPDIRECTDRAWn IDontExistAnyMore
#define LPDIRECT3DDEVICEn LPDIRECT3DDEVICE8
#define D3DDEVICEDESCn D3DCAPS8
// DDSURFACEDESC has been split up into stuff like D3DLOCKED_RECT and D3DSURFACE_DESC
#define DDSURFACEDESCn IDontExistAnyMoreInAUsefulWay
#else
#error Define DXVERSION to be 7 or 8. No other versions supported ATM.
#endif
#if DXVERSION==7
// Initialise a D3D-style object
template <class S> void D3DInit ( S &thing )
{
ZeroMemory ( &thing, sizeof ( S ) );
thing.dwSize = sizeof ( S );
}
#endif //#if DXVERSION==7
// Check the ref count of a D3D object.
// Only legal with debug runtime.
template <class S> int CheckD3DRefCount ( S &thing )
{
thing->AddRef();
return ( thing->Release() );
}
// A struct to handle 4-component texture coords.
struct D3DTEXCOORD
{
float fU;
float fV;
float fW;
float fT;
};
// A generalised FVF semi-smart pointer.
class MyFVFPointer
{
private:
DWORD dwFVFType; // The D3D format.
// These are byte offsets from the start of the vertex.
// If an offset is -1, that item is not present.
int iOffsetPosition;
int iOffsetRHW;
int iOffsetBlendWeights;
int iOffsetNormal;
int iOffsetPsize;
int iOffsetColour[2]; // AKA "diffuse" and "specular"
int iOffsetTexCoord[8];
int iNumBlendWeights; // Number of blend weights.
int iNumTexCoords; // Number of texture sets.
int iSizeOfVertex; // Size in bytes.
void *pvCurrentVert; // The vertex this is currently pointing to.
public:
// Sets the FVF type
void SetFVFType ( DWORD dwType )
{
int i;
// Initialise everything.
dwFVFType = dwType;
iOffsetPosition = -1;
iOffsetRHW = -1;
iOffsetBlendWeights = -1;
iOffsetNormal = -1;
iOffsetPsize = -1;
iOffsetColour[0] = -1;
iOffsetColour[1] = -1;
iSizeOfVertex = 0;
iNumBlendWeights = 0;
iNumTexCoords = 0;
for ( i = 0; i < 8; i++ )
{
iOffsetTexCoord[i] = -1;
}
if ( dwType == 0 )
{
// NULL type - not set up yet.
return;
}
// Now find the components that are present.
int iOffset = 0;
// Bits 1,2,3 all code for a position type.
switch ( dwType & D3DFVF_POSITION_MASK )
{
case 0:
// Invalid.
ASSERT ( FALSE );
break;
case D3DFVF_XYZ:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iNumBlendWeights = 0;
break;
case D3DFVF_XYZRHW:
ASSERT ( ( dwType & D3DFVF_NORMAL ) == 0 );
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetRHW = iOffset;
iOffset += 1 * sizeof ( float );
iNumBlendWeights = 0;
break;
case D3DFVF_XYZB1:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetBlendWeights = iOffset;
iNumBlendWeights = 1;
iOffset += iNumBlendWeights * sizeof ( float );
break;
case D3DFVF_XYZB2:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetBlendWeights = iOffset;
iNumBlendWeights = 2;
iOffset += iNumBlendWeights * sizeof ( float );
break;
case D3DFVF_XYZB3:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetBlendWeights = iOffset;
iNumBlendWeights = 3;
iOffset += iNumBlendWeights * sizeof ( float );
break;
case D3DFVF_XYZB4:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetBlendWeights = iOffset;
iNumBlendWeights = 4;
iOffset += iNumBlendWeights * sizeof ( float );
break;
case D3DFVF_XYZB5:
iOffsetPosition = iOffset;
iOffset += 3 * sizeof ( float );
iOffsetBlendWeights = iOffset;
iNumBlendWeights = 5;
iOffset += iNumBlendWeights * sizeof ( float );
break;
}
#if DXVERSION==7
if ( dwType & D3DFVF_RESERVED1 )
{
// A special-case D3DLVERTEX. Make sure it's correct.
ASSERT ( dwType == D3DFVF_LVERTEX );
// No offset to mark, just a DWORD to skip.
iOffset += sizeof ( float );
}
#endif
if ( dwType & D3DFVF_NORMAL )
{
iOffsetNormal = iOffset;
iOffset += 3 * sizeof ( float );
}
#if DXVERSION==8
if ( dwType & D3DFVF_PSIZE )
{
iOffsetPsize = iOffset;
iOffset += 1 * sizeof ( float );
}
#endif
if ( dwType & D3DFVF_DIFFUSE )
{
iOffsetColour[0] = iOffset;
iOffset += 1 * sizeof ( DWORD );
}
if ( dwType & D3DFVF_SPECULAR )
{
iOffsetColour[1] = iOffset;
iOffset += 1 * sizeof ( DWORD );
}
// Now do the textures.
// Slight hardwiring because the D3D headers don't give quite enough info.
#if D3DFVF_TEXCOORDSIZE1(3) != ( 0x3 << ( 3 * 2 + 16 ) )
#error Hardwired FVF format flags do not match headers.
#endif
iNumTexCoords = ( dwType & D3DFVF_TEXCOUNT_MASK ) >> D3DFVF_TEXCOUNT_SHIFT;
DWORD dwTemp = dwType >> 16;
for ( i = 0; i < iNumTexCoords; i++ )
{
// Set up the offsets.
switch ( dwTemp & 0x3 )
{
case D3DFVF_TEXTUREFORMAT1:
// 1 component.
iOffsetTexCoord[i] = iOffset;
iOffset += 1 * sizeof ( float );
break;
case D3DFVF_TEXTUREFORMAT2:
// 1 component.
iOffsetTexCoord[i] = iOffset;
iOffset += 2 * sizeof ( float );
break;
case D3DFVF_TEXTUREFORMAT3:
// 1 component.
iOffsetTexCoord[i] = iOffset;
iOffset += 3 * sizeof ( float );
break;
case D3DFVF_TEXTUREFORMAT4:
// 1 component.
iOffsetTexCoord[i] = iOffset;
iOffset += 4 * sizeof ( float );
break;
default:
// The maths fell over somewhere.
ASSERT ( FALSE );
break;
}
dwTemp >>= 2;
}
// The size of the whole vertex.
iSizeOfVertex = iOffset;
#if DXVERSION==8
// D3DX is almost useful!
ASSERT ( (unsigned)iSizeOfVertex == D3DXGetFVFVertexSize ( dwFVFType ) );
#endif
}
// Gets the FVF type
DWORD GetFVFType ( void )
{
return dwFVFType;
}
// Assignment - can only be done between FVF pointers of the same type.
MyFVFPointer & operator= ( const MyFVFPointer &other )
{
ASSERT ( dwFVFType == other.dwFVFType );
pvCurrentVert = other.pvCurrentVert;
ASSERT ( 0 == memcmp ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) ) );
return ( *this );
}
// Assignment from a void*
MyFVFPointer & operator= ( void *ptr )
{
// Can only assign NULL to an untyped vertex.
ASSERT ( ( dwFVFType != 0 ) || ( ptr == NULL ) );
pvCurrentVert = ptr;
return ( *this );
}
// Comparison - can only be done between FVF pointers of the same type.
bool operator== ( const MyFVFPointer &other )
{
ASSERT ( dwFVFType == other.dwFVFType );
if ( pvCurrentVert == other.pvCurrentVert )
{
ASSERT ( 0 == memcmp ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) ) );
return ( TRUE );
}
else
{
return ( FALSE );
}
}
// Constructor.
MyFVFPointer ( DWORD dwType = 0 )
{
SetFVFType ( dwType );
}
// Constructor from type & pointer.
MyFVFPointer ( DWORD dwType, void *ptr )
{
// Just a straight memberwise copy.
SetFVFType ( dwType );
pvCurrentVert = ptr;
}
// Copy constructors.
MyFVFPointer ( MyFVFPointer &other )
{
// Just a straight memberwise copy.
memcpy ( (void *)this, (void *)&other, sizeof ( MyFVFPointer ) );
}
// Destruction.
~MyFVFPointer ( void ) {}
// Gets the FVF size in bytes
DWORD GetFVFSize ( void )
{
return ( iSizeOfVertex );
}
// Set current vertex base
void SetCurVertex ( void *ptr )
{
ASSERT ( dwFVFType != 0 );
pvCurrentVert = ptr;
}
// Get current vertex base
void *GetCurVertex ( void )
{
return ( pvCurrentVert );
}
// Move the vertex to the next one.
void NextVertex ( void )
{
pvCurrentVert = GetVertex ( 1 );
}
// Move the vertex to the previous one.
void PrevVertex ( void )
{
pvCurrentVert = GetVertex ( -1 );
}
// Indexed offset. Does not affect the current pointer.
// iOffset is signed - can be -ve or +ve.
void *GetVertex ( int iOffset )
{
return ( (void *)( (char *)pvCurrentVert + iSizeOfVertex * iOffset ) );
}
// Allocate some vertices.
// Return is TRUE on success.
bool AllocVertices ( int iNumVertices )
{
ASSERT ( dwFVFType != 0 );
ASSERT ( iSizeOfVertex > 0 );
pvCurrentVert = malloc ( iNumVertices * iSizeOfVertex );
if ( pvCurrentVert != NULL )
{
return ( TRUE );
}
else
{
return ( FALSE );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -