⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvstatemanager.h

📁 游戏编程精华02-含有几十个游戏编程例子
💻 H
📖 第 1 页 / 共 3 页
字号:
		{
			NVASSERT((dwRegister + i) < NVSTATEMANAGER_MAX_VCONSTANTS, "ERROR: Constant out of range!");
			m_DirtyStates.push_back(NVStateID(STATE_VCONSTANT, dwRegister + i));
			m_CurrentState.m_VertexShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
		}
	}

	// SetPixelShaderConstant
	virtual void SavePixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
	{
		DWORD i;
		for (i = 0; i < dwConstantCount; i++)
		{
			NVASSERT((dwRegister + i) < NVSTATEMANAGER_MAX_PCONSTANTS, "ERROR: Constant out of range!");

			m_CopyState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
		}
		SetPixelShaderConstant(dwRegister, pConstantData, dwConstantCount);
	}

	virtual void RestorePixelShaderConstant(DWORD dwRegister, DWORD dwConstantCount)
	{
		SetPixelShaderConstant(dwRegister, &m_CopyState.m_PixelShaderConstants[dwRegister], dwConstantCount);
	}

	virtual void SetPixelShaderConstant(DWORD dwRegister,CONST void* pConstantData,DWORD dwConstantCount)
	{
		DWORD i;

		NVASSERT(pConstantData, "Pixel shader out of range");
		NVASSERT(dwRegister < NVSTATEMANAGER_MAX_PCONSTANTS, "pixel shader constant out of range");

		if (!m_bForce)
		{
			for (i = 0; i < dwConstantCount; i++)
			{
				NVASSERT((dwRegister + i) < NVSTATEMANAGER_MAX_PCONSTANTS, "ERROR: Constant out of range!");
				if (m_CurrentState.m_PixelShaderConstants[dwRegister + i] != *(((D3DXVECTOR4*)pConstantData + i)))
					break;
			}

			if (i == dwConstantCount)
				return;
		}

		// Set the renderstate and remember it.
		for (i = 0; i < dwConstantCount; i++)
		{
			NVASSERT((dwRegister + i) < NVSTATEMANAGER_MAX_PCONSTANTS, "ERROR: Constant out of range!");
			m_DirtyStates.push_back(NVStateID(STATE_PCONSTANT, dwRegister + i));
			m_CurrentState.m_PixelShaderConstants[dwRegister + i] = *(((D3DXVECTOR4*)pConstantData) + i);
		}
	}

	void SaveStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData,UINT Stride)
	{
		// Check that we have set this up before, if not, the default is this.
		m_CopyState.m_StreamData[StreamNumber] = m_CurrentState.m_StreamData[StreamNumber];
		SetStreamSource(StreamNumber, pStreamData, Stride);
	}

	void RestoreStreamSource(UINT StreamNumber)
	{
		SetStreamSource(StreamNumber, m_CopyState.m_StreamData[StreamNumber].m_pStreamData, m_CopyState.m_StreamData[StreamNumber].m_Stride);
	}

	void SetStreamSource(UINT StreamNumber, LPDIRECT3DVERTEXBUFFER8 pStreamData,UINT Stride)
	{
		if (!m_bForce && m_CurrentState.m_StreamData[StreamNumber] == NVStreamData(pStreamData, Stride))
		{
			return;
		}
		m_DirtyStates.push_back(NVStateID(STATE_STREAM, (DWORD)StreamNumber));
		m_CurrentState.m_StreamData[StreamNumber] = NVStreamData(pStreamData, Stride);
	}

	void SaveIndices(LPDIRECT3DINDEXBUFFER8 pIndexData, UINT BaseVertexIndex)
	{
		m_CopyState.m_IndexData = m_CurrentState.m_IndexData;
		SetIndices(pIndexData, BaseVertexIndex);
	}

	void RestoreIndices()
	{
		SetIndices(m_CopyState.m_IndexData.m_pIndexData, m_CopyState.m_IndexData.m_BaseVertexIndex);
	}

    void SetIndices(LPDIRECT3DINDEXBUFFER8 pIndexData,UINT BaseVertexIndex)
	{
		if (!m_bForce && m_CurrentState.m_IndexData == NVIndexData(pIndexData, BaseVertexIndex))
		{
			return;
		}

		m_DirtyStates.push_back(NVStateID(STATE_INDEX));
		m_CurrentState.m_IndexData = NVIndexData(pIndexData, BaseVertexIndex);
	}

