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

📄 shader_toonshade.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	D3DXMatrixMultiply(&worldViewProjMat, &worldViewProjMat, &m_proj);
	D3DXMatrixTranspose(&worldViewProjMat, &worldViewProjMat);
	
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &worldViewProjMat, 4);
	
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_IT_0, &worldITMat, 4);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &worldMat, 4);
	
	return S_OK;
}

// ------------------------------------------------------------------------------
// CShaderToonShade::Free
//
// Description: Called when we switch away from this demo.	Free up all the 
//		memory that is in use.
// ------------------------------------------------------------------------------ 
HRESULT CShaderToonShade::Free()
{
	SAFE_RELEASE(m_pVertexBuffer);
	SAFE_RELEASE(m_pIndexBuffer);
	
	SAFE_RELEASE(m_pShadeTexture);
	SAFE_RELEASE(m_pEdgeTexture);
	
	SAFE_DELETE_ARRAY(m_pAttributes);
	SAFE_DELETE_ARRAY(m_pTFactorColors);
	
	if (m_pD3DDev)
	{
		m_pD3DDev->DeleteVertexShader(m_dwCurrentShader);
		SAFE_RELEASE(m_pD3DDev);
	}

	SAFE_DELETE(m_pUI);
	
	return S_OK;
}


HRESULT CShaderToonShade::LoadXFile(const char* fileName, const DWORD dwFVF)
{
	ID3DXMesh* tempMesh = 0;
	ID3DXMesh* tempMeshFVF = 0;
	ID3DXMesh* tempMeshOpt = 0;
	ID3DXBuffer* tempMaterials = 0;
	
	HRESULT hr = D3DXLoadMeshFromX(const_cast<char*>(fileName), D3DXMESH_VB_SYSTEMMEM, m_pD3DDev, NULL, 
		&tempMaterials, &m_dwNumSections, &tempMesh);

	//comptr to ensure this object gets released
	ComPtr< ID3DXBuffer* > tempMaterialBuffer( tempMaterials, COMPTR_DONT_ADD_REF );
	ComPtr< ID3DXMesh* > tempMesh2( tempMesh, COMPTR_DONT_ADD_REF  );

	if(FAILED(hr))
		return hr;

	//compute bounding sphere
	TSVertex* pBuff;
	hr = tempMesh->LockVertexBuffer(D3DLOCK_READONLY, (BYTE**)&pBuff);
	if(FAILED(hr))
		return hr;
	D3DXComputeBoundingSphere(pBuff, tempMesh->GetNumVertices(), tempMesh->GetFVF(), &m_vecCenter, &m_fRadius);
	tempMesh->UnlockVertexBuffer();
	
	//optimize in attribute order
	hr = tempMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &tempMeshOpt);
	if(FAILED(hr))
		return hr;

	//comptr to ensure this object gets released
	ComPtr< ID3DXMesh* > tempMesh3( tempMeshOpt, COMPTR_DONT_ADD_REF  );

	//get attributes
	DWORD attribSize = m_dwNumSections;
	hr = tempMeshOpt->GetAttributeTable(NULL, &attribSize);
	if(FAILED(hr))
		return hr;
	
	m_pAttributes = new D3DXATTRIBUTERANGE[attribSize];
	
	hr = tempMeshOpt->GetAttributeTable(m_pAttributes, &attribSize);
	if(FAILED(hr))
		return hr;

	//convert to our format, and also make writeonly
	hr = tempMeshOpt->CloneMeshFVF(D3DXMESH_WRITEONLY, dwFVF, m_pD3DDev, &tempMeshFVF);
	if(FAILED(hr))
		return hr;

	//comptr to ensure this object gets released
	ComPtr< ID3DXMesh* > tempMesh4( tempMeshFVF, COMPTR_DONT_ADD_REF  );
	
	tempMeshFVF->GetVertexBuffer(&m_pVertexBuffer);
	tempMeshFVF->GetIndexBuffer(&m_pIndexBuffer);
	
	//create texture colors
	m_pTFactorColors = new D3DCOLOR[ max(m_dwNumSections, 5) ];
	m_pTFactorColors[0] = D3DCOLOR_RGBA(250, 150, 250, 0);
	m_pTFactorColors[1] = D3DCOLOR_RGBA(255, 0, 0, 0);
	m_pTFactorColors[2] = D3DCOLOR_RGBA(0, 0, 255, 0);
	m_pTFactorColors[3] = D3DCOLOR_RGBA(255, 255, 0, 0);
	m_pTFactorColors[4] = D3DCOLOR_RGBA(255, 0, 0, 0);

	for(int i = 4; i < m_dwNumSections; i++)
	{
		m_pTFactorColors[i] = D3DCOLOR_RGBA(255, 255, 255, 255);
	}

	return S_OK;
}


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


HRESULT CShaderToonShade::SetTextureStageStates()
{
	//we're going to pass the material color in thru tfactor
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	if(m_eDisplayOption == TOONDISPLAY_SILHOUETTES)
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
	else
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
	
	//and modulate this resulting color with the edge texture (which should be white everywhere but on the edge)
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
	if(m_eDisplayOption == TOONDISPLAY_SHADING)
		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	else
		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);	

	return S_OK;
}
// ------------------------------------------------------------------------------
// CShaderToonShade::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 CShaderToonShade::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;

	SetVertexShaderMatrices();

	SetTextureStageStates();
  
	m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID));

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

	for(int i = 0; i < m_dwNumSections; i++)
	{
		m_pD3DDev->SetRenderState(D3DRS_TEXTUREFACTOR, m_pTFactorColors[i]);
		m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, m_pAttributes[i].VertexStart, 
		m_pAttributes[i].VertexCount, m_pAttributes[i].FaceStart*3, m_pAttributes[i].FaceCount);
	}

	return hr;
}


void CShaderToonShade::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 CShaderToonShade::MouseMove(HWND hWnd, int x, int y)
{
	m_pUI->OnMouseMove(x, y);
	return;
}

void CShaderToonShade::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
	if(bDown)
	{
		switch(dwKey)
		{
			case 'W' :
            case 'w' :
            {
                m_bWireframe = !m_bWireframe;
				m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
                break;
            }

            case 'H' :
            case VK_F1 :
            {
		        ::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 VK_HOME :
            case VK_END :
			case VK_NUMPAD7 :
			case VK_NUMPAD1 :
            case '7' :
            case '1' :
            {
                m_pUI->Reset();
                m_bWireframe = false;
				m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
                break;
            }

            default :
            {
                break;
            }
        }
	}
	SetVertexShaderMatrices();
	return;
}

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

	EBString	name;

	if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
	{

		name = pProperty->GetPropertyName();

		if( name == EBString(STR_LOADMESH) )
		{
			// Now do file dialog
			NVXFileDialog aDialog;

			std::string theResult;
			bWritten = ( aDialog.Open( theResult ) );
			
			if ( bWritten )
			{
				SAFE_RELEASE(m_pVertexBuffer);
				SAFE_RELEASE(m_pIndexBuffer);
	
				SAFE_DELETE_ARRAY(m_pAttributes);
				SAFE_DELETE_ARRAY(m_pTFactorColors);

				bWritten = ( LoadXFile( theResult.c_str(), TSVertex::FVF_Flags ) == S_OK );

				SetBuffers();
			}
		}
	}
}

⌨️ 快捷键说明

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