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

📄 shader_dot3_directional.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	D3DXMATRIX matProj = m_pNVDevice->GetProjectionTransform();
	D3DXMATRIX matView = m_pNVDevice->GetViewTransform();

	D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
	D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
	D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
	D3DXMatrixInverse(&matWorldInverse, NULL, &matWorld);
	
	// Create a 3x3 invertse of the worldview for the normal transformation (we transpose it as we load it into
	// the constant store)
	D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
		
	// Projection to clip space
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);

	// Transform to eye space
	D3DXMatrixTranspose(&matWorldView, &matWorldView);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
	D3DXMatrixTranspose(&matWorldView, &matWorldView);

	// Transform to world space
	D3DXMatrixTranspose(&matWorld, &matWorld);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4);
	D3DXMatrixTranspose(&matWorld, &matWorld);

	// Transform for normals
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matWorldViewIT(0, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matWorldViewIT(1, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matWorldViewIT(2, 0), 1);

	return S_OK;

}

// Draw the actual light so we can see where it's pointing.
HRESULT CShaderDot3Directional::DrawDirectionalLightObject(D3DXVECTOR3 vecLightDirection)
{
	D3DXMATRIX matWorld;
	D3DXMATRIX matTemp;
	D3DXVECTOR3 vecNormalizedDirection;

	const NVBounds* pBounds = m_pLightMesh->GetBounds();
	D3DXMatrixIdentity(&matWorld);

	// Translate to the middle
	D3DXMatrixTranslation(&matTemp, -pBounds->m_vecCenter.x, -pBounds->m_vecCenter.y, -pBounds->m_vecCenter.z);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);

	float fLightScale = 0.1f; 
	D3DXMatrixScaling(&matTemp, fLightScale / pBounds->m_fRadius, fLightScale / pBounds->m_fRadius, fLightScale / pBounds->m_fRadius);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);

	// Orientation of the light object (the arrow)
	D3DXVECTOR3 vLightObject = D3DXVECTOR3(0.0f, -1.0f, 0.0f);

	D3DXVec3Normalize(&vecNormalizedDirection, &vecLightDirection);

	// Create the rotation axis
	D3DXVECTOR3 vOrthoNormal;
	D3DXVec3Cross(&vOrthoNormal, &vecNormalizedDirection, &vLightObject);
	D3DXVec3Normalize(&vOrthoNormal, &vOrthoNormal);

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

	// Rotate the object about our rotation axis to map one vector onto another
	D3DXMatrixRotationAxis(&matTemp, &vOrthoNormal, -fAngle);
	D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);

	D3DXMATRIX matTranslate = m_pUI->GetTranslationMatrix();
	// vecLightDirection is a direction vector, pointing at the origin, so we negate it to find the position
	D3DXMatrixTranslation(&matTemp, -vecLightDirection.x + matTranslate._41, -vecLightDirection.y + matTranslate._42, -vecLightDirection.z + matTranslate._43);

	D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);

	D3DXVECTOR3 LightColor(1.0f, 1.0f, 1.0f);
	m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_COLOR, &LightColor.x, 1);

	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);

	m_pLightMesh->Render(m_pNVDevice);		

	return S_OK;
}

HRESULT CShaderDot3Directional::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;

	
	//////////////////////

	assert( m_pCA_Water != NULL );

	m_pCA_Water->Tick();

	//////////////////////

	// Point at the vertex data
	hr = m_pD3DDev->SetStreamSource(0, m_pSphereVertexBuffer, sizeof(Dot3Vertex));
	if (FAILED(hr))
	{
		m_strLastError = "Could not set VB source";
		return hr;
	}
	
	// Point at the index data
	hr = m_pD3DDev->SetIndices(m_pSphereIndexBuffer, 0);
	if (FAILED(hr))
	{
		m_strLastError = "Could not set Index source";
		return hr;
	}

	//////////////////////


	D3DXMATRIX matWorld;
	D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
	D3DXMATRIX matTemp;

	// Clear to grey
	//	hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);

	m_pD3DDev->SetRenderState(D3DRS_FILLMODE, m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
	// Increase rotation
	
	if (!m_bPause)
	{
		m_fAngle = timeGetTime() * ((float)0.01f);
	}


	D3DXMatrixMultiply( &matWorld, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix() );


	// Load transform data.
	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	// Create the light direction vector.
	D3DXVECTOR3 vecLightDirection;
	float fLightDistance = 1.1f;
	vecLightDirection.x = fLightDistance * cos( D3DXToRadian(m_fAngle));
	vecLightDirection.z = fLightDistance * sin( D3DXToRadian(m_fAngle));
	vecLightDirection.y = fLightDistance;
		
	// Do the rendering
	DrawDirectional(vecLightDirection);

	// Draw the light shape
	DrawDirectionalLightObject(vecLightDirection);



	return hr;
}
	
HRESULT CShaderDot3Directional::DrawDirectional(D3DXVECTOR3 vecLightDirection)
{
	D3DXMATRIX matWorld;
	D3DXMATRIX matTemp;

	D3DXVec3Normalize(&vecLightDirection, &vecLightDirection);

	// shader math requires that the light direction vector points towards the light.
	vecLightDirection = -vecLightDirection;


	// Setup the vertex shader
	m_pD3DDev->SetVertexShader(m_dwDot3Shader);

	m_pD3DDev->SetPixelShader(0);


	// Normal map in stage 0
	// DotProduct 3 the normal map with the diffuse color set in the vertex
	// shader (this will be the local light vector)


	m_pD3DDev->SetTexture(0, m_pCA_Water->GetOutputTexture() );

	m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);

	m_pD3DDev->SetRenderState( D3DRS_WRAP0, 0 );

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
	
	// If you want a base texture, put it in stage 1 and MODULATE:
	// Modulate the bump output from the previous stage by the current texture
	//	m_pD3DDev->SetTexture(1, m_pBaseTexture );
	//	m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1  );
	//	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU,	D3DTADDRESS_WRAP);
	//	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV,	D3DTADDRESS_WRAP);

	//	m_pD3DDev->SetRenderState( D3DRS_WRAP1, 0 );

	//	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	//	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
	//	MODULATE);

	// Override the setup options if the user wants to display the components
	switch(m_eDisplayOption)
	{
		default:
		case DISPLAY_RESULT:
			break;
		case DISPLAY_BUMPMAP:
			// Show the bump texture, disable the base texture pass
			m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
			m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
			break;
		case DISPLAY_LIGHTVECTOR:
			// Show the diffuse color, output from the vshader which is the texture-space
			// light vector
			m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
			m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
			break;
		case DISPLAY_BASETEXTURE:
			break;
	}

	// Not using stage 2
	m_pD3DDev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);

	// Load the location of the light into the vertex shader.
	m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_DIRECTION, (void*)&vecLightDirection.x, 1);
	
	// Point at the vertex data
	m_pD3DDev->SetStreamSource(0, m_pSphereVertexBuffer, sizeof(Dot3Vertex));
	
	// Point at the index data
	m_pD3DDev->SetIndices(m_pSphereIndexBuffer, 0);
	
	// Backface cull the sphere
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

	// Draw the sphere
	m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);


	return S_OK;
}


HRESULT CShaderDot3Directional::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
	if (!(pCaps->MaxSimultaneousTextures >= 2))
	{
		m_strLastError = "Device cannot dual texture!";
		return E_FAIL;
	}

	if (!(pCaps->TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
	{
		m_strLastError = "Device cannot handle dotproduct3 operation!";
		return E_FAIL;
	}


	return S_OK;
}

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

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

	bool res;
	res = m_pCA_Water->Keyboard( dwKey, nFlags, bDown );

	if( res == true )
		return;

	/////////////////

	EBString msg;

    switch ( Action )
    {
		case EB_HELP:
		{

			msg  = "H  or  F1 for Help\n";
			msg += "\n";
			msg += "*** This demo is framerate limited.  ***\n";
			msg += "    Hit 'S' to run as fast as possible!\n";
			msg += "\n";
			msg += "L       : Toggle logo in water\n";
			msg += "\n";
			msg += "NUMPAD7   : Reset to initial conditions\n";
			msg += "\n";
			msg += "1       :   Display normal map\n";	
			msg += "2       :   Display velocity map\n";	
			msg += "3       :   Display prev pos,pos,v,n maps\n";	
			msg += "\n";	
			msg += "W       : Wireframe\n";
			msg += "\n";
			msg += "G          : Start/stop procedural animation       \n";
			msg += "S          : Toggle animation rate limiting\n";
			msg += "  L arrow : Run animation faster\n";
			msg += "  R arrow : Run animation slower\n";
			msg += "\n";
			msg += "B       : Toggle texture border wrapping\n";
			msg += "\n";
			msg += "Up arrow   : Increase droplet frequency\n";	
			msg += "Dwn arrow  : Decrease droplet frequency\n";	
			msg += "\n";
			msg += "Y       : Decrease normal map red/green\n";
			msg += "U       : Increase normal map red/green\n";
			msg += "\n";
			msg += "C       : Decrease height smoothing\n";	
			msg += "V       : Increase height smoothing\n";	
			msg += "<, >    : Dec/Inc velocity apply factor\n";
			msg += "[, ]    : Dec/Inc force apply factor\n";
			msg += "Z,X     : Dec/Inc equilibrium restore force\n";
			msg += "\n";
			msg += "\n";
			
			
			MessageBoxEx( NULL, msg.c_str(), "Dynamic Reflection Map Help",
						MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );

		}
		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;

		case EB_RESET:
        {
            m_pUI->Reset();
			m_pUI->SetTranslationalSensitivityFactor( 0.25f );

            m_bWireframe = false;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
            
        }
		break;

		case EB_NORMALMAP:
		{
			if (m_eDisplayOption != DISPLAY_BUMPMAP)
				m_eDisplayOption = DISPLAY_BUMPMAP;
			else
				m_eDisplayOption = DISPLAY_RESULT;

			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
		}
		break;

        default :
            break;
    }
}

⌨️ 快捷键说明

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