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

📄 shader_brdf.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);

    m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
    m_pD3DDev->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	
	//load textures
	hr = D3DXCreateTextureFromFile(m_pD3DDev, GetFilePath("woman.dds").c_str(), &m_pWomanTexture);
	if (FAILED(hr))
		return hr;
	
	// create a normalization cubemap
	hr = CreateNormalizationCubeMap(m_pD3DDev, 256, 9, &m_pNormalizingTexture);
	if (FAILED(hr))
		return hr;

	hr = CreateMinnaertMap(m_pD3DDev, 256, 256, 0, &m_pMinnaertTexture, m_MinnaertPower);
	if (FAILED(hr))
		return hr;

	//load textures
	hr = D3DXCreateTextureFromFile(m_pD3DDev, GetFilePath("velvetBump.dds").c_str(), &m_pVelvetBumpMapTexture);
	if (FAILED(hr))
		return hr;

	Create2DBitmap(0, 0, 100, 100);

	CreateTestQuad();

	m_pD3DDev->SetTexture(1, m_pWomanTexture);
	
	m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
	
	m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_NONE);

	m_pD3DDev->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 2);
	m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_POINT);
	m_pD3DDev->SetTextureStageState(2, D3DTSS_MIPFILTER, D3DTEXF_NONE);

	if(m_bUseTrilinear)
		m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);

	// setup our object pitched about 90 degrees, because of 3ds max exporter
	// doesn't
#ifdef TESTQUAD
	D3DXMatrixRotationYawPitchRoll(&m_MatObject[WOMAN_OBJECT], D3DXToRadian(0.0f), D3DXToRadian(0.0f), D3DXToRadian(0.0f));
#else
	D3DXMatrixIdentity(&m_MatObject[WOMAN_OBJECT]);
#endif
	D3DXMatrixIdentity(&m_MatObject[LIGHT_OBJECT]);

	SetLightPosition();

	// make enough room for camera to rotate around radius of object,
	// with a gap of approximately 1/4 of the size of the light object.

	SetupFixedCamera(m_ObjectRadius[WOMAN_OBJECT]+(m_ObjectRadius[LIGHT_OBJECT]*1.5f));

	return S_OK;
}

void CShaderBRDF::SetupFixedCamera(float radius)
{
	m_vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -2.0f*radius);
	m_vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);
	m_vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f);

    D3DXMatrixLookAtLH(&m_MatView, &m_vEyePt, &m_vLookatPt, &m_vUp);
    FLOAT fAspect = m_D3DViewPort.Width / (FLOAT)m_D3DViewPort.Height;
    D3DXMatrixPerspectiveFovLH( &m_MatProj, D3DX_PI/4, fAspect, 100.0f,
                                radius*4);
}

void CShaderBRDF::UpdateObject(DWORD index)
{
    D3DXMATRIX matRotationInverse;
    D3DXMATRIX matRotation;
	D3DXMATRIX matTemp;

	D3DXMatrixTranslation( &m_MatWorld, -m_ObjectCenter[index].x,
			                              -m_ObjectCenter[index].y,
					                      -m_ObjectCenter[index].z );
	switch (index)
	{
	case WOMAN_OBJECT:

		if (m_Rotating == WOMAN_OBJECT)
		{
			if (m_bAutoRotate)
			{
				// rotate about y axis
				m_curPitch += D3DXToRadian(1.0f);
				m_curYaw += D3DXToRadian(5.0f);
				D3DXMatrixRotationAxis(&m_MatObject[WOMAN_OBJECT], &m_VRotation, m_curYaw);
			}
			else 
			{
				D3DXMatrixMultiply( &m_MatObject[WOMAN_OBJECT], &m_mUI->GetRotationMatrix(), &m_mUI->GetTranslationMatrix() );
			}
		}

		D3DXMatrixMultiply( &m_MatWorld, &m_MatWorld, &m_MatObject[WOMAN_OBJECT] );

		break;

	case LIGHT_OBJECT:
		if (m_Rotating == LIGHT_OBJECT)
		{
			if (m_bAutoRotate)
			{
				m_curPitch += D3DXToRadian(1.0f);
				m_curYaw += D3DXToRadian(5.0f);
				D3DXMatrixRotationAxis(&matTemp, &m_VRotation, m_curYaw);
			}
			else
			{
				matTemp = m_mUI->GetRotationMatrix();
			}

			m_LightDir.x = 0.0f;
			m_LightDir.y = 0.0f;
			m_LightDir.z = 1.0f;
			D3DXVec3Normalize(&m_LightDir, &m_LightDir);

			D3DXVec3TransformNormal(&m_LightDir, &m_LightDir, &matTemp);
			SetLightPosition();
		}

		D3DXMatrixMultiply( &m_MatWorld, &m_MatWorld, &m_MatObject[LIGHT_OBJECT]);

		break;
	}

}

