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

📄 shader_modelview.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	NVComplexMeshBounds Bounds;
	m_pMesh->ComputeBounds(Bounds);
	m_pMesh->Translate(-Bounds.m_vecCenter);
	m_pMesh->Scale(1.0f / Bounds.m_fRadius);

	UpdateMeshMaterials();

	// Prepare the mesh for rendering
	hr = m_pMesh->PrepareDeviceObjects(m_pD3DDev);
	if (FAILED(hr))
	{
		m_strLastError = "Loaded, but can't render " + m_strFileName;
		MessageBox(NULL, m_strLastError.c_str(), "Error", MB_ICONEXCLAMATION);
		SAFE_DELETE(m_pMesh);
		return E_FAIL;
	}

	return S_OK;
}

HRESULT CShaderModelView::UpdateMeshMaterials()
{
	// Get a list of sections.  We assume we only have pass1, because we created the mesh from
	// a mesh file
	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 = NVMaterialResource::GetMaterialResource(itrSections->GetMaterialID());
		if (pMaterial)
		{
			NVConstant* pConstant;

			// Tell the mesh where to place it's constants
			pConstant = pMaterial->FindConstant("diffuse");
			if (pConstant)
				pConstant->SetLocation(CV_MAT_DIFFUSE);

			pConstant = pMaterial->FindConstant("ambient");
			if (pConstant)
				pConstant->SetLocation(CV_MAT_AMBIENT);
			
			pConstant = pMaterial->FindConstant("specular");
			if (pConstant)
			{
				pMaterial->AddRenderState(D3DRS_SPECULARENABLE, TRUE);
				pConstant->SetLocation(CV_MAT_SPECULAR);
			}
			else
			{
				pMaterial->AddRenderState(D3DRS_SPECULARENABLE, FALSE);
			}
			
			pConstant = pMaterial->FindConstant("power");
			if (pConstant)
				pConstant->SetLocation(CV_MAT_POWER);

			pMaterial->RestoreTexture(0);
			if (m_bHasTexture)
			{
				if (m_bDirectionalBump)
				{
					// Setup the vertex shader
					pMaterial->AddVertexShader(m_dwDirectionalLightBumpShader);

					// Setup texture properties
					pMaterial->AddTexture(0, NVRESOURCEMANAGER.FindResourceID("DefaultBumpMap"));
					pMaterial->AddTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
					pMaterial->AddTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					pMaterial->AddTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
					pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
					pMaterial->AddTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
					pMaterial->AddTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
			
					// Stage 1 has the base texture.
					// Modulate the bump output from the previous stage by the current texture
					// Use 2x to brighten it up a bit.
					pMaterial->AddTexture(1, NVRESOURCEMANAGER.FindResourceID("DefaultBaseTexture"));
					pMaterial->AddTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1  );
					pMaterial->AddTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					pMaterial->AddTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
					pMaterial->AddTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
					pMaterial->AddTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
				}
				else
				{
					pMaterial->AddTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
					pMaterial->AddTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
					pMaterial->AddTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
					pMaterial->AddTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

					pMaterial->AddVertexShader(m_dwDirectionalLightShader);

					if (NVTextureResource::GetTexture(pMaterial->GetTextureID(0)) != NULL)
					{
						pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);	
					}
					else
					{
						pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);	
					}

					pMaterial->AddTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
				}
			}
			else
			{
				pMaterial->AddVertexShader(m_dwDirectionalLightShader);

				pMaterial->AddTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
				pMaterial->AddTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
				pMaterial->AddTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
				pMaterial->AddTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);

				pMaterial->AddTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
			}

		}
		itrSections++;
	}

	return S_OK;
}

