You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
8.1 KiB
220 lines
8.1 KiB
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: stateset.hpp
|
|
* Content: State sets handling interfaces
|
|
*
|
|
***************************************************************************/
|
|
#ifndef _STATESET_HPP_
|
|
#define _STATESET_HPP_
|
|
|
|
struct CHandle;
|
|
const DWORD __INVALIDHANDLE = 0xFFFFFFFF;
|
|
|
|
extern void InsertStateSetOp(LPDIRECT3DDEVICEI pDevI, DWORD dwOperation, DWORD dwParam, D3DSTATEBLOCKTYPE sbt);
|
|
//---------------------------------------------------------------------
|
|
// This class is used to generate sequential integer numbers (handles).
|
|
// When a handle is released it will be reused.
|
|
// Number of handles is unlimited
|
|
//
|
|
class CHandleFactory
|
|
{
|
|
public:
|
|
CHandleFactory() {m_dwArraySize = 0; m_Handles = NULL;}
|
|
~CHandleFactory();
|
|
HRESULT Init(DWORD dwInitialSize, DWORD dwGrowSize);
|
|
DWORD CreateNewHandle();
|
|
void ReleaseHandle(DWORD handle);
|
|
protected:
|
|
CHandle* CreateHandleArray(DWORD dwSize);
|
|
|
|
CHandle *m_Handles; // Array of objects
|
|
DWORD m_dwGrowSize;
|
|
DWORD m_dwArraySize; // Number of objects in the array
|
|
DWORD m_Free; // Header for free elements in the array
|
|
};
|
|
//---------------------------------------------------------------------
|
|
// This class provides interface to the growing state set buffer
|
|
//
|
|
class CStateSetBuffer
|
|
{
|
|
public:
|
|
CStateSetBuffer()
|
|
{
|
|
m_pBuffer = NULL;
|
|
m_dwCurrentSize = 0;
|
|
m_dwBufferSize = 0;
|
|
m_pDP2CurrCommand = 0;
|
|
}
|
|
CStateSetBuffer(CStateSetBuffer& src)
|
|
{
|
|
m_dwCurrentSize = src.m_dwCurrentSize;
|
|
m_dwBufferSize = src.m_dwCurrentSize;
|
|
if(m_dwCurrentSize != 0)
|
|
{
|
|
m_pBuffer = new BYTE[m_dwCurrentSize];
|
|
if(m_pBuffer == 0)
|
|
{
|
|
m_dwCurrentSize = 0;
|
|
m_pDP2CurrCommand = 0;
|
|
throw DDERR_OUTOFMEMORY;
|
|
}
|
|
memcpy(m_pBuffer, src.m_pBuffer, m_dwCurrentSize);
|
|
}
|
|
else
|
|
{
|
|
m_pBuffer = 0;
|
|
}
|
|
m_pDP2CurrCommand = 0;
|
|
}
|
|
~CStateSetBuffer()
|
|
{
|
|
delete [] m_pBuffer;
|
|
}
|
|
void operator=(CStateSetBuffer& src)
|
|
{
|
|
m_dwCurrentSize = src.m_dwCurrentSize;
|
|
if(m_dwBufferSize != m_dwCurrentSize)
|
|
{
|
|
m_dwBufferSize = m_dwCurrentSize;
|
|
delete [] m_pBuffer;
|
|
if(m_dwCurrentSize != 0)
|
|
{
|
|
m_pBuffer = new BYTE[m_dwCurrentSize];
|
|
if(m_pBuffer == 0)
|
|
{
|
|
m_dwCurrentSize = 0;
|
|
m_pDP2CurrCommand = 0;
|
|
throw DDERR_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pBuffer = 0;
|
|
m_pDP2CurrCommand = 0;
|
|
return;
|
|
}
|
|
}
|
|
memcpy(m_pBuffer, src.m_pBuffer, m_dwCurrentSize);
|
|
m_pDP2CurrCommand = 0;
|
|
}
|
|
// Insert a command to the buffer. Grow buffer if necessary
|
|
void InsertCommand(D3DHAL_DP2OPERATION, LPVOID pData, DWORD dwDataSize);
|
|
// Reset current command
|
|
void ResetCurrentCommand()
|
|
{
|
|
m_pDP2CurrCommand = 0;
|
|
}
|
|
// Set buffer to its initial state. Memory is not freed
|
|
void Reset()
|
|
{
|
|
m_dwCurrentSize = 0;
|
|
m_pDP2CurrCommand = 0;
|
|
}
|
|
|
|
DWORD m_dwCurrentSize;
|
|
DWORD m_dwBufferSize;
|
|
BYTE *m_pBuffer;
|
|
//Pointer to the current position the CB1 buffer
|
|
LPD3DHAL_DP2COMMAND m_pDP2CurrCommand;
|
|
};
|
|
//---------------------------------------------------------------------
|
|
// This class provides interface to a state set
|
|
//
|
|
const DWORD __STATESET_INITIALIZED = 1;
|
|
// Set if we have to check if we need to restore texture stage indices
|
|
const DWORD __STATESET_NEEDCHECKREMAPPING = 2;
|
|
class CStateSet
|
|
{
|
|
public:
|
|
CStateSet()
|
|
{
|
|
m_dwStateSetFlags = 0;
|
|
m_dwDeviceHandle = __INVALIDHANDLE;
|
|
}
|
|
void InsertCommand(D3DHAL_DP2OPERATION, LPVOID pData, DWORD dwDataSize, BOOL bDriverCanHandle);
|
|
// Mark the state set as unused. The object is not destroyed and can be
|
|
// reused
|
|
HRESULT Release();
|
|
// Execute the front-end only or device state subset
|
|
void Execute(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer);
|
|
// Capture the current device state into the state block
|
|
void Capture(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer);
|
|
// Reset the current command in both buffers
|
|
void ResetCurrentCommand()
|
|
{
|
|
m_FEOnlyBuffer.ResetCurrentCommand();
|
|
m_DriverBuffer.ResetCurrentCommand();
|
|
}
|
|
protected:
|
|
CStateSetBuffer m_FEOnlyBuffer; // Contains commands that driver can not
|
|
// understand
|
|
CStateSetBuffer m_DriverBuffer; // Contains commands that driver can
|
|
// understand
|
|
DWORD m_dwDeviceHandle; // Some sets could not have corresponding
|
|
// device buffers, so device handle is not
|
|
// equal to the user visible handle
|
|
DWORD m_dwStateSetFlags;
|
|
friend class CStateSets;
|
|
};
|
|
//---------------------------------------------------------------------
|
|
// This class encapsulates handling of array of state sets
|
|
//
|
|
class CStateSets
|
|
{
|
|
public:
|
|
CStateSets();
|
|
~CStateSets();
|
|
HRESULT Init(DWORD dwFlags);
|
|
HRESULT StartNewSet();
|
|
void EndSet();
|
|
// Returns current handle
|
|
DWORD GetCurrentHandle() {return m_dwCurrentHandle;}
|
|
// Delete state set
|
|
void DeleteStateSet(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle);
|
|
// Returns information about state set data to be written to the device
|
|
// Allocates a new handle for the device buffer
|
|
void GetDeviceBufferInfo(DWORD* dwStateSetHandle, LPVOID *pBuffer, DWORD* dwBufferSize);
|
|
// Insert a render state to the current state set
|
|
// Throws an exception in case of error
|
|
void InsertRenderState(D3DRENDERSTATETYPE state, DWORD dwValue,
|
|
BOOL bDriverCanHandle);
|
|
void InsertLight(DWORD dwLightIndex, LPD3DLIGHT7);
|
|
void InsertLightEnable(DWORD dwLightIndex, BOOL bEnable);
|
|
void InsertMaterial(LPD3DMATERIAL7);
|
|
void InsertViewport(LPD3DVIEWPORT7);
|
|
void InsertTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMat);
|
|
void InsertTextureStageState(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
|
|
void InsertTexture(DWORD dwStage, LPDIRECTDRAWSURFACE7 pTex);
|
|
void InsertClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation);
|
|
// Execute a state set with the specified handle
|
|
void Execute(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle);
|
|
// Capture a state set to the the specified handle
|
|
void Capture(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle);
|
|
// Capture predefined state
|
|
void CreatePredefined(LPDIRECT3DDEVICEI pDevI, D3DSTATEBLOCKTYPE sbt);
|
|
void Cleanup(DWORD dwHandle);
|
|
protected:
|
|
const DWORD m_GrowSize;
|
|
DWORD m_dwMaxSets; // Maximum number of state sets
|
|
DWORD m_dwCurrentHandle;
|
|
CStateSet * m_pStateSets; // Array of state sets
|
|
CStateSet * m_pCurrentStateSet;
|
|
CHandleFactory m_DeviceHandles; // Used to create device handles
|
|
CHandleFactory m_SetHandles; // Used to create state sets
|
|
CStateSet m_BufferSet;
|
|
DWORD m_dwFlags;
|
|
};
|
|
|
|
// This is RESERVED0 in d3dhal.h
|
|
#define D3DDP2OP_FRONTENDDATA 4 // Used by the front-end only
|
|
|
|
// This structure is used by the front-end only
|
|
typedef struct _D3DHAL_DP2FRONTENDDATA
|
|
{
|
|
WORD wStage; // texture stage
|
|
LPVOID pTexture; // Texture pointer
|
|
} D3DHAL_DP2FRONTENDDATA, *LPD3DHAL_DP2FRONTENDDATA;
|
|
|
|
#endif //_STATESTE_HPP_
|