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

📄 shader_linkerdemo.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					{
						m_GeneratedNormalMapID = NVRESOURCEMANAGER.AddResource(new NVTextureNormalMapFromResource(m_pD3DDev, pMaterial->GetTextureID(0), (D3DFORMAT)MAKEFOURCC('N', 'V', 'H', 'S'), D3DPOOL_DEFAULT));
					}
					pMaterial->AddTexture(0, m_GeneratedNormalMapID);
				}
				else
				{
					pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("DefaultNormalMap"));
				}

				pMaterial->AddTexture(3, NVRESOURCEMANAGER.FindResourceID("CubeMap"));
				pMaterial->AddPixelShader(m_dwBumpPixelShader);
				pMaterial->AddTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
				pMaterial->AddTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);

			}
			else
			{
				pMaterial->RestoreTexture(0);
			}

			if ((pMaterial->GetTextureID(0) == NVINVALID_RESOURCEID) || !bNeedTexture)
			{
				pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
			}
			else
			{
				pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			}
		}
		itrSections++;
	}

	// Find second pass if there is one.  The sphere will have done this.
	if (m_pMesh->GetPass(1))
	{

		// Pass 2 is more simple, we just want the transform and the write of the texture coordinates
		ThisShader.clear();
		if (bNeedTexture)
		{
			ThisShader.push_back(m_FragmentID[F_WRITE_DEFAULT_TEXTURE]);
		}

		// Need to fog the decal
		if (bNeedFog)
		{
			// In eye space put the vertex down and calculate the eye vector
			if (m_Settings.m_bEyeSpace)
			{
				ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_VERTEX]);
				ThisShader.push_back(m_FragmentID[F_CREATE_EYESPACE_EYEVECTOR_LOCAL_VIEWER]);
			}
			// In object space get the eye vector 
			else
			{
				ThisShader.push_back(m_FragmentID[F_CREATE_OBJECTSPACE_EYEVECTOR_LOCAL_VIEWER]);
			}
			// Calculate the fog
			ThisShader.push_back(m_FragmentID[F_CALCULATE_LINEAR_RANGE_FOG]);
		}

		ThisShader.push_back(m_FragmentID[F_XFORM_WORLDVIEWPROJECTION]);
		ThisShader.push_back(0);

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

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

		// Now setup the mesh
		tSectionList& Sections = m_pMesh->GetPass(1)->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)
			{
				// Setup the vertex shader
				pMaterial->AddVertexShader(m_dwPass1Shader);

				string strGlossTexture;
				LPDIRECT3DTEXTURE8 pGlossTexture = NULL;

				pMaterial->AddRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
				pMaterial->AddRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
				pMaterial->AddRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

				// Add the default gloss map
				pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("DefaultGlossMap"));
				
				// Setup texture properties
				pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
			}
			itrSections++;
		}
	}

	// Prepare the mesh for rendering
	m_pMesh->PrepareDeviceObjects(m_pD3DDev);

	return S_OK;
}

HRESULT CShaderLinkerDemo::LoadMesh(const string& strFileName)
{
	int Pos = strFileName.find_last_of('.', strFileName.size());
	string strExtension = strFileName.substr(Pos + 1, strFileName.size() - Pos);

	if (m_pMesh)
	{
		SAFE_DELETE(m_pMesh);
	}

	if (m_GeneratedNormalMapID != NVINVALID_RESOURCEID)
	{
		NVRESOURCEMANAGER.RemoveResource(m_GeneratedNormalMapID);
		m_GeneratedNormalMapID = NVINVALID_RESOURCEID;
	}

	m_pMesh = new NVComplexMesh();

	bool bOK;
	if (strFileName == "")
	{
		bOK = m_pMesh->CreateFromSphere(1.0f, 40, 80, D3DXVECTOR3(1.0f, 1.0f, 1.0f), D3DXVECTOR2(1.0f, 1.0f));
		if (bOK)
		{
			m_pMesh->DuplicatePass(0, 1);
		}
	}
	else if (strExtension.compare("x") == 0)
	{
		bOK = m_pMesh->CreateFromXFile(m_pD3DDev, strFileName.c_str());
		if (bOK)
		{
			// If the model has texture coords...
			if (m_pMesh->FindVertexData("texture0"))
			{
				bool bFoundTex = false;

				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)
					{
						if (NVTextureResource::GetTexture(pMaterial->GetTextureID(0)) != NULL)
							bFoundTex = true;
					}
					itrSections++;
				}

				// This mesh has texture coords, but no texture.  We will be using the default NVIDIA bump
				// texture
				if (!bFoundTex)
				{
					// Add a second pass for the gloss map
					m_pMesh->DuplicatePass(0, 1);
				}
			}
		}
	}
	else if (strExtension.compare("m") == 0)
	{
		bOK = m_pMesh->CreateFromMFile(m_pD3DDev, strFileName.c_str());
	}
	else
	{
		assert(0);
		return E_FAIL;
	}

	if (!bOK)
	{
		SAFE_DELETE(m_pMesh);
		return E_FAIL;
	}
	m_strFileName = strFileName;

	// We require for the shader that these components are present.
	// If they are already there, then these calls won't do anything
	if (!m_pMesh->FindVertexData("normal"))
	{
		m_pMesh->AddVertexData("normal", NVCOMPLEXMESH_FLOAT3);
		m_pMesh->GenerateNormals();
	}

	if (m_pMesh->FindVertexData("texture0"))
	{
		// Add basis vectors.  We use the normal as our SxT vector
		m_pMesh->AddVertexData("sbasis0", NVCOMPLEXMESH_FLOAT3);
		m_pMesh->AddVertexData("tbasis0", NVCOMPLEXMESH_FLOAT3);
		m_pMesh->GenerateBasis(0);

		m_bHasTextureCoords = true;
		m_Settings.m_bEnableBump = m_bSupportsNormalMap;
		m_Settings.m_bEnableTextures = true;
	}
	else
	{
		m_bHasTextureCoords = false;
		m_Settings.m_bEnableBump = false;
		m_Settings.m_bTextures = false;
		m_Settings.m_bEnableTextures = false;
		m_Settings.m_TexGen = TEXGEN_NONE;
	}

	// Get the bounding info and scale the model
	NVComplexMeshBounds Bounds;
	m_pMesh->ComputeBounds(Bounds);
	m_pMesh->Translate(-Bounds.m_vecCenter);
	m_pMesh->Scale(0.8f / Bounds.m_fRadius);

	//m_pMesh->UnIndex();

	m_DialogFunc.SetSettings(&m_Settings);

	return S_OK;
}