#ifdef _DEBUG
	void Debug_DumpFlushStates(DWORD DebugLevel)
	{
		tStateID::const_iterator itrDirtyStates = m_DirtyStates.begin();
		while (itrDirtyStates != m_DirtyStates.end())
		{
			const NVStateID& ThisState = *itrDirtyStates;
			switch(ThisState.m_Type)
			{
				case STATE_RENDER:
					DISPDBG(DebugLevel, "RENDERSTATE:" << ThisState.m_RenderStateType);
					break;
				case STATE_TEXTURE:
					DISPDBG(DebugLevel, "TEXTURE:" << ThisState.m_dwValue0);
					break;
				case STATE_TEXTURESTAGE:
					DISPDBG(DebugLevel, "TEXTURESTAGESTATE:" << ThisState.m_dwStage << "," << ThisState.m_TextureStageStateType);
					break;
				case STATE_VSHADER:
					DISPDBG(DebugLevel, "VERTEXSHADER:" << ThisState.m_dwValue0);
					break;
				case STATE_PSHADER:
					DISPDBG(DebugLevel, "PIXELSHADER:" << ThisState.m_dwValue0);
					break;
				case STATE_TRANSFORM:
					DISPDBG(DebugLevel, "TRANSFORM:" << ThisState.m_TransformStateType);
					break;
				case STATE_VCONSTANT:
					DISPDBG(DebugLevel, "VERTEXSHADERCONSTANT:" << ThisState.m_dwValue0);
					break;
				case STATE_PCONSTANT:
					DISPDBG(DebugLevel, "PIXELSHADERCONSTANT:" << ThisState.m_dwValue0);
					break;
				case STATE_STREAM:
					DISPDBG(DebugLevel, "STREAM:" << ThisState.m_dwValue0);
					break;
				case STATE_INDEX:
					DISPDBG(DebugLevel, "INDEX");
					break;
			}
			
			itrDirtyStates++;
		}
	}
