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

📄 detail.cpp

📁 <B>DirectX9.0 3D游戏编程</B>
💻 CPP
字号:
/********************************************************************
 *         Advanced 3D Game Programming using DirectX 9.0			*
 ********************************************************************
 * copyright (c) 2003 by Peter A Walsh and Adrian Perez				*
 * See license.txt for modification and distribution information	*
 ********************************************************************/

#include "stdafx.h"

char g_helpMessage[] = "\
Detail Texture example app\n\
Advanced 3D Game Programming using DirectX 8.0\n\
\n\
  Controls:\n\
      [D] : Turn detail textures on/off\n\
      [H] : Toggle Help\n\
";

struct sDetailVertex
{
	point3 loc;
	DWORD diff;
	// 2 pairs of u,v coordinates
	float tex[2][2];
};

struct sDetailPoly
{
	sDetailVertex v[4];

	// Convenience function to set up textures for us.
	void SetCoords( int num, float minu, float maxu, float minv, float maxv )
	{
		v[0].tex[num][0] = minu;
		v[0].tex[num][1] = minv;
		v[1].tex[num][0] = maxu;
		v[1].tex[num][1] = minv;
		v[2].tex[num][0] = maxu;
		v[2].tex[num][1] = maxv;
		v[3].tex[num][0] = minu;
		v[3].tex[num][1] = maxv;
	}
};

class cDetailApp : public cApplication,
	public iKeyboardReceiver

{
	// Data for the square
	sDetailPoly m_square;
	void LoadTextures();

	void SetStage1();
	void SetStage2();

	cTexture*	m_pTextures[3];

	// If this is true, draw some help on the screen
	bool m_drawHelp;

	void InitSquare();
	void DrawSquare();

	bool m_bCanDoMultitexture;
	bool m_bCanDoAddSigned;
	bool m_bDrawDetail;

public:

	//==========--------------------------  cApplication

	virtual void DoFrame( float timeDelta );
	virtual void SceneInit();

	cDetailApp() :
		cApplication()
	{
		m_pTextures[0] = NULL;
		m_pTextures[1] = NULL;
		m_pTextures[2] = NULL;
		m_title = string( "Detail Textures - press [H] for help" );
	}

	~cDetailApp()
	{
		delete m_pTextures[0];
		delete m_pTextures[1];
		delete m_pTextures[2];
	}

	//==========--------------------------  iKeyboardReceiver

	virtual void KeyUp( int key );
	virtual void KeyDown( int key );

	//==========--------------------------  cDetailApp

	bool CheckCaps()
	{
		D3DCAPS9 DevCaps;

		Graphics()->GetDevice()->GetDeviceCaps( &DevCaps );
	
		m_bCanDoMultitexture = false;
		if( DevCaps.MaxSimultaneousTextures > 1 )
		{
			m_bCanDoMultitexture = true;
		}

		m_bCanDoAddSigned = false;
		if( DevCaps.TextureOpCaps & D3DTEXOPCAPS_ADDSIGNED )
		{
			m_bCanDoAddSigned = true;
		}
		
		if( !(DevCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATE2X) )
		{
			// the device can't do mod 2x.  If we also can't do add signed,
			// we have no way to do the multitexture.
			if( !m_bCanDoAddSigned )
			{
				// turn off multitexture and just go with the one detail texture
				m_bCanDoMultitexture = false;
			}
		}

		bool bSrcColor = DevCaps.SrcBlendCaps & D3DPBLENDCAPS_SRCCOLOR;
		bool bDestColor = DevCaps.SrcBlendCaps & D3DPBLENDCAPS_DESTCOLOR;
		if( !m_bCanDoMultitexture && !(bSrcColor && bDestColor) )
		{
			// device couldn't do the alpha blending we wanted.
			return false;
		}

		return true;
	}
};

cApplication* CreateApplication()
{
	return new cDetailApp();
}

void DestroyApplication( cApplication* pApp )
{
	delete pApp;
}

void cDetailApp::SceneInit()
{
	CheckCaps();

	Graphics()->SetProjectionData( PI/3.5f, 1.f, 200.f );
	Graphics()->MakeProjectionMatrix();

	Input()->GetKeyboard()->SetReceiver( this );

	// initialize our scene
	LPDIRECT3DDEVICE9 lpDevice = Graphics()->GetDevice();
	lpDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

	lpDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
	lpDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
	lpDevice->SetRenderState( D3DRS_AMBIENT, 0x00404040 );
	lpDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

	// initialize the camera
	Graphics()->SetViewMatrix( matrix4::Identity );

	// don't draw help
	m_drawHelp = false;
	// do draw the detail
	m_bDrawDetail = true;

	// init our geometry
	InitSquare();

	// load our textures
	LoadTextures();
}