HRESULT CShaderModelView::SetVertexShaderMatrices()
{
	D3DXMATRIX WorldViewProjection, WorldViewIT, World;
	
	D3DXMatrixMultiply(&World, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix());
	D3DXMatrixMultiply(&WorldViewProjection, &World, &m_matView);
	D3DXMatrixInverse(&WorldViewIT, NULL, &WorldViewProjection);

	D3DXMatrixMultiply(&WorldViewProjection, &WorldViewProjection, &m_matProjection);
	D3DXMatrixTranspose(&WorldViewProjection, &WorldViewProjection);
	
	NVStateManager::GetSingleton().SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &WorldViewProjection, 4);
	NVStateManager::GetSingleton().SetVertexShaderConstant(CV_WORLDVIEWIT_0, &WorldViewIT, 4);
	
	// Transform direction vector into eye space
	D3DXVECTOR3 vLight = D3DXVECTOR3(0.3f, 0.0f, 1.0f);
	
	D3DXVECTOR3 vLightToEye;
	D3DXVec3Normalize(&vLightToEye, &vLight);
	D3DXVec3TransformNormal(&vLightToEye, &vLightToEye, &m_matView);
	D3DXVec3Normalize(&vLightToEye, &vLightToEye);

	// Shader math requires vector towards light
	D3DXVECTOR4 vLightEye;
	vLightEye.x = -vLightToEye.x;
	vLightEye.y = -vLightToEye.y;
	vLightEye.z = -vLightToEye.z;
	vLightEye.w = 1.0f;

	NVStateManager::GetSingleton().SetVertexShaderConstant(CV_LIGHT1_DIRECTION, &vLightEye, 1);

	D3DXMatrixTranspose(&World, &World);
	NVStateManager::GetSingleton().SetVertexShaderConstant(CV_WORLD_0, &World, 4);

	return S_OK;
}

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

	if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
	{
		if (pProperty->GetPropertyName().compare("Flip Normals") == 0)
		{
			if (m_pMesh)
				m_pMesh->FlipNormals();
		
			// Prepare the mesh for rendering
			m_pMesh->PrepareDeviceObjects(m_pD3DDev);

		}
		else
		{
			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)
			{
				LoadMesh(&FileName[0]);
			}
			else
			{
				// Might be OK if the user hit cancel
				DWORD dwErr = CommDlgExtendedError();
			}
		}
	}
	else
	{
		if (pProperty->GetPropertyName().compare(STR_DIRECTIONALBUMP) == 0)
		{
			UpdateMeshMaterials();
		}
	}

}

// ------------------------------------------------------------------------------
// CShaderModelView::Free
//
// Description: Called when we switch away from this demo.	Free up all the 
//		memory that is in use.
// ------------------------------------------------------------------------------ 
HRESULT CShaderModelView::Free()
{
	SAFE_DELETE(m_pMesh);

	if (m_pD3DDev)
	{
		if (m_dwDirectionalLightShader)
			m_pD3DDev->DeleteVertexShader(m_dwDirectionalLightShader);
		if (m_dwDirectionalLightBumpShader)
			m_pD3DDev->DeleteVertexShader(m_dwDirectionalLightBumpShader);

		m_dwDirectionalLightShader = 0;
		m_dwDirectionalLightBumpShader = 0;

		SAFE_RELEASE(m_pD3DDev);
	}
	delete m_pUI, m_pUI = 0;

	SAFE_DELETE(g_pStateManager);
	SAFE_DELETE(g_pResourceManager);
	
	return S_OK;
}

// ------------------------------------------------------------------------------
// CShaderModelView::Start
//
// Description: Called to reset
// ------------------------------------------------------------------------------ 
HRESULT CShaderModelView::Start()
{
	return S_OK;
}

// ------------------------------------------------------------------------------
// CShaderModelView::Tick
//
// Description: This function is called every frame.  Here is where we write
//		and update constants, clear the z- and back-buffer and render our 
//		primitives
// ------------------------------------------------------------------------------ 
HRESULT CShaderModelView::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;

	SetVertexShaderMatrices();

	NVSTATEMANAGER.SetRenderState(D3DRS_FILLMODE, (m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID));

	m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00BFBFBF, 1.0f, 0L);

	if (m_pMesh)
		m_pMesh->Render(m_pD3DDev);

	return hr;
}

void CShaderModelView::MouseButton(HWND hWnd, eButtonID button, bool bDown, int x, int y)
{
	if(button == MOUSE_LEFTBUTTON)
	{
		if(bDown)
		{
			m_pUI->OnLButtonDown(x, y);
		}
		else
		{
			m_pUI->OnLButtonUp(x, y);
		}
	}
	return;
}

void CShaderModelView::MouseMove(HWND hWnd, int x, int y)
{
	m_pUI->OnMouseMove(x, y);
	return;
}

void CShaderModelView::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
	eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);

	switch(Action)
	{
		case EB_HELP:
		{
	        MessageBoxEx( NULL, " Help : F1 - Help \n\n Home - Reset To Defaults \n\n W - Wireframe Toggle \n\n Space\\Pause - Toggle Pause/Resume \n\n Left Button & Mouse - Rotate Object\n\n Shift Left Button & Mouse - Pan Camera \n\n Ctrl Left Button & Mouse - Move Camera In & Out\n\n",
			   "Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
		}
		break;

		case EB_RESET:
		{
			m_pUI->Reset();
		}
		break;

		case EB_PAUSE:
		{
			m_bPause = !m_bPause;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
		}
		break;

		case EB_WIREFRAME:
		{
			m_bWireframe = !m_bWireframe;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
		
		}
		break;

		default:
			break;
	}
}

⌨️ 快捷键说明

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