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

📄 shader_linkerdemo.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if (dwLocation != NVLINK_NOT_USED)
		{
			m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
			pVertexData->SetLocation(dwStreamPosition++);
		}
		else
		{
			pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
		}
	}

	pVertexData = m_pMesh->FindVertexData("sbasis0");
	if (pVertexData)
	{
		m_pLinker->GetVertexSlot(m_VertexID[V_SBASIS0], &dwLocation);
		if (dwLocation != NVLINK_NOT_USED)
		{
			m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
			pVertexData->SetLocation(dwStreamPosition++);
		}
		else
		{
			pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
		}
	}
	pVertexData = m_pMesh->FindVertexData("tbasis0");
	if (pVertexData)
	{
		m_pLinker->GetVertexSlot(m_VertexID[V_TBASIS0], &dwLocation);
		if (dwLocation != NVLINK_NOT_USED)
		{
			m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
			pVertexData->SetLocation(dwStreamPosition++);
		}
		else
		{
			pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
		}
	}

	pVertexData = m_pMesh->FindVertexData("sxtbasis0");
	if (pVertexData)
	{
		m_pLinker->GetVertexSlot(m_VertexID[V_SXTBASIS0], &dwLocation);
		if (dwLocation != NVLINK_NOT_USED)
		{
			m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
			pVertexData->SetLocation(dwStreamPosition++);
		}
		else
		{
			pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
		}
	}

	for (DWORD i = 0; i < NV_MAX_TEXTURES; i++)
	{
		string strBuff;
  		strBuff.resize(2);
  		ultoa(i, &strBuff[0], 2);
  		string texname = "texture" + strBuff;
  		texname = texname.substr(0, strlen(texname.c_str()));

		pVertexData = m_pMesh->FindVertexData(texname.c_str());
		if (pVertexData)
		{
			if (i == 0)
			{
				// We have chosen to place texture 0 at a fixed location.
				dwLocation = FIXED_TEXTURE0_LOCATION;
			}
			else
			{
				m_pLinker->GetVertexSlot(m_VertexID[V_TEXTURE0 + i], &dwLocation);
			}

			if (dwLocation != NVLINK_NOT_USED)
			{
				m_MeshDeclaration.push_back(D3DVSD_REG(dwLocation, pVertexData->GetDataType()));
				pVertexData->SetLocation(dwStreamPosition++);
			}
			else
			{
				pVertexData->SetLocation(NVCOMPLEXMESH_NO_VERTEX);
			}
		}
	}

	// Finish the decleration and create the shader
	m_MeshDeclaration.push_back(D3DVSD_END());
}