void CShaderBRDF::SetLightPosition()
{
	D3DXMATRIX matTemp;
	D3DXVECTOR3 lightPos(0, 0, -m_ObjectRadius[WOMAN_OBJECT]+(m_ObjectRadius[LIGHT_OBJECT]*.25f));
	D3DXVECTOR3 vLightObjectDir(0.0f, 0.0f, 1.0f);

	m_mUI->GetTranslationMatrix(&matTemp);
	D3DXVec3TransformCoord(&lightPos, &lightPos, &matTemp);

	// Create the rotation axis
	D3DXVECTOR3 vOrthoNormal;
	D3DXVec3Cross(&vOrthoNormal, &m_LightDir, &vLightObjectDir);
	D3DXVec3Normalize(&vOrthoNormal, &vOrthoNormal);

	// Calculate the angle between the two vectors.
	float fAngle = acos(D3DXVec3Dot(&m_LightDir, &vLightObjectDir));

	// Rotate the object about our rotation axis to map one vector onto another
	D3DXMatrixRotationAxis(&m_MatObject[LIGHT_OBJECT], &vOrthoNormal, -fAngle);

	D3DXMatrixTranslation( &matTemp, lightPos.x, lightPos.y, lightPos.z);
	D3DXMatrixMultiply(&m_MatObject[LIGHT_OBJECT], &matTemp, &m_MatObject[LIGHT_OBJECT]);

}