void CShaderLinkerDemo::PropertyUpdateCallback(const EBProperty* pProperty, bool bWritten)
{
	if (!bWritten)
		return;

	if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
	{
		OPENFILENAME ofn;
		ZeroMemory(&ofn, sizeof(OPENFILENAME));
	
#define PATH_SIZE 2048
		char FileName[PATH_SIZE] = "";

		ofn.lStructSize = sizeof(OPENFILENAME);
		ofn.hwndOwner = NULL;
		ofn.hInstance = NULL;
		ofn.lpstrFilter = "Model Files (*.x, *.m)\0*.x;*.m\0\0";
		ofn.lpstrCustomFilter = NULL;
		ofn.nMaxCustFilter = 0;
		ofn.nFilterIndex = 0;
		ofn.lpstrFile = &FileName[0];
		ofn.nMaxFile = PATH_SIZE;
		ofn.lpstrFileTitle = NULL;
		ofn.nMaxFileTitle = 0;
		ofn.lpstrInitialDir = NULL;
		ofn.lpstrTitle = NULL;
		ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
		ofn.nFileOffset = 0;
		ofn.nFileExtension = 0;
		ofn.lpstrDefExt = NULL;

		int iSuccess = GetOpenFileName(&ofn);
		if (iSuccess > 0)
		{
			NVRESOURCEMANAGER.DisposeResources();
			LoadMesh(&FileName[0]);
		}
		else
		{
			// Might be OK if the user hit cancel
			DWORD dwErr = CommDlgExtendedError();
		}

		m_eDisplayOption = DISPLAY_MODEL;
		m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;

		UpdateShader();
		m_pUI->Reset();
	}
	else
	{
		EBString strProp = pProperty->GetPropertyName();
		if (strProp == EBString(STR_DISPLAYOPTIONS))
		{
			switch(m_eDisplayOption)
			{
				case DISPLAY_MODEL:
				{
					NVRESOURCEMANAGER.DisposeResources();
					LoadMesh(GetFilePath("bigship1.x"));
					UpdateShader();
					m_pUI->Reset();
				}
				break;
				case DISPLAY_SPHERE:
				{
					NVRESOURCEMANAGER.DisposeResources();
					LoadMesh("");
					UpdateShader();
					m_pUI->Reset();
				}
				break;
				default:
				{
					assert(0);
				}
				break;
			}
		}
	}
}

// ------------------------------------------------------------------------------
// CShaderLinkerDemo::Free
//
// Description: Called when we switch away from this demo.	Free up all the 
//		memory that is in use.
// ------------------------------------------------------------------------------ 
HRESULT CShaderLinkerDemo::Free()
{
	m_PointLights.clear();
	m_DirectionalLights.clear();
	FreeLightObjects();

	// Delete mesh
	SAFE_DELETE(m_pMesh);

	SAFE_RELEASE(m_pWorldBoxVertices);
	SAFE_RELEASE(m_pWorldBoxIndices);

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

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

		if (m_dwBumpPixelShader)
			m_pD3DDev->DeletePixelShader(m_dwBumpPixelShader);
		m_dwBumpPixelShader = 0;

		SAFE_RELEASE(m_pD3DDev);
	}
	
	// Free the linker and unload the library
	SAFE_RELEASE(m_pLinker);

	if (m_hLinker)
	{
		FreeLibrary(m_hLinker);
		m_hLinker = NULL;
	}

	delete m_pUI, m_pUI = 0;

	// Check the function pointer to ensure we got as far
	// as loading it.
	if (m_DialogFunc.Free)
	{
		m_DialogFunc.Free();
		ZeroMemory(&m_DialogFunc, sizeof(m_DialogFunc));
	}

	if (m_hDialog)
	{
		FreeLibrary(m_hDialog);
		m_hDialog = NULL;
	}

	// Final step, releas

⌨️ 快捷键说明

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