HRESULT CShaderLinkerDemo::UpdateShader()
{
	HRESULT hr;
	std::string strOutFile;
	HANDLE hFile;
	DWORD dwNumWritten;
	DWORD dwLocation;
	DWORD i;

	if (m_dwPass0Shader)
	{
		m_pD3DDev->DeleteVertexShader(m_dwPass0Shader);
		m_dwPass0Shader = 0;
	}

	if (m_dwPass1Shader)
	{
		m_pD3DDev->DeleteVertexShader(m_dwPass1Shader);
		m_dwPass1Shader = 0;
	}

	// Force a change to a default vertex shader because the deletes above will upset us otherwise.
	NVSTATEMANAGER.SetVertexShader(D3DFVF_XYZ);
	NVSTATEMANAGER.FlushVertexShader();

	// Create the required shader.
	// ThisShader is an array of DWORDS that can grow.  Each push_back call adds another DWORD to the array.
	// STL is nice like this because it eliminates stupid errors with over-filling arrays.  Of course the drawback
	// is dynamic allocation, but this is a demo and I'm going for simple.
	// The DWORD's we put in are the ID's of the shader components we want to build.

	// You can get as intricate as you like about how the shader is layed out.  The linker will automatically remove
	// the redundant instructions, but you should make every effort to remove redundant code for speed.
	
	vector<DWORD>ThisShader;

	DWORD dwNumLights = m_DirectionalLights.size() + m_PointLights.size();
	bool bNeedLighting = m_Settings.m_bLighting && (dwNumLights > 0);
	bool bNeedSpecular = m_Settings.m_bSpecular && bNeedLighting;
	bool bNeedTexture = m_Settings.m_bTextures && m_bHasTextureCoords;
	bool bNeedCubeReflection = (m_Settings.m_TexGen == TEXGEN_CAMERASPACEREFLECTION) && bNeedTexture;
	bool bNeedFog = (m_Settings.m_Fog != FOG_NONE);
	bool bNeedRDotL = bNeedSpecular && m_Settings.m_bSpecularRDotL;
	bool bNeedEyeReflection = bNeedCubeReflection || bNeedRDotL;
	bool bNeedNormal = bNeedLighting || bNeedCubeReflection;
	bool bNeedVertex = bNeedLighting || bNeedCubeReflection || bNeedFog;
	bool bNeedEyeVector = (bNeedSpecular && (m_Settings.m_bLocalViewer || m_Settings.m_bSpecularRDotL)) || (bNeedCubeReflection) || (bNeedFog);
	bool bNeedBasis = (m_Settings.m_TexGen == TEXGEN_BLINNBUMPREFLECTION) && bNeedTexture;
	bool bNeedLit = true;
	bool bFirstLight = true;
	bool bLastLight = false;

	ThisShader.push_back(m_FragmentID[F_XFORM_WORLDVIEWPROJECTION]);

	if (m_Settings.m_bEyeSpace)
	{
		// Create some things we need
		if (bNeedVertex)
			ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_VERTEX]);
		
		// Specular and reflections require an eye vector
		if (bNeedEyeVector)
			ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_EYEVECTOR_LOCAL_VIEWER]);
		
		// Reflections and lights require a normal
		if (bNeedNormal)
			ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_NORMAL]);
		
		if (bNeedFog)
			ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);

		if (bNeedEyeReflection)
		{
			// Camera space reflection is always done with local viewer.  This is practical because it can look
			// pretty aweful without it.
			ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_REFLECTION]);
		}

		// If texgen is on, apply it
		if (bNeedCubeReflection)
		{
			ThisShader.push_back(m_FragmentID[F_CALCULATE_CUBEREFLECTION_VECTOR]);
		}

		
		if (bNeedLighting)
		{
			// Add the ambient color, and setup the specular power if needed
			ThisShader.push_back(m_FragmentID[F_SET_AMBIENT]);
			if (bNeedSpecular)
			{
				ThisShader.push_back(m_FragmentID[F_SET_POWER]);
			}

			tLightList::const_iterator itrLights = m_DirectionalLights.begin();
			while (itrLights != m_DirectionalLights.end())
			{
				if (m_PointLights.empty() && ((itrLights + 1) == m_DirectionalLights.end()))
				{
					bLastLight = true;
				}

				// Add a directional light fragment
				if (bNeedSpecular)
				{
					if (m_Settings.m_bSpecularRDotL)
					{
						ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
					}
					else
					{
						if (m_Settings.m_bLocalViewer)
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
						}
						else
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
						}
					}
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_DIRECTIONALLIGHT_DIFFUSE_INTENSITY]);
				}

				if (bNeedLit)
				{
					ThisShader.push_back(m_FragmentID[F_CLAMP_DIFFUSE_EXPONENTIATE_SPECULAR]);
				}

				if (bLastLight)
				{
					ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE_LAST]);
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_DIFFUSE]);
				}

				if (bNeedSpecular)
				{
					if (bFirstLight && bLastLight)
					{
						ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
					}
					else if (bFirstLight)
					{
						ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_FIRST]);
					}
					else if (bLastLight)
					{
						ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR_LAST]);
					}
					else
					{
						ThisShader.push_back(m_FragmentID[F_DIRLIGHT_ACCUMULATE_SPECULAR]);
					}
				}

				bFirstLight = false;

				itrLights++;
			}

			itrLights = m_PointLights.begin();
			while (itrLights != m_PointLights.end())
			{
				if ((itrLights + 1) == m_PointLights.end())
				{
					bLastLight = true;
				}

				ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_VECTOR]);
				
				if (bNeedSpecular)
				{
					if (m_Settings.m_bSpecularRDotL)
					{
						ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
					}
					else
					{
						if (m_Settings.m_bLocalViewer)
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
						}
						else
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
						}
					}
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_CALCULATE_EYESPACE_POINTLIGHT_DIFFUSE_INTENSITY]);
				}

				if (bNeedLit)
				{
					ThisShader.push_back(m_FragmentID[F_CLAMP_DIFFUSE_EXPONENTIATE_SPECULAR]);
				}

				if (bLastLight)
				{
					ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE_LAST]);
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_DIFFUSE]);
				}

				if (bNeedSpecular)
				{
					if (bFirstLight && bLastLight)
					{
						ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST_AND_LAST]);
					}
					else if (bFirstLight)
					{
						ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_FIRST]);
					}
					else if (bLastLight)
					{
						ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR_LAST]);
					}
					else
					{
						ThisShader.push_back(m_FragmentID[F_POINTLIGHT_ACCUMULATE_SPECULAR]);
					}
				}

				bFirstLight = false;

				itrLights++;
			}
		}

		if (bNeedBasis)
		{
			ThisShader.push_back(m_FragmentID[F_CALCULATE_BASIS_VECTORS]);
		}
	}
	else
	// object space
	{
		if (bNeedEyeVector)
			ThisShader.push_back(m_FragmentID[F_CREATE_OBJECTSPACE_EYEVECTOR_LOCAL_VIEWER]);

		if (bNeedEyeReflection)
		{
			// Camera space reflection is always done with local viewer.  This is practical because it can look
			// pretty aweful without it.
			ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_REFLECTION]);
		}

		// If texgen is on, apply it
		if (bNeedCubeReflection)
		{
			ThisShader.push_back(m_FragmentID[F_CALCULATE_CUBEREFLECTION_VECTOR]);
		}

		if (bNeedFog)
			ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);

		if (bNeedLighting)
		{
			// Add the ambient color, and setup the specular power if needed
			ThisShader.push_back(m_FragmentID[F_SET_AMBIENT]);
			if (bNeedSpecular)
			{
				ThisShader.push_back(m_FragmentID[F_SET_POWER]);
			}

			tLightList::const_iterator itrLights = m_DirectionalLights.begin();
			while (itrLights != m_DirectionalLights.end())
			{
				if (m_PointLights.empty() && ((itrLights + 1) == m_DirectionalLights.end()))
				{
					bLastLight = true;
				}

				// Add a directional light fragment
				if (bNeedSpecular)
				{
					if (m_Settings.m_bSpecularRDotL)
					{
						ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
					}
					else
					{
						if (m_Settings.m_bLocalViewer)
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
						}

⌨️ 快捷键说明

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