HRESULT CShaderBRDF::SetVertexShaderMatrices(DWORD index)
{
    // set up vertex shading constants to contain proper
    // transformation matrices etc.
    D3DXMATRIX matWorldView;
	D3DXMATRIX matWorldViewProj;
	D3DXMATRIX matWorldI;

	UpdateObject(index);

	D3DXMatrixInverse(&matWorldI, NULL, &m_MatWorld);

	D3DXMatrixMultiply(&matWorldView,     &m_MatWorld,     &m_MatView);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorldView, &m_MatProj);
	
	// Write Projection to clip space
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);

	// made this a vector 4 so, we wouldn't have to set the w part in the shader
	D3DXVECTOR4 vecLight;
	// Transform from world space to model space and point it away from the vertex towards the light
	// Light is pointing into the world
	D3DXVec3TransformNormal((D3DXVECTOR3*)&vecLight, &m_LightDir, &matWorldI);
	D3DXVec3Normalize((D3DXVECTOR3*)&vecLight, (D3DXVECTOR3*)&vecLight);
	// Shader math requires that the vector is to the light
	vecLight = -vecLight;
	vecLight.w = 1.0f;

	m_pD3DDev->SetVertexShaderConstant(CVP_LIGHT_DIRECTION, &vecLight, 1);

	// bias and scale, because pixel shader will clamp these values
	vecLight += D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 0.0f );
	vecLight *= .5f;
	vecLight.w = 1.0f;
	m_pD3DDev->SetPixelShaderConstant(CVP_LIGHT_DIRECTION, &vecLight, 1);

	// made this a vector 4 so, we wouldn't have to set the w part in the shader
	D3DXVECTOR4 eyePos;
	// put eye into object space.
	D3DXVec3TransformCoord((D3DXVECTOR3*)&eyePos, &m_vEyePt, &matWorldI);
	eyePos.w = 1.0f;
	m_pD3DDev->SetVertexShaderConstant(CV_EYE_POSITION, &eyePos, 1);

	D3DXVECTOR4 vecOne(1.0f, 1.0f, 1.0f, 1.0f);
	m_pD3DDev->SetVertexShaderConstant(CV_ONE, &vecOne, 1);

	return S_OK;
}

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

	for (i=0; i<NUM_OBJECTS; i++)
	{
		SAFE_RELEASE(m_pVertexBuffer[i]);
		SAFE_RELEASE(m_pIndexBuffer[i]);
	
		SAFE_DELETE_ARRAY(m_pAttributes[i]);
		SAFE_DELETE_ARRAY(m_pMaterials[i]);

		if (m_pD3DDev)
		{
			if (m_dwCurrentVShader[i] != 0)
			{
				m_pD3DDev->DeleteVertexShader(m_dwCurrentVShader[i]);
				m_dwCurrentVShader[i] = 0;
			}

			if (m_dwCurrentPShader[i] != 0)
			{
				m_pD3DDev->DeletePixelShader(m_dwCurrentPShader[i]);
				m_dwCurrentPShader[i] = 0;
			}
		}

	}
	
	SAFE_RELEASE(m_pD3DDev);
	SAFE_RELEASE(m_pWomanTexture);
	SAFE_RELEASE(m_pMinnaertTexture);
	SAFE_RELEASE(m_pNormalizingTexture);
	SAFE_RELEASE(m_pVelvetBumpMapTexture);
	SAFE_RELEASE(m_pTestQuadVB);	
	SAFE_RELEASE(m_pTexture2DVB);
	SAFE_DELETE(m_mUI);
	
	return S_OK;
}

HRESULT CShaderBRDF::LoadXFile(const char* fileName, const DWORD dwFVF, DWORD index)
{
	ID3DXMesh *tempMesh, *tempMeshFVF, *tempMeshOpt;
    LPBYTE pSrc;
	
	HRESULT hr = D3DXLoadMeshFromX(const_cast<char*>(fileName), D3DXMESH_SYSTEMMEM, m_pD3DDev, NULL, 
		(ID3DXBuffer**)&m_pMaterials[index], &m_dwNumSections[index], &tempMesh);
	
	//convert to our format
	hr = tempMesh->CloneMeshFVF(D3DXMESH_DYNAMIC, dwFVF, m_pD3DDev, &tempMeshFVF);
	
	tempMeshFVF->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &tempMeshOpt);

	DWORD attribSize = m_dwNumSections[index];
	hr = tempMeshOpt->GetAttributeTable(NULL, &attribSize);
	
	m_pAttributes[index] = new D3DXATTRIBUTERANGE[attribSize];
	
	hr = tempMeshOpt->GetAttributeTable(m_pAttributes[index], &attribSize);
	
	tempMeshOpt->GetVertexBuffer(&m_pVertexBuffer[index]);
	tempMeshOpt->GetIndexBuffer(&m_pIndexBuffer[index]);

	m_pVertexBuffer[index]->Lock( 0, 0, (BYTE**)&pSrc, 0 );
	// grab bound sphere, so we may initially scale our view.
	D3DXComputeBoundingSphere(pSrc, tempMeshOpt->GetNumVertices(), dwFVF, &m_ObjectCenter[index], &m_ObjectRadius[index]);

	m_pVertexBuffer[index]->Unlock();


	SAFE_RELEASE(tempMesh);
	SAFE_RELEASE(tempMeshFVF);
	SAFE_RELEASE(tempMeshOpt);
	
	return S_OK;
}

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