#define DEBUG_DUMPFLUSHSTATES(a) Debug_DumpFlushStates(a)
#else
#define DEBUG_DUMPFLUSHSTATES(a)
#endif

	void FlushVertexShader()
	{
		CHECK_D3DAPI(m_pD3DDev->SetVertexShader(m_CurrentState.m_dwVertexShader));
		m_ChipState.m_dwVertexShader = m_CurrentState.m_dwVertexShader;
	}

	void FlushPixelShader()
	{
		CHECK_D3DAPI(m_pD3DDev->SetPixelShader(m_CurrentState.m_dwPixelShader));
		m_ChipState.m_dwPixelShader = m_CurrentState.m_dwPixelShader;
	}

	void FlushState()
	{
		DWORD dwWrittenStates = 0;

		DISPDBG(10, "Flushing " << m_DirtyStates.size() << " States");
		
		DEBUG_DUMPFLUSHSTATES(10);

		tStateID::const_iterator itrDirtyStates = m_DirtyStates.begin();
		while (itrDirtyStates != m_DirtyStates.end())
		{
			const NVStateID& ThisState = *itrDirtyStates;
			switch(ThisState.m_Type)
			{
				case STATE_MATERIAL:
				{
					dwWrittenStates++;
					m_ChipState.m_D3DMaterial = m_CurrentState.m_D3DMaterial;
					CHECK_D3DAPI(m_pD3DDev->SetMaterial(&m_CurrentState.m_D3DMaterial));
				}
				break;

				case STATE_RENDER:
				{
					if (m_bForce || (m_ChipState.m_RenderStates[ThisState.m_RenderStateType] != m_CurrentState.m_RenderStates[ThisState.m_RenderStateType]))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetRenderState(ThisState.m_RenderStateType, m_CurrentState.m_RenderStates[ThisState.m_RenderStateType]));
						m_ChipState.m_RenderStates[ThisState.m_RenderStateType] = m_CurrentState.m_RenderStates[ThisState.m_RenderStateType];
					}
				}
				break;

				case STATE_TEXTURE:
				{
					if (m_bForce || (m_ChipState.m_Textures[ThisState.m_dwValue0] != m_CurrentState.m_Textures[ThisState.m_dwValue0]))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetTexture(ThisState.m_dwValue0, m_CurrentState.m_Textures[ThisState.m_dwValue0]));
						m_ChipState.m_Textures[ThisState.m_dwValue0] = m_CurrentState.m_Textures[ThisState.m_dwValue0];
					}
				}
				break;

				case STATE_TEXTURESTAGE:
				{
					if (m_bForce || (m_ChipState.m_TextureStates[ThisState.m_dwStage][ThisState.m_TextureStageStateType] != m_CurrentState.m_TextureStates[ThisState.m_dwStage][ThisState.m_TextureStageStateType]))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetTextureStageState(ThisState.m_dwStage, ThisState.m_TextureStageStateType, m_CurrentState.m_TextureStates[ThisState.m_dwStage][ThisState.m_TextureStageStateType]));
						m_ChipState.m_TextureStates[ThisState.m_dwStage][ThisState.m_TextureStageStateType] = m_CurrentState.m_TextureStates[ThisState.m_dwStage][ThisState.m_TextureStageStateType];
					}
				}
				break;

				case STATE_VSHADER:
				{
					if (m_bForce || (m_ChipState.m_dwVertexShader != m_CurrentState.m_dwVertexShader))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetVertexShader(m_CurrentState.m_dwVertexShader));
						m_ChipState.m_dwVertexShader = m_CurrentState.m_dwVertexShader;
					}
				}
				break;

				case STATE_PSHADER:
				{
					if (m_bForce || (m_ChipState.m_dwPixelShader != m_CurrentState.m_dwPixelShader))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetPixelShader(m_CurrentState.m_dwPixelShader));
						m_ChipState.m_dwPixelShader = m_CurrentState.m_dwPixelShader;
					}
				}
				break;

				// Always set this one
				case STATE_TRANSFORM:
				{
					dwWrittenStates++;
					CHECK_D3DAPI(m_pD3DDev->SetTransform(ThisState.m_TransformStateType, &m_CurrentState.m_Matrices[ThisState.m_TransformStateType]));
					m_ChipState.m_Matrices[ThisState.m_TransformStateType] = m_CurrentState.m_Matrices[ThisState.m_TransformStateType];
				}
				break;
					
				case STATE_VCONSTANT:
				{
					if (m_bForce || (m_ChipState.m_VertexShaderConstants[ThisState.m_dwValue0] != m_CurrentState.m_VertexShaderConstants[ThisState.m_dwValue0]))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetVertexShaderConstant(ThisState.m_dwValue0, m_CurrentState.m_VertexShaderConstants[ThisState.m_dwValue0], 1));
						m_ChipState.m_VertexShaderConstants[ThisState.m_dwValue0] = m_CurrentState.m_VertexShaderConstants[ThisState.m_dwValue0];
					}
				}
				break;

				case STATE_PCONSTANT:
				{
					if (m_bForce || (m_ChipState.m_PixelShaderConstants[ThisState.m_dwValue0] != m_CurrentState.m_PixelShaderConstants[ThisState.m_dwValue0]))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetPixelShaderConstant(ThisState.m_dwValue0, m_CurrentState.m_PixelShaderConstants[ThisState.m_dwValue0], 1));
						m_ChipState.m_PixelShaderConstants[ThisState.m_dwValue0] = m_CurrentState.m_PixelShaderConstants[ThisState.m_dwValue0];
					}
				}
				break;
				
				case STATE_STREAM:
				{
					if (m_bForce || (!(m_ChipState.m_StreamData[ThisState.m_dwValue0] == m_CurrentState.m_StreamData[ThisState.m_dwValue0])))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetStreamSource(ThisState.m_dwValue0, m_CurrentState.m_StreamData[ThisState.m_dwValue0].m_pStreamData, m_CurrentState.m_StreamData[ThisState.m_dwValue0].m_Stride));
						m_ChipState.m_StreamData[ThisState.m_dwValue0] = m_CurrentState.m_StreamData[ThisState.m_dwValue0];
					}
				}
				break;

				case STATE_INDEX:
				{
					if (m_bForce || (!(m_ChipState.m_IndexData == m_CurrentState.m_IndexData)))
					{
						dwWrittenStates++;
						CHECK_D3DAPI(m_pD3DDev->SetIndices(m_CurrentState.m_IndexData.m_pIndexData, m_CurrentState.m_IndexData.m_BaseVertexIndex));
						m_ChipState.m_IndexData = m_CurrentState.m_IndexData;
					}
				}
				break;
			}
			itrDirtyStates++;
		}

		m_DirtyStates.clear();
		DISPDBG(10, "..." << dwWrittenStates << " Actually sent");

	}

    HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount)
	{
		FlushState();
		return (m_pD3DDev->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount));
	}

	HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount)
	{
		FlushState();
		return (m_pD3DDev->DrawIndexedPrimitive(PrimitiveType, minIndex, NumVertices, startIndex, primCount));
	}

	HRESULT DrawRectPatch(UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo)
	{
		FlushState();
		return (m_pD3DDev->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo));
	}

private:
	NVStateManagerState m_ChipState;
	NVStateManagerState m_CurrentState;
	NVStateManagerState m_CopyState;
	tStateID m_DirtyStates;
	bool m_bForce;

	LPDIRECT3DDEVICE8 m_pD3DDev;

};

#define NVSTATEMANAGER (NVStateManager::GetSingleton())


}; //nv_objects

#endif __NVSTATEMANAGER_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -