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

📄 multitex.cpp

📁 <B>DirectX9.0 3D游戏编程</B>
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    // Generate the group of rings for the sphere
    for( int ring = 0; ring < numSphereRings; ring++ )
    {    
        float r0 = (float)sin( (ring+0) * fDeltaRingAngle );
        float r1 = (float)sin( (ring+1) * fDeltaRingAngle );
        float y0 = (float)cos( (ring+0) * fDeltaRingAngle );
        float y1 = (float)cos( (ring+1) * fDeltaRingAngle );

        // Generate the group of segments for the current ring
        for( int seg = 0; seg < (numSphereSegments+1); seg++ )
        {
            float x0 =  r0 * (float)sin( seg * fDeltaSegAngle );
            float z0 =  r0 * (float)cos( seg * fDeltaSegAngle );
            float x1 =  r1 * (float)sin( seg * fDeltaSegAngle );
            float z1 =  r1 * (float)cos( seg * fDeltaSegAngle );

			curr.loc = radius * point3(x0,y0,z0);
			curr.norm = curr.loc;
			curr.norm.Normalize();
			for( i=0; i<2; i++ )
			{
				curr.tex[i][0] = scales[i] * -((FLOAT)seg)/numSphereSegments;
				curr.tex[i][1] = scales[i] * ((ring+0)/(FLOAT)numSphereRings);
			}
			pVec->push_back( curr );

			curr.loc = radius * point3(x1,y1,z1);
			curr.norm = curr.loc;
			curr.norm.Normalize();
			for( i=0; i<2; i++ )
			{
				curr.tex[i][0] = scales[i] * -((FLOAT)seg)/numSphereSegments;
				curr.tex[i][1] = scales[i] * ((ring+1)/(FLOAT)numSphereRings);
			}
			pVec->push_back( curr );
        }
    }
}


void cMultiTexApp::LoadTextures()
{
	char* names[7] = { 
		"media\\earth.dds", 
		"media\\glowmap.dds", 
		"media\\detail.dds", 
		"media\\stars.dds",
		"media\\glownoise.dds",
		"media\\spheremap.dds",
		"media\\specmap.dds"
	};
	int stages[7] = { 0, 0, 0, 1, 1, 1, 1 };

	for( int i=0; i<7; i++ )
	{
		m_pTextures[i] = new cTexture( names[i], stages[i] );
	}
}

void cMultiTexApp::DoBasePass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	/**
	 * first pass should modulate with the diffuse color
	 */
	pDevice->SetTexture( 0, m_pTextures[0]->GetTexture() );
	SetColorStage( 0, D3DTA_TEXTURE, D3DTA_CURRENT, D3DTOP_MODULATE );

	/**
	 * first pass doesn't use alpha blending.
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

    sMaterial mat( 
		0.f, 
		color3(0.8f,0.8f,0.8f),
		color3(0.0f,0.0f,0.0f),
		color3(0.0f,0.0f,0.0f) );
    pDevice->SetMaterial(&mat);
	
	pDevice->DrawPrimitiveUP(
		D3DPT_TRIANGLESTRIP,
		m_earthVerts.size() - 2,
		&m_earthVerts[0],
		sizeof( sMTVertex ) );

}

void cMultiTexApp::DoDetailPass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	/**
	 * set up modulate 2x style alpha blending
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR );
	pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR );

	/**
	 * first stage is the detail map
	 */
	pDevice->SetTexture( 0, m_pTextures[2]->GetTexture() );
	SetColorStage( 0, D3DTA_TEXTURE, D3DTA_CURRENT, D3DTOP_SELECTARG1 );

	/**
	 * The detail map needs the second pair of coordinates
	 */
	pDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 1 );

	pDevice->DrawPrimitiveUP(
		D3DPT_TRIANGLESTRIP,
		m_earthVerts.size() - 2,
		&m_earthVerts[0],
		sizeof( sMTVertex ) );

	/**
	 * Restore the texture coordinates
	 */
	pDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 );
}


void cMultiTexApp::DoGlowPass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	/**
	 * glow map the glow map mask gets modulated with the
	 * inverse diffuse color, that way it fades as light
	 * hits it.
	 */
	pDevice->SetTexture( 0, m_pTextures[1]->GetTexture() );
	SetColorStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_DIFFUSE | D3DTA_COMPLEMENT, 
		D3DTOP_MODULATE );

	/**
	 * The second pass is the noise map, to give the
	 * illusion of millions of little lights.  just
	 * modulate with whatever made it through the 
	 * first pass
	 */
	pDevice->SetTexture( 1, m_pTextures[4]->GetTexture() );
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 );
	SetColorStage( 
		1, 
		D3DTA_TEXTURE, 
		D3DTA_CURRENT, 
		D3DTOP_MODULATE );


	/**
	 * set up add style blending
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
	pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

	/**
	 * Turn up diffuse all the way to accentuate the
	 * effect
	 */
    sMaterial mat( 
		0.f, 
		color3(1.0f,1.0f,1.0f),
		color3(0.0f,0.0f,0.0f),
		color3(0.0f,0.0f,0.0f) );
    pDevice->SetMaterial(&mat);

	/**
	 * The second light is to help accentuate the light hitting the earth.
	 * This helps the little lights fade away as they hit sunlight.
	 */
	pDevice->LightEnable(1, TRUE);


	pDevice->DrawPrimitiveUP( 
		D3DPT_TRIANGLESTRIP,
		m_earthVerts.size() - 2,
		&m_earthVerts[0],
		sizeof( sMTVertex ) );

	/**
	 * Restore the basic state
	 */
	pDevice->SetTextureStageState(1, D3DTSS_COLOROP ,D3DTOP_DISABLE );
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 );
	pDevice->LightEnable(1, FALSE);

}


void cMultiTexApp::DoEnvyPass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	/**
	 * The first color pass is just the inverse diffuse color.
	 * the first alpha pass takes the earth mask used in
	 * the gloss pass.  This will be modulated with the 
	 * final color before being alpha blended onto the 
	 * frame buffer.
	 */
	pDevice->SetTexture( 0, m_pTextures[1]->GetTexture() );
	SetColorStage( 
		0, 
		D3DTA_DIFFUSE | D3DTA_COMPLEMENT, 
		D3DTA_CURRENT,
		D3DTOP_SELECTARG1 );

	SetAlphaStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_CURRENT,
		D3DTOP_SELECTARG1 );

	/**
	 * The second pass is the envy map.  Sure, a nice
	 * star pattern would have worked, but using the 
	 * coffeeshop texturemap really points out that
	 * the envymapping is working correctly.
	 */
	pDevice->SetTexture( 1, m_pTextures[5]->GetTexture() );
	SetColorStage( 
		1, 
		D3DTA_TEXTURE, 
		D3DTA_CURRENT, 
		D3DTOP_MODULATE );

	/**
	 * Set up texture transformations.
	 */
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL  );
	pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

	/**
	 * Set up the environment mapping matrix.
	 * This performs the calculation we want:
	 * u=n_x/2 + 0.5
	 * v=-n_y/2 + 0.5
	 */
	matrix4 texMat;
	texMat.MakeIdent();
	texMat._11 = 0.5;
	texMat._41 = 0.5;
	texMat._22 = -0.5;
	texMat._42 = 0.5;
	pDevice->SetTransform( D3DTS_TEXTURE1, (D3DMATRIX*)&texMat );

	/**
	 * Reflect lots of the diffuse light again
	 */
    sMaterial mat( 
		0.f, 
		color3(1.0f,1.0f,1.0f),
		color3(0.0f,0.0f,0.0f),
		color3(0.0f,0.0f,0.0f) );
    pDevice->SetMaterial(&mat);

	// Turn on that extra light we used in the glow pass too.
	pDevice->LightEnable(1, TRUE);

	/**
	 * set up add style blending
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );


	pDevice->DrawPrimitiveUP( 
		D3DPT_TRIANGLESTRIP,
		m_earthVerts.size() - 2,
		&m_earthVerts[0],
		sizeof( sMTVertex ) );

	/**
	 * Fix up all of our esoteric states
	 */
	pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
	pDevice->SetTextureStageState(1, D3DTSS_COLOROP ,D3DTOP_DISABLE );
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 );
	pDevice->LightEnable(1, FALSE);
}


void cMultiTexApp::DoGlossPass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

	/**
	 * The first color pass is just the diffuse color.
	 * the first alpha pass uses the gloss map texture.
	 * This will be modulated with the 
	 * final color before being alpha blended onto the 
	 * frame buffer.
	 */
	pDevice->SetTexture( 0, m_pTextures[1]->GetTexture() );
	SetColorStage( 
		0, 
		D3DTA_DIFFUSE, 
		D3DTA_CURRENT,
		D3DTOP_SELECTARG1 );

	SetAlphaStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_CURRENT,
		D3DTOP_SELECTARG1 );

	/**
	 * The second pass is the specular map.  It isn't even
	 * close to being correct, but it looks good enough.
	 */
	pDevice->SetTexture( 1, m_pTextures[6]->GetTexture() );
	SetColorStage( 
		1, 
		D3DTA_TEXTURE, 
		D3DTA_CURRENT, 
		D3DTOP_SELECTARG1 );

	/**
	 * Set up texture transformations.
	 */
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL  );
	pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

	/**
	 * Set up the environment mapping matrix.
	 * This performs the calculation we want:
	 * u=n_x/2 + 0.5
	 * v=-n_y/2 + 0.5
	 */
	matrix4 texMat;
	texMat.MakeIdent();
	texMat._11 = 0.5;
	texMat._41 = 0.5;
	texMat._22 = -0.5;
	texMat._42 = 0.5;
	pDevice->SetTransform( D3DTS_TEXTURE1, (D3DMATRIX*)&texMat );

	/**
	 * Reflect lots of the diffuse light again
	 */
    sMaterial mat( 
		0.f, 
		color3(1.0f,1.0f,1.0f),
		color3(0.0f,0.0f,0.0f),
		color3(0.0f,0.0f,0.0f) );
    pDevice->SetMaterial(&mat);

	// Turn on that extra light we used in the glow pass too.
	pDevice->LightEnable(1, TRUE);

	/**
	 * set up add style blending
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

	pDevice->DrawPrimitiveUP( 
		D3DPT_TRIANGLESTRIP,
		m_earthVerts.size() - 2,
		&m_earthVerts[0],
		sizeof( sMTVertex ) );

	/**
	 * Fix up all of our esoteric states
	 */
	pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
	pDevice->SetTextureStageState(1, D3DTSS_COLOROP ,D3DTOP_DISABLE );
	pDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 );
	pDevice->LightEnable(1, FALSE);
}


void cMultiTexApp::DoCloudPass()
{
	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

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

	SetColorStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_DIFFUSE, 
		D3DTOP_SELECTARG2 );

	SetAlphaStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_DIFFUSE, 
		D3DTOP_SELECTARG1 );


	/**
	 * Reflect lots of the diffuse light again
	 */
    sMaterial mat( 
		0.f, 
		color3(1.0f,1.0f,1.0f),
		color3(0.0f,0.0f,0.0f),
		color3(0.3f,0.3f,0.3f) );
    pDevice->SetMaterial(&mat);

	/**
	 * Alpha blending modulates with source color, so
	 * the brighter the texture is the more it is seen.
	 */
	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
	pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );


	pDevice->DrawPrimitiveUP( 
		D3DPT_TRIANGLESTRIP,
		m_cloudVerts.size() - 2,
		&m_cloudVerts[0],
		sizeof( sMTVertex ) );
}


/**
 * Draw a simple starry background.
 * uses the camera's location to set itself
 * up so that it's always facing towards
 * the viewer.
 */
void cMultiTexApp::DrawBackground()
{
	matrix4 mat;
	Graphics()->GetViewMatrix( &mat );

	matrix4 viewInv;
	viewInv.ToInverse( mat );

	Graphics()->SetWorldMatrix( viewInv );

	LPDIRECT3DDEVICE9 pDevice = Graphics()->GetDevice();

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

	pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	SetColorStage( 
		0, 
		D3DTA_TEXTURE, 
		D3DTA_DIFFUSE, 
		D3DTOP_SELECTARG1 );

	sLitVertex v[4];

	v[0] = sLitVertex( point3( -150,  150, 80.f ), 0, 0, 0.f, 0.f );
	v[1] = sLitVertex( point3(  150,  150, 80.f ), 0, 0, 8.f, 0.f );
	v[2] = sLitVertex( point3(  150, -150, 80.f ), 0, 0, 8.f, 8.f );
	v[3] = sLitVertex( point3( -150, -150, 80.f ), 0, 0, 0.f, 8.f );


	pDevice->SetFVF(
		D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1 );

	pDevice->DrawPrimitiveUP( 
		D3DPT_TRIANGLEFAN,
		2,
		v,
		sizeof( sLitVertex ) );

	pDevice->SetFVF(
		D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2 );
}

⌨️ 快捷键说明

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