// this really should be a general drawing function inside the effects browser
// code.
HRESULT CShaderBRDF::Draw2DBitmap()
{
	DWORD dwVertexShader;
	DWORD dwPixelShader;
	UINT VBStride;
	LPDIRECT3DVERTEXBUFFER8 pVB;
	LPDIRECT3DBASETEXTURE8 pTexture;
	DWORD i;

	typedef struct tagRenderStates
	{
		D3DRENDERSTATETYPE Type;
		DWORD Value;
	} tRenderStates;

	typedef struct tagTextureStageStates
	{
		D3DTEXTURESTAGESTATETYPE Type;
		DWORD Value;
	} tTextureStates;

	tRenderStates SavedRender[] = 
	{
		{ D3DRS_ZENABLE, 0 }, 
		{ D3DRS_ALPHATESTENABLE, 0 },
		{ D3DRS_ALPHAREF, 0 },
		{ D3DRS_ALPHAFUNC, 0 },
		{ D3DRS_ALPHABLENDENABLE, 0 },
		{ D3DRS_SRCBLEND, 0 },
		{ D3DRS_DESTBLEND, 0 },
		{ D3DRS_FOGENABLE, 0 },
		{ D3DRS_CULLMODE, 0 },
		{ D3DRS_FILLMODE, 0 },
		{ D3DRS_WRAP0, 0}
	};

	tTextureStates SavedTextureStage0[] = 
	{
		{ D3DTSS_COLOROP, 0 }, 
		{ D3DTSS_COLORARG1, 0 },
		{ D3DTSS_ALPHAOP, 0 },
		{ D3DTSS_ALPHAARG1, 0 },
		{ D3DTSS_TEXCOORDINDEX, 0 },
		{ D3DTSS_MINFILTER, 0 },
		{ D3DTSS_MAGFILTER, 0 },
	};

	tTextureStates SavedTextureStage1[] = 
	{
		{ D3DTSS_COLOROP, 0 }, 
		{ D3DTSS_ALPHAOP, 0 },
		{ D3DTSS_TEXCOORDINDEX, 0 }
	};

	// Save state
	m_pD3DDev->GetVertexShader(&dwVertexShader);
	m_pD3DDev->GetPixelShader(&dwPixelShader);
	m_pD3DDev->GetStreamSource(0, &pVB, &VBStride);
	m_pD3DDev->GetTexture(0, &pTexture);
	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		m_pD3DDev->GetRenderState(SavedRender[i].Type, &SavedRender[i].Value);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)
	{
		m_pD3DDev->GetTextureStageState(0, SavedTextureStage0[i].Type, &SavedTextureStage0[i].Value);
	}
	for (i = 0; i < sizeof(SavedTextureStage1) / sizeof(tTextureStates); i++)
	{
		m_pD3DDev->GetTextureStageState(1, SavedTextureStage1[i].Type, &SavedTextureStage1[i].Value);
	}

	// draw logo
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

	m_pD3DDev->SetStreamSource(0, m_pTexture2DVB, sizeof(TLVertex));
	m_pD3DDev->SetVertexShader(D3DFVF_TLVERTEX);
	m_pD3DDev->SetPixelShader(0);

	// Enable alpha testing to remove the outer pixels
	m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
	m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
	m_pD3DDev->SetRenderState(D3DRS_ALPHAREF, 0x80 );
	m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
	m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
	m_pD3DDev->SetRenderState(D3DRS_FOGENABLE, FALSE);
	m_pD3DDev->SetRenderState( D3DRS_WRAP0, 0);

	m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 );

	// Restore state
	m_pD3DDev->SetVertexShader(dwVertexShader);
	m_pD3DDev->SetStreamSource(0, pVB, VBStride);
	m_pD3DDev->SetTexture(0, pTexture);
	m_pD3DDev->SetPixelShader(dwPixelShader);

	SAFE_RELEASE(pTexture);
	SAFE_RELEASE(pVB);

	for (i = 0; i < sizeof(SavedRender) / sizeof(tRenderStates); i++)
	{
		m_pD3DDev->SetRenderState(SavedRender[i].Type, SavedRender[i].Value);
	}
	for (i = 0; i < sizeof(SavedTextureStage0) / sizeof(tTextureStates); i++)

⌨️ 快捷键说明

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