void cDetailApp::DoFrame( float timeDelta )
{
	static float total =0.f;
	total += timeDelta;
	
	float dist = 1.1f + 80.f*(1.f + sin(total));

	matrix4 mat;
	mat.ToTranslation( point3(0.0f, 0.0f, dist) );
	Graphics()->SetWorldMatrix( mat );
	
	// then, draw the frame.
	Graphics()->BeginScene();

	Graphics()->Clear( true, true, 0xE0E0E0, 1.f );

	// Draw the square
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	if( m_bCanDoMultitexture )
	{
		// Do one pass, two textures.
		pDevice->SetTexture( 0, m_pTextures[0]->GetTexture() );	

		if( m_bDrawDetail )
		{
			pDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
			pDevice->SetTexture( 1, m_pTextures[2]->GetTexture() );	

			if( m_bCanDoAddSigned )
			{
				pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );
			}
			else
			{
				pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X );
			}
		}
		else
		{
			pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
		}

		DrawSquare();
	}
	else
	{
		// Do two passes, blended.

		// Pass 1: no alpha blending, base texture.
		pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		pDevice->SetTexture( 0, m_pTextures[0]->GetTexture() );	
		DrawSquare();

		if( m_bDrawDetail )
		{
			// Pass 2: Alpha-blend in the detail texture
			pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
			pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR );
			pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR );
			pDevice->SetTexture( 0, m_pTextures[1]->GetTexture() );	

			pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );
			DrawSquare();
			// restore the texture index
			pDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );

		}
	}

	

	if( m_drawHelp )
	{
		Graphics()->DrawTextString(
			4,
			4,
			D3DCOLOR_XRGB( 256, 0, 0 ),
			g_helpMessage); 
	}
	else
	{
		Graphics()->DrawTextString(
			4,
			4,
			D3DCOLOR_XRGB( 256, 0, 0 ),
			"Press [H] for help" ); 
	}

	Graphics()->EndScene();

	// flip the buffer.
	Graphics()->Flip();
}



void cDetailApp::KeyUp( int key )
{
	if( key == DIK_H )
	{
		m_drawHelp = !m_drawHelp;
	}

	else if( key == DIK_D )
	{
		m_bDrawDetail = !m_bDrawDetail;
	}
}


void cDetailApp::KeyDown( int key )
{
}


void cDetailApp::InitSquare()
{
	point3 v[4];
	v[0] = point3(-10.f, 10.f,0.f);
	v[1] = point3( 10.f, 10.f,0.f);
	v[2] = point3( 10.f,-10.f,0.f);
	v[3] = point3(-10.f,-10.f,0.f);

	DWORD diff = -1; // white

	m_square.v[0].loc = v[0];
	m_square.v[0].diff = diff;
	m_square.v[1].loc = v[1];
	m_square.v[1].diff = diff;
	m_square.v[2].loc = v[2];
	m_square.v[2].diff = diff;
	m_square.v[3].loc = v[3];
	m_square.v[3].diff = diff;
	m_square.SetCoords( 0, 0.f, 1.f, 0.f, 1.f );
	m_square.SetCoords( 1, 0.5f, 17.9f, 0.f, 17.9f );
}

void cDetailApp::DrawSquare()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	int fvfFlags = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2;

	pDevice->SetFVF( fvfFlags );

	pDevice->DrawPrimitiveUP(
		D3DPT_TRIANGLEFAN,
		2,
		&m_square,
		sizeof( sDetailVertex ) );
}

void cDetailApp::LoadTextures()
{
	LPDIRECT3DDEVICE9 lpDevice = Graphics()->GetDevice();

	/**
	 * turn on bi-lin
	 */
    lpDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    lpDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	lpDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
	lpDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

    lpDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    lpDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	lpDevice->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
	lpDevice->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );

	/**
	 * base map in texture stage 0
	 */
	m_pTextures[0] = new cTexture( "media\\base.dds", 0 ); 

	/**
	 * because of the multitexture, and because some cards (3dfx) can't
	 * share texture memory across stages, we need two copies of the 
	 * detail map, one for each stage.
	 * InitDetail generates mip-levels, and also blurs each mip upon
	 * creation, to help the high-frequency detail fade away quicker.
	 */
	m_pTextures[1] = new cTexture( "media\\detail.dds", 0 ); 
	if( m_bCanDoMultitexture )
	{
		m_pTextures[2] = new cTexture( "media\\detail.dds", 1 ); 
	}
	
}


void cDetailApp::SetStage1()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	// Set the texture state's for single-texturing mode
	pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
	pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );

	// In a real-world app we'd do something more meaningful with the 
	// second stage if we had multitexture, such as a lightmap
	pDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );

	pDevice->SetTexture( 0, m_pTextures[0]->GetTexture() );	

	// this stage doesn't use alpha blending, turn it off.
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}

void cDetailApp::SetStage2()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	// Set the texture state's for single-texturing mode
	pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
	pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
	pDevice->SetTexture( 0, m_pTextures[1]->GetTexture() );	

	if( m_bCanDoMultitexture )
	{
		pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		pDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
		if( m_bCanDoAddSigned )
		{
			pDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_ADDSIGNED );
		}
		else
		{
			pDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE2X );
		}
		
		pDevice->SetTexture( 1, m_pTextures[2]->GetTexture() );	
	}


}

⌨️ 快捷键说明

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