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

📄 shader_linkerdemo.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						else
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_DIRECTIONALLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
						}
					}
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_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_OBJECTSPACE_POINTLIGHT_VECTOR]);
				
				if (bNeedSpecular)
				{
					if (m_Settings.m_bSpecularRDotL)
					{
						ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_RDOTL]);
					}
					else
					{
						if (m_Settings.m_bLocalViewer)
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_LOCALVIEWER]);
						}
						else
						{
							ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_POINTLIGHT_DIFFUSE_AND_SPECULAR_INTENSITY_NONLOCALVIEWER]);
						}
					}
				}
				else
				{
					ThisShader.push_back(m_FragmentID[F_CALCULATE_OBJECTSPACE_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]);
		}

	}

	if (!bNeedLighting)
	{
		// Write out the final values.
		ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_DIFFUSE]);
	}

	if (bNeedTexture)
	{
		// If no texgen mode is on, write the texture coordinates out directly
		if(m_Settings.m_TexGen == TEXGEN_NONE)
		{
			ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_TEXTURE]);
		}
	}

	for (i = 0; i < ThisShader.size(); i++)
	{
		assert(ThisShader[i] != 0);
	}

	ThisShader.push_back(0);

	// Load the shader
	NVLinkBuffer* pShader;

	// Use this to reserve a range of constant/vertex registers - useful for indexed skinning, for example.
	// You can only have one range.
	// m_pLinker->ReserveConstantRange(3, 10);

	// Our vertex format will contain a position and a tex coord at 0 and 1.  To ensure that the linker
	// never allocates these registers to fragments that don't ever use FIXED_TEXTURE0, we reserve the 'slots'
	m_pLinker->ReserveVertexRange(0, 1);

	DWORD dwRet = m_pLinker->CreateBinaryShader(&ThisShader[0], &pShader);
	// In the failure case, update the text in the window
	if (dwRet != NVLINK_OK)
	{
		switch (dwRet)
		{
			case NVLINK_OUT_OF_MEMORY:
				m_strLastError = "Linker out of memory";
				break;

			case NVLINK_TOO_MANY_INSTRUCTIONS:
				m_strLastError = "Too many instructions";
				break;
			case NVLINK_TOO_MANY_ADDRESS_REGISTERS:
				m_strLastError = "Too many address registers required";
				break;

			case NVLINK_TOO_MANY_CONSTANTS:
				m_strLastError = "Too many constants required";
				break;
			
			case NVLINK_TOO_MANY_VERTICES:
				m_strLastError = "Too many vertex slots required";
				break;

			case NVLINK_TOO_MANY_REGISTERS:
				m_strLastError = "Too many temporary registers required";
				break;

			case NVLINK_NO_FRAGMENTS:
				m_strLastError = "Linker has no fragments";
				break;

			case NVLINK_INVALID_FRAGMENT:
				m_strLastError = "Invalid fragment ID passed to linker";
				break;

			default:
				m_strLastError = "Failed to link shader";
				break;
		}


		strOutFile = effect_api::GetModulePath() + "\\" + "output.nvv";
		hFile = CreateFile(strOutFile.c_str(), GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, 0, NULL);
		WriteFile(hFile, const_cast<char*>(m_strLastError.c_str()), m_strLastError.length(), &dwNumWritten, NULL);		
		CloseHandle(hFile);

		if (!m_bSetShaderToShow)
		{
			m_strEffectVertexShader = GetFilePath("output.nvv");
			m_bSetShaderToShow = true;
		}

		// Dirty the vertex shaders so the effects browser reloads the file
		m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_VERTEXSHADERS;

		return E_FAIL;
	}

	// Write the created shader's source text to an output file
	NVLinkBuffer* pShaderText = NULL;
	if (m_pLinker->GetShaderSource(&pShaderText) == NVLINK_OK)
	{
		strOutFile = effect_api::GetModulePath() + "\\" + "output.nvv";
		hFile = CreateFile(strOutFile.c_str(), GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, 0, NULL);
		WriteFile(hFile, pShaderText->GetPointer(), pShaderText->GetBufferSize(), &dwNumWritten, NULL);		
		CloseHandle(hFile);
		SAFE_RELEASE(pShaderText);

		if (!m_bSetShaderToShow)
		{
			m_strEffectVertexShader = GetFilePath("output.nvv");
			m_bSetShaderToShow = true;
		}

		// Dirty the vertex shaders so the effects browser reloads the file
		m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_VERTEXSHADERS;
	}

	UpdateMeshVertexSlots();

	// Store a list of constant slots for this shader
	for (i = 0; i < C_NUM_CONSTANTS; i++)
	{
		m_pLinker->GetConstantSlot(m_ConstantID[i], 0, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[i], 0)] = dwLocation;
	}

	//Special ones with offsets
	for (i = 0; i < m_PointLights.size(); i++)
	{
		m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_POSITION], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_POSITION], i)] = dwLocation;

		m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_DIFFUSE], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_DIFFUSE], i)] = dwLocation;

		m_pLinker->GetConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], i)] = dwLocation;

	}

	for (i = 0; i < m_DirectionalLights.size(); i++)
	{
		m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_DIRECTION], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_DIRECTION], i)] = dwLocation;

		m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_DIFFUSE], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_DIFFUSE], i)] = dwLocation;

		m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], i)] = dwLocation;

		m_pLinker->GetConstantSlot(m_ConstantID[C_DIRLIGHT_HALFVECTOR], i, &dwLocation);
		m_ConstantSlots[0][CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_HALFVECTOR], i)] = dwLocation;
	}

	DWORD* pBuff = (DWORD*)pShader->GetPointer();
	hr = m_pD3DDev->CreateVertexShader(&m_MeshDeclaration[0], (DWORD*)pShader->GetPointer(), &m_dwPass0Shader, 0);
	SAFE_RELEASE(pShader);
	if (FAILED(hr))
	{
		m_strLastError = "Failed CreateVertexShader on linked shader";
		return hr;
	}

	// Get a list of sections for pass 0
	tSectionList& Sections = m_pMesh->GetPass(0)->GetSections();
	tSectionList::iterator itrSections = Sections.begin();

	// Walk all the model sections in this pass
	while (itrSections != Sections.end())
	{
		// Set the constants and vertex shaders in this section
		NVMaterialResource* pMaterial = static_cast<NVMaterialResource*>(NVRESOURCEMANAGER.FindResource((*itrSections).GetMaterialID()));
		if (pMaterial)
		{
			NVConstant* pConstant;
			tConstantInfoToSlot::iterator itrConstant;

			// Make sure we have a specular and a power constant in the mesh
			pMaterial->AddConstant("specular", D3DXVECTOR4(0.3f, 0.3f, 0.3f, 0.0f), NV_NO_CONSTANT);
			pMaterial->AddConstant("power", D3DXVECTOR4(0.0f, 0.0f, 0.0f, 25.0f), NV_NO_CONSTANT);

			// Specular off by default
			pMaterial->AddRenderState(D3DRS_SPECULARENABLE, FALSE);

			// Tell the mesh where to place it's constants
			pConstant = pMaterial->FindConstant("diffuse");
			if (pConstant)
			{
				// Not loading the material into constant memory - we are premodulating it with
				// the light color - see the tick function.
				pConstant->SetLocation(NV_NO_CONSTANT);
			}

			pConstant = pMaterial->FindConstant("specular");
			if (pConstant)
			{
				// Not loading the material into constant memory - we are premodulating it with
				// the light color - see the tick function.
				pConstant->SetLocation(NV_NO_CONSTANT);

				if (bNeedSpecular)
				{
					// If we require any specular at all, enable the specular renderstate
					itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_POINTLIGHT_SPECULAR], 0));
					assert(itrConstant != m_ConstantSlots[0].end());
					if (itrConstant->second != NVLINK_NOT_USED)
					{
						pMaterial->AddRenderState(D3DRS_SPECULARENABLE, TRUE);
					}

					itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_DIRLIGHT_SPECULAR], 0));
					assert(itrConstant != m_ConstantSlots[0].end());
					if (itrConstant->second != NVLINK_NOT_USED)
					{
						pMaterial->AddRenderState(D3DRS_SPECULARENABLE, TRUE);
					}
				}
			}

			pConstant = pMaterial->FindConstant("power");
			if (pConstant)
			{
				itrConstant = m_ConstantSlots[0].find(CLinkerConstantSlot(m_ConstantID[C_MAT_POWER], 0));
				assert(itrConstant != m_ConstantSlots[0].end());
				if (itrConstant->second != NVLINK_NOT_USED)
				{
					pConstant->SetLocation(itrConstant->second);
				}
				else
				{
					pConstant->SetLocation(NV_NO_CONSTANT);
				}
			}

			// Setup the vertex shader, and turn off pixel shader by default
			pMaterial->AddVertexShader(m_dwPass0Shader);
			pMaterial->AddPixelShader(0);

			pMaterial->RestoreTexture(0);

			pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
			pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);

			if(bNeedCubeReflection)
			{
				pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("CubeMap"));
				pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
				pMaterial->AddTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);

			}
			else if (bNeedBasis)
			{
				string strNormalMapTexture;
				LPDIRECT3DBASETEXTURE8 pNormalMapTexture = NULL;
				
				// If the mesh has a texture, add a bumpmap for it
				if (NVTextureResource::GetTexture(pMaterial->GetTextureID(0)) != NULL)
				{
					if (m_GeneratedNormalMapID == NVINVALID_RESOURCEID)

⌨️ 快捷键说明

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