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

📄 shader_blinnreflect.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		NULL,
		NULL,
		&m_pCubeTexture);
	if (FAILED(hr))
	{
		m_strLastError = "Could not load texture (sky_cube_mipmap.dds)";
		return hr;
	}

	// Setup constants
	m_pD3DDev->SetVertexShaderConstant(CV_ZERO,   D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_ONE,    D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);

	// Camera stuff
	D3DXMATRIX matProj;
	D3DXMATRIX matView;

	D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
	D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f,  0.0f );
	D3DXVECTOR3 vUp       = D3DXVECTOR3( 0.0f, 1.0f,  0.0f );
	m_pD3DDev->SetVertexShaderConstant(CV_EYE_WORLD, D3DXVECTOR4(vEyePt.x, vEyePt.y, vEyePt.z, 0.0f), 1);

	// View
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);

	// Projection
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 0.1f, 50.0f);

	m_pNVDevice->SetViewTransform(&matView);
	m_pNVDevice->SetProjectionTransform(&matProj);

	m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, FALSE);


	if (m_pLightMesh)
		m_pLightMesh->RestoreDeviceObjects(m_pNVDevice);

	// Reset control points for mesh
	m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;

	// Point at the vertex data
    CreateBasisVectors(m_pVertexBuffer, m_pIndexBuffer);
	
	// Point at the index data
	hr = m_pD3DDev->SetIndices(m_pIndexBuffer, 0);
	if (FAILED(hr))
	{
		m_strLastError = "Could not set Index source";
		return hr;
	}

	return S_OK;

}

HRESULT CShaderBlinnReflect::Free()
{
	SAFE_DELETE(m_pLightMesh);
    SAFE_RELEASE(m_pPatchBuffer);
    SAFE_RELEASE(m_pVertexBuffer);
    SAFE_RELEASE(m_pIndexBuffer);
	SAFE_RELEASE(m_pBumpMapQWVU);
	SAFE_RELEASE(m_pBumpMapHILO);
	SAFE_RELEASE(m_pGlossMap);
	SAFE_RELEASE(m_pCubeTexture);
	SAFE_DELETE(m_pUI);

	SAFE_DELETE(m_pNVDevice);

	if (m_pD3DDev)
	{
		if (m_dwBlinnPixelShader)
			m_pD3DDev->DeletePixelShader(m_dwBlinnPixelShader);
		if (m_dwBlinnVertexShader)
			m_pD3DDev->DeleteVertexShader(m_dwBlinnVertexShader);
		if (m_dwTransformShader)
			m_pD3DDev->DeleteVertexShader(m_dwTransformShader);
		if (m_dwBlinnPatchVertexShader)
			m_pD3DDev->DeleteVertexShader(m_dwBlinnPatchVertexShader);
		if (m_dwTransformPatchShader)
			m_pD3DDev->DeleteVertexShader(m_dwTransformPatchShader);

		m_dwBlinnPixelShader = 0;
		m_dwBlinnVertexShader = 0;
		m_dwTransformShader = 0;
		m_dwBlinnPatchVertexShader = 0;
		m_dwTransformPatchShader = 0;

		SAFE_RELEASE(m_pD3DDev);
	}
	
	return S_OK;
}

HRESULT CShaderBlinnReflect::Start()
{
	m_fAngle = 0.0f;
	return S_OK;
}

  
HRESULT CShaderBlinnReflect::SetTransform()
{
	D3DXMATRIX matTemp;
	D3DXMATRIX matWorldViewProj;
	D3DXMATRIX matWorldView;
	D3DXMATRIX matWorldViewI;
	D3DXMATRIX matWorldI;

	D3DXMATRIX matWorld = m_pNVDevice->GetWorldTransform();
	D3DXMATRIX matProj = m_pNVDevice->GetProjectionTransform();
	D3DXMATRIX matView = m_pNVDevice->GetViewTransform();

	D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
	D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
	D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
	D3DXMatrixInverse(&matWorldI, 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(&matWorldViewI, NULL, &matWorldView);
		
	// Projection to clip space
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);

	D3DXMatrixTranspose(&matWorld, &matWorld);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_1, &matWorld(1, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLD_2, &matWorld(2, 0), 1);
	D3DXMatrixTranspose(&matWorld, &matWorld);

	// If you are rotating the cubemap, you need to apply that transform here too
	D3DXMATRIX matBasisTransform = matWorld;

	D3DXMatrixTranspose(&matBasisTransform, &matBasisTransform);
	m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_0, &matBasisTransform(0, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_1, &matBasisTransform(1, 0), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_2, &matBasisTransform(2, 0), 1);
	D3DXMatrixTranspose(&matBasisTransform, &matBasisTransform);

	return S_OK;

}

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

	// Set the bump scale
	m_pD3DDev->SetVertexShaderConstant(CV_BUMPSCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, m_fBumpScale), 1);

    AnimateSplinePatch(pTimer);

	D3DXMatrixMultiply( &matWorld, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix() );
			
	// Load transform data.
	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	DrawReflection();

	return hr;
}
	
HRESULT CShaderBlinnReflect::DrawReflection()
{
	D3DXMATRIX matWorld;
	D3DXMATRIX matTemp;

	m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

	// General setup
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
	m_pD3DDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V);

	// Point at the vertex data
    m_pD3DDev->SetStreamSource(0, m_bUsePatch ? m_pPatchBuffer : m_pVertexBuffer, sizeof(Dot3Vertex));

	// Backface cull the sphere
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE, m_bUsePatch ? D3DCULL_NONE : D3DCULL_CCW);

	// Point at the index data
	m_pD3DDev->SetIndices(m_pIndexBuffer, 0);

	m_pD3DDev->SetPixelShader(0);

	if ((m_eDisplayOption == DISPLAY_BLINN8BITSIGNED) && (!m_bSupportsQWVU))
	{
		m_eDisplayOption = DISPLAY_BLINNHILOSIGNED;
	}
	
	if ((m_eDisplayOption == DISPLAY_BLINNHILOSIGNED) && (!m_bSupportsHILO))
	{
		m_eDisplayOption = DISPLAY_BLINN8BITSIGNED;
	}

	// 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)
	if (m_eDisplayOption == DISPLAY_BLINN8BITSIGNED)
	{
		m_pD3DDev->SetTexture(0, m_pBumpMapQWVU);
	}
	else
	{
		m_pD3DDev->SetTexture(0, m_pBumpMapHILO);
	}

	m_pD3DDev->SetTexture(1, NULL);
	m_pD3DDev->SetTexture(2, NULL);
	m_pD3DDev->SetTexture(3, m_pCubeTexture);
	
	// Setup the vertex shader
    m_pD3DDev->SetVertexShader(m_bUsePatch ? m_dwBlinnPatchVertexShader : m_dwBlinnVertexShader);
	m_pD3DDev->SetPixelShader(m_dwBlinnPixelShader);

	float numSegs[4];
	numSegs[0] = 20.0f;
	numSegs[1] = 20.0f;
	numSegs[2] = 20.0f;
	numSegs[3] = 20.0f;

	D3DRECTPATCH_INFO info;
	info.StartVertexOffsetWidth  = 0;
	info.StartVertexOffsetHeight = 0;
	info.Width  = 4;
	info.Height = 4;
	info.Stride = 4; // verticies to next row of verticies
	info.Basis  = D3DBASIS_BEZIER;
	info.Order  = D3DORDER_CUBIC;

    // Draw 
    if (m_bUsePatch)
    {
        // draw a single patch for now
        // always tesselate from scratch...
	    m_pD3DDev->DrawRectPatch(1, numSegs, &info);
    }
    else
        m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);

    m_pD3DDev->SetVertexShader(m_bUsePatch ? m_dwTransformPatchShader : m_dwTransformShader);
	m_pD3DDev->SetPixelShader(0);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
	m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
	m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

	m_pD3DDev->SetTexture(0, m_pGlossMap);
	m_pD3DDev->SetTexture(3, NULL);

	// Draw again
    if (m_bUsePatch)
	    m_pD3DDev->DrawRectPatch(2, numSegs, &info);
    else
	    m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);

	return S_OK;
}

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

void CShaderBlinnReflect::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 +\\- Change Bump Scale\n\n",
				   "Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
		}
		break;

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

		case EB_RESET:
        {
            m_pUI->Reset();
            m_bWireframe = false;
			// Reset mesh control points
			m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;
			m_fBumpScale = 0.2f;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
            
        }
		break;

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

		case EB_ADD:
		{
			m_fBumpScale += 0.02f;
			if (m_fBumpScale > 1.0f)
				m_fBumpScale = 1.0f;
		}
		break;

		case EB_SUBTRACT:
		{
			m_fBumpScale -= 0.02f;
			if (m_fBumpScale < 0.0f)
				m_fBumpScale = 0.0f;
		}		
		break;

        default :
            break;
    }
}

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

	EBString	name;

	if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
	{

		name = pProperty->GetPropertyName();
		
		if(name == EBString(STR_INCREASEBUMPSCALE))
		{
			Keyboard(VK_ADD, 0, true);
		}
		else if (name == EBString(STR_DECREASEBUMPSCALE))
		{
			Keyboard(VK_SUBTRACT, 0, true);
		}
		else if (name == EBString(STR_RESETPATCH))
		{
			Keyboard(VK_HOME, 0, true);
		}
	}
}



⌨️ 快捷键说明

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