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

📄 shader_blinnreflect.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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;

/*
	if( m_pCA_Water->m_SimulationMode == SM_NORMAL_GRAY )
	{
		//m_pCA_Water->m_bDrawOutput = false;

		// Clear to grey
		hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,
								D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
	}
	else
	{
		m_pCA_Water->m_bDrawOutput = true;
	}
*/
	if( m_pCA_Water->m_bDrawOutput == false )
	{
		// Clear to grey
		hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,
								D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
	}

	//////////////////////////////////////////
	// Update dynamic normal map

	assert( m_pCA_Water != NULL );

	// Tick also draws the maps in background if m_bDrawOutput is on
	hr = m_pCA_Water->Tick();
	
	ASSERT_IF_FAILED(hr);

	////////////////////////////////////////////////////
	// Restore render state because it may have been polluted
	//		by water animation

	if( m_pCA_Water->m_bDrawOutput == false )
	{

		RestoreRenderState();


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



		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)
	{
		assert( m_pCA_Water != NULL );

		IDirect3DTexture8 * pTex = m_pCA_Water->GetOutputTexture();

		assert( pTex != NULL );

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

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


	// now render gloss map
/*
    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(0, m_pCA_Water->GetOutputTexture() );

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

	if( button == MOUSE_LEFTBUTTON && m_bDrawModeOn == true )
	{
		if(bDown)
		{
			m_bDrawing = true;
		}
		else
		{
			// Draw the last point clicked as the mouse button 
			//   comes up.
			
			TryDrawDroplet( x,y );

			m_bDrawing = false;
		}
	}

	return;
}


void CShaderBlinnReflect::TryDrawDroplet( float x, float y )
{

	float fx,fy;
	RECT winr;

	if( m_pUI->IsInWindow( x,y ))
	{
		winr = m_pUI->GetRECT();

		fx = 1.0f - ((float)x - (float)winr.left)/((float)winr.right - winr.left);
		fy =        ((float)y - (float)winr.top)/((float)winr.bottom - winr.top);

		m_pCA_Water->DrawDroplet( fx, fy, false );
	}

	RestoreRenderState();
}


void CShaderBlinnReflect::RestoreRenderState()
{
	// call to reset render modes to those appropriate for
	//  rendering the reflective surface

	int i;
	for( i=0; i < 4; i++ )
	{
        m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_POINT  );  // nearest level
	}

	m_pD3DDev->SetRenderState( D3DRS_ZENABLE,			D3DZB_TRUE );
	m_pD3DDev->SetRenderState( D3DRS_ZWRITEENABLE,		true );

}


void CShaderBlinnReflect::MouseMove(HWND hWnd, int x, int y)
{

	if( m_bDrawing && m_bDrawModeOn )
	{
		if( m_pCA_Water != NULL )
		{
			TryDrawDroplet( x,y );
		}
	}
	else if( m_pUI != NULL )
	{
		m_pUI->OnMouseMove(x, y);
	}


	return;
}

void CShaderBlinnReflect::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{

	assert( m_pCA_Water != NULL );
	bool result;
	result = m_pCA_Water->Keyboard( dwKey, nFlags, bDown );

	if( result == true )
	{
		return;			// no more keyboard processing!
	}

	if( !bDown )
	{
		switch( dwKey )
		{
		case VK_NUMPAD8:
			m_pUI->Reset();
			m_pUI->Translate( 0.0f, 0.0f, -0.25f );
			m_pUI->OnLButtonDown( 50, 50 );
			m_pUI->OnMouseMove( 68, 62 );
			m_pUI->OnLButtonUp( 68, 62 );

            m_bWireframe = false;
			m_pCA_Water->m_bWireframe = false;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;

			m_bShowProceduralMaps = false;

			break;

		case 'D':
			m_bDrawModeOn = !m_bDrawModeOn;
			FDebug("Set draw mode: %s\n", m_bDrawModeOn?"ON":"OFF");
			break;
		case '5':
			m_bShowProceduralMaps = !m_bShowProceduralMaps;
			break;
		case 'P':
			m_bPause = !m_bPause;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			break;
		}
	}


	eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
	

	if( result == true && Action != EB_WIREFRAME )
	{
		return;			// no more keyboard processing!
	}


	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 += "D       : Toggle draw/move mode\n";
			msg += "L       : Toggle logo in water\n";
			msg += "\n";
			msg += "NUMPAD7   : Reset to initial conditions\n";
			msg += "NUMPAD8   : Reset view\n";
			msg += "\n";
			msg += "5       : Display dynamic maps\n";	
			msg += "   1    :   Display normal map\n";	
			msg += "   2    :   Display velocity map\n";	
			msg += "   3    :   Display initial,pos,v,n maps\n";	
			msg += "\n";	
			msg += "W       : Wireframe\n";
			msg += "+        : Increase bump height\n";
			msg += "-         : Decrease bump height\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 += "Up arrow   : Increase droplet frequency\n";	
			msg += "Dwn arrow  : Decrease droplet frequency\n";	
			msg += "\n";
			msg += "M       : Toggle normal map creation method\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 += "\n";
			msg += "\n";
			
			
			MessageBoxEx( NULL, msg.c_str(), "Dynamic Reflection Map 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:
        {
			// Reset mesh control points
			m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;

			m_fBumpScale = 0.25f;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;

			if( m_pCA_Water != NULL )
			{
				m_pCA_Water->m_bReset = true;
			}
        }
		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);
		}
		else if (name == EBString(STR_MOREOPTION))
		{
			Keyboard(VK_F1, 0, true );
		}
	}
}



⌨️ 快捷键说明

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