📄 nvstatemanager.h
字号:
/******************************************************************************
Copyright (C) 1999, 2000 NVIDIA Corporation
This file is provided without support, instruction, or implied warranty of any
kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is
not liable under any circumstances for any damages or loss whatsoever arising
from the use or inability to use this file or items derived from it.
Comments:
A simple class to manage rendering state. Created as a singleton.
Create it as a static global, or with new. It doesn't matter as long as it is created
before you use the NVStateManager::GetSingleton() API to get a reference to it.
Call it with NVSTATEMANAGER.SetRenderState(...)
Call it with NVSTATEMANAGER.SetTextureStageState(...), etc.
Call the 'Save' versions of the function if you want to deviate from the current state.
Call the 'Restore' version to retrieve the last Save.
There are two levels of caching:
- All Sets/Saves/Restores are tracked for redundancy. This reduces the size of the batch to
be flushed
- The flush function is called before rendering, and only copies state that is
different from the current chip state.
If you get an assert it is probably because an API call failed.
See NVLink for a good example of how this class is used.
Don't be afraid ofthe vector being used to track the flush batch. It will grow as big as
it needs to be and then stop, so it shouldn't be reallocated.
The state manager holds a reference to the d3d device.
- cmaughan@nvidia.com
******************************************************************************/
#ifndef __NVSTATEMANAGER_H
#define __NVSTATEMANAGER_H
#include "singleton.h"
#include "nvdebug.h"
namespace nv_objects
{
static const DWORD NVSTATEMANAGER_MAX_RENDERSTATES = 256;
static const DWORD NVSTATEMANAGER_MAX_TEXTURESTATES = 128;
static const DWORD NVSTATEMANAGER_MAX_STAGES = 8;
static const DWORD NVSTATEMANAGER_MAX_VCONSTANTS = 96;
static const DWORD NVSTATEMANAGER_MAX_PCONSTANTS = 8;
static const DWORD NVSTATEMANAGER_MAX_TRANSFORMSTATES = 300; // World1 lives way up there...
static const DWORD NVSTATEMANAGER_MAX_STREAMS = 16;
class NVStreamData
{
public:
NVStreamData(LPDIRECT3DVERTEXBUFFER8 pStreamData = NULL, UINT Stride = 0)
: m_pStreamData(pStreamData),
m_Stride(Stride)
{}
bool operator == (const NVStreamData& rhs) const { return ((m_pStreamData == rhs.m_pStreamData) && (m_Stride == rhs.m_Stride)); }
LPDIRECT3DVERTEXBUFFER8 m_pStreamData;
UINT m_Stride;
};
class NVIndexData
{
public:
NVIndexData(LPDIRECT3DINDEXBUFFER8 pIndexData = NULL, UINT BaseVertexIndex = 0)
: m_pIndexData(pIndexData),
m_BaseVertexIndex(BaseVertexIndex)
{}
bool operator == (const NVIndexData& rhs) const { return ((m_pIndexData == rhs.m_pIndexData) && (m_BaseVertexIndex == rhs.m_BaseVertexIndex)); }
LPDIRECT3DINDEXBUFFER8 m_pIndexData;
UINT m_BaseVertexIndex;
};
// State types managed by the class
typedef enum eStateType
{
STATE_MATERIAL = 0,
STATE_RENDER,
STATE_TEXTURE,
STATE_TEXTURESTAGE,
STATE_VSHADER,
STATE_PSHADER,
STATE_TRANSFORM,
STATE_VCONSTANT,
STATE_PCONSTANT,
STATE_STREAM,
STATE_INDEX
} eStateType;
class NVStateID
{
public:
NVStateID(eStateType Type, DWORD dwValue0 = 0, DWORD dwValue1 = 0)
: m_Type(Type),
m_dwValue0(dwValue0),
m_dwValue1(dwValue1)
{}
NVStateID(eStateType Type, DWORD dwStage, D3DTEXTURESTAGESTATETYPE StageType)
: m_Type(Type),
m_dwStage(dwStage),
m_TextureStageStateType(StageType)
{}
NVStateID(eStateType Type, D3DRENDERSTATETYPE RenderType)
: m_Type(Type),
m_RenderStateType(RenderType)
{}
eStateType m_Type;
union
{
DWORD m_dwValue0;
DWORD m_dwStage;
D3DRENDERSTATETYPE m_RenderStateType;
D3DTRANSFORMSTATETYPE m_TransformStateType;
};
union
{
DWORD m_dwValue1;
D3DTEXTURESTAGESTATETYPE m_TextureStageStateType;
};
};
typedef std::vector<NVStateID> tStateID;
class NVStateManagerState
{
public:
NVStateManagerState()
{
}
void ResetState()
{
DWORD i, y;
for (i = 0; i < NVSTATEMANAGER_MAX_RENDERSTATES; i++)
{
m_RenderStates[i] = 0;
}
for (i = 0; i < NVSTATEMANAGER_MAX_STAGES; i++)
{
for (y = 0; y < NVSTATEMANAGER_MAX_TEXTURESTATES; y++)
{
m_TextureStates[i][y] = 0;
}
}
for (i = 0; i < NVSTATEMANAGER_MAX_STREAMS; i++)
{
m_StreamData[i] = NVStreamData();
}
m_IndexData = NVIndexData();
for (i = 0; i < NVSTATEMANAGER_MAX_STAGES; i++)
{
m_Textures[i] = 0;
}
// Matrices and constants are not cached, just restored. It's silly to check all the
// data elements (by which time the driver could have been sent them).
for (i = 0; i < NVSTATEMANAGER_MAX_TRANSFORMSTATES; i++)
{
D3DXMatrixIdentity(&m_Matrices[i]);
}
for (i = 0; i < NVSTATEMANAGER_MAX_VCONSTANTS; i++)
{
m_VertexShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
}
for (i = 0; i < NVSTATEMANAGER_MAX_PCONSTANTS; i++)
{
m_PixelShaderConstants[i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
}
m_dwPixelShader = 0;
m_dwVertexShader = D3DFVF_XYZ;
ZeroMemory(&m_Matrices, sizeof(D3DXMATRIX) * NVSTATEMANAGER_MAX_TRANSFORMSTATES);
}
// Renderstates
DWORD m_RenderStates[NVSTATEMANAGER_MAX_RENDERSTATES];
// Texture stage states
DWORD m_TextureStates[NVSTATEMANAGER_MAX_STAGES][NVSTATEMANAGER_MAX_TEXTURESTATES];
// Vertex shader constants
D3DXVECTOR4 m_VertexShaderConstants[NVSTATEMANAGER_MAX_VCONSTANTS];
// Pixel shader constants
D3DXVECTOR4 m_PixelShaderConstants[NVSTATEMANAGER_MAX_PCONSTANTS];
// Textures
LPDIRECT3DBASETEXTURE8 m_Textures[NVSTATEMANAGER_MAX_STAGES];
// Shaders
DWORD m_dwPixelShader;
DWORD m_dwVertexShader;
D3DXMATRIX m_Matrices[NVSTATEMANAGER_MAX_TRANSFORMSTATES];
D3DMATERIAL8 m_D3DMaterial;
NVStreamData m_StreamData[NVSTATEMANAGER_MAX_STREAMS];
NVIndexData m_IndexData;
};
class NVStateManager : public Singleton <NVStateManager>
{
public:
NVStateManager(LPDIRECT3DDEVICE8 pDevice)
: m_pD3DDev(pDevice)
{
NVASSERT(pDevice, "Invalid device!");
pDevice->AddRef();
SetDefaultState();
}
virtual ~NVStateManager()
{
SAFE_RELEASE(m_pD3DDev);
}
virtual void SetDefaultState()
{
m_CurrentState.ResetState();
m_CopyState.ResetState();
m_ChipState.ResetState();
m_bForce = true;
D3DXMATRIX Identity;
D3DXMatrixIdentity(&Identity);
SetTransform(D3DTS_WORLD, &Identity);
SetTransform(D3DTS_VIEW, &Identity);
SetTransform(D3DTS_PROJECTION, &Identity);
D3DMATERIAL8 DefaultMat;
ZeroMemory(&DefaultMat, sizeof(D3DMATERIAL8));
DefaultMat.Diffuse.r = 1.0f;
DefaultMat.Diffuse.g = 1.0f;
DefaultMat.Diffuse.b = 1.0f;
DefaultMat.Diffuse.a = 1.0f;
SetMaterial(&DefaultMat);
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_LINEPATTERN, 0xFFFFFFFF);
SetRenderState(D3DRS_LASTPIXEL, FALSE);
SetRenderState(D3DRS_ALPHAREF, 0);
SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS);
SetRenderState(D3DRS_ZVISIBLE, FALSE);
SetRenderState(D3DRS_FOGSTART, 0);
SetRenderState(D3DRS_FOGEND, 0);
SetRenderState(D3DRS_FOGDENSITY, 0);
SetRenderState(D3DRS_EDGEANTIALIAS, FALSE);
SetRenderState(D3DRS_ZBIAS, 0);
SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
SetRenderState(D3DRS_AMBIENT, 0x00000000);
SetRenderState(D3DRS_LOCALVIEWER, FALSE);
SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
SetRenderState(D3DRS_COLORWRITEENABLE, 0xFFFFFFFF);
SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_FOGENABLE, FALSE);
SetRenderState(D3DRS_FOGCOLOR, 0xFF0000);
SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE );
SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR );
SetRenderState(D3DRS_RANGEFOGENABLE, FALSE );
SetRenderState(D3DRS_ZENABLE, TRUE);
SetRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL);
SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
SetRenderState(D3DRS_DITHERENABLE, TRUE);
SetRenderState(D3DRS_STENCILENABLE, FALSE);
SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
SetRenderState(D3DRS_CLIPPING, TRUE);
SetRenderState(D3DRS_LIGHTING, FALSE);
SetRenderState(D3DRS_SPECULARENABLE, FALSE);
SetRenderState(D3DRS_COLORVERTEX, FALSE);
SetRenderState(D3DRS_WRAP0, 0);
SetRenderState(D3DRS_WRAP1, 0);
SetRenderState(D3DRS_WRAP2, 0);
SetRenderState(D3DRS_WRAP3, 0);
SetRenderState(D3DRS_WRAP4, 0);
SetRenderState(D3DRS_WRAP5, 0);
SetRenderState(D3DRS_WRAP6, 0);
SetRenderState(D3DRS_WRAP7, 0);
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -