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

📄 shader_shadows.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************

  Copyright (C) 1999, 2000 NVIDIA Corporation
  This file is provided without support, instruction, or implied warranty of any
  kind.  NVIDIA makes no guarantee of its fitness for a particular purpose and is
  not liable under any circumstances for any damages or loss whatsoever arising
  from the use or inability to use this file or items derived from it.
  
        
******************************************************************************/

#include "eb_effect.h"
#include "nvmesh.h"
#include "nvdevice.h"
#include "shader_Shadows.h"
#include "Constants.h"
#include "NVFileDialog.h"

using namespace nv_objects;
using namespace std;

DECLARE_EFFECT_MAIN()

#pragma pack( push, 1 )

class TLVertex
{
public:
	D3DXVECTOR4 Position;
	DWORD Diffuse;
	DWORD Specular;
	D3DXVECTOR2 Texture;
	enum FVF_Flags
	{
		FVF = (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)
	};
};

#pragma pack( pop )

extern "C"
{

__declspec(dllexport) unsigned int GetNumEffects() { return 1; }

__declspec(dllexport) EBEffect* CreateEffect(unsigned int EffectNum)
{
	return new CShaderShadows();
}

}

void CShaderShadows::UpdateProperties()
{
	EBEffect::UpdateProperties();
    AddProperty(new EBProperty("Wireframe", OBJECT_MEMBER(mbWireFrame), EBTYPE_BOOL_PROP));

/*    EBEnumProperty* pEnumProp = new EBEnumProperty("Blur Length Options", OBJECT_MEMBER(meBlurLengthOption), EBTYPE_DWORD_PROP);
	
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "0.5x Blur Length", (DWORD)HALFxBLURLENGTH,   EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "1.0x Blur Length", (DWORD)ONExBLURLENGTH,    EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "1.5x Blur Length", (DWORD)ONEHALFxBLURLENGTH,EBTYPE_DWORD_PROP));
	AddProperty(pEnumProp);
*/
	AddProperty(new EBProperty("Load .X File", OBJECT_MEMBER(m_bEnableShadows), EBTYPE_BOOL_PROP));
	AddProperty(new EBProperty("Enable Shadows", OBJECT_MEMBER(m_bEnableShadows), EBTYPE_BOOL_PROP));
	AddProperty(new EBProperty("ShowShadowMap", OBJECT_MEMBER(m_bShowShadowMap), EBTYPE_BOOL_PROP));
    AddProperty(new EBProperty("Pause", OBJECT_MEMBER(m_bPause), EBTYPE_BOOL_PROP));

	m_pVertexShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "Shadows", GetFilePath("ShadowShow.nvv"), EBTYPE_STRING_PROP));
}

CShaderShadows::CShaderShadows()
    : m_pNVDevice(NULL)
	, m_pFloorMesh(NULL)
	, m_pObjectMesh(NULL)
	, m_pShadowMap(NULL)
	, m_pShadowGen(NULL)
	, m_pShadowZBuffer(NULL)
	, m_pTigerTexture( NULL )
	, m_pShowShadowMapVB( NULL )
	, m_pMouseUI( NULL )
    , m_bEnableShadows( true )
    , m_bShowShadowMap(   false )
    , m_bPause(           false )
    , mbWireFrame       ( false )
{
	m_dwShadowShowShader = 0;
	m_dwShadowGenShader = 0;

	m_strEffectName = "Shadows";
	m_strEffectLocation = "Pixel Shaders";
	m_strEffectPixelShader = "";
	m_strEffectVertexShader = GetFilePath("ShadowShow.nvv");
}

CShaderShadows::~CShaderShadows()
{
	Free();	
}

#pragma optimize ("", off)
HRESULT CShaderShadows::Initialize(IDirect3DDevice8* pDev)
{
	HRESULT     hr;

	m_ShadowSize = 256;

	m_pD3DDev = pDev;
	pDev->AddRef();

	m_pNVDevice = new NVShadowsDevice(pDev, this);

	//initialize mouse UI
	RECT rect;
	rect.left = rect.top = 0;
	D3DVIEWPORT8 viewport;
	m_pD3DDev->GetViewport(&viewport);
	rect.bottom = viewport.Height;
	rect.right  = viewport.Width;
	m_pMouseUI = new MouseUI((const RECT)rect);

	{
		// Create a big square for rendering the fogmap
		if( FAILED( m_pD3DDev->CreateVertexBuffer( 4*sizeof(TLVertex), D3DUSAGE_WRITEONLY, TLVertex::FVF, 
													  D3DPOOL_MANAGED, &m_pShowShadowMapVB ) ) )
			return E_FAIL;
		// Create a quad for the final pass
		TLVertex* v;
		FLOAT sx = m_ShadowSize * 2;
		FLOAT sy = m_ShadowSize * 2;
		m_pShowShadowMapVB->Lock( 0, 0, (BYTE**)&v, 0 );

		v[0].Position = D3DXVECTOR4(0, sy, 0.5f, 1);
		v[0].Diffuse = 0x0;
		v[0].Specular = 0;
		v[0].Texture = D3DXVECTOR2(0, 1);


		v[1].Position = D3DXVECTOR4(0, 0, 0.5f, 1);
		v[1].Diffuse = 0x0;
		v[1].Specular = 0;
		v[1].Texture = D3DXVECTOR2(0, 0);
    

		v[2].Position = D3DXVECTOR4(sx, sy, 0.5f, 1);
		v[2].Diffuse = 0x0;
		v[2].Specular = 0;
		v[2].Texture = D3DXVECTOR2(1, 1);


		v[3].Position = D3DXVECTOR4(sx, 0, 0.5f, 1);
		v[3].Diffuse = 0x0;
		v[3].Specular = 0;
		v[3].Texture = D3DXVECTOR2(1, 0);

		m_pShowShadowMapVB->Unlock();
	}

	DWORD        dwVBFlags = D3DUSAGE_WRITEONLY;
	LPD3DXBUFFER pCode = NULL;

    DWORD declaration[] = 
    {
        D3DVSD_STREAM(0),
        D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
        D3DVSD_REG(D3DVSDE_NORMAL,   D3DVSDT_FLOAT3),
        D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2),
        D3DVSD_END()
    };


	m_dwShadowGenShader = 0;
	hr = LoadAndCreateShader(GetFilePath("ShadowGen.vso"), &declaration[0], 0, SHADERTYPE_VERTEX, &m_dwShadowGenShader);
	if (FAILED(hr))
		return hr;

	m_dwShadowShowShader = 0;
	hr = LoadAndCreateShader(GetFilePath("ShadowShow.vso"), &declaration[0], 0, SHADERTYPE_VERTEX, &m_dwShadowShowShader);
	if (FAILED(hr))
		return hr;

	m_dwDrawObjectShader = 0;

	hr = LoadAndCreateShader(GetFilePath("DrawObject.vso"), &declaration[0], 0, SHADERTYPE_VERTEX, &m_dwDrawObjectShader);
	if (FAILED(hr))
		return hr;

	std::string  objectNameToLoad("bigship1");

	//m_XFileDialog.Open( objectNameToLoad );

    m_pObjectMesh = new NVMesh();
    hr = m_pObjectMesh->Create(m_pNVDevice, GetFilePath(objectNameToLoad + ".x"));
	if (FAILED(hr))
	{
		m_strLastError = "Could not load " + GetFilePath(objectNameToLoad + ".x");
		return hr;
	}
	m_pObjectMesh->SetFVF(m_pNVDevice, ShadowsVertex::FVF );
	m_pObjectMesh->SetVertexShader(m_dwShadowGenShader);
    m_pObjectMesh->RestoreDeviceObjects(m_pNVDevice);

	m_Models.push_back( ModelInstance( m_pObjectMesh, m_pObjectMesh->m_pTexture ) );
	
	//(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) PURE;
	hr = m_pNVDevice->GetDevice()->CreateDepthStencilSurface( m_ShadowSize,
															  m_ShadowSize,
															  D3DFMT_D24X8,
															  D3DMULTISAMPLE_NONE,
															  &m_pShadowZBuffer );
	if (FAILED(hr))
	{
		m_strLastError = "Could not Create Shadow ZBuffer";
		return hr;
	}

    //STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) PURE;
	hr = m_pNVDevice->GetDevice()->CreateTexture( m_ShadowSize,
												  m_ShadowSize,
												  1,
												  D3DUSAGE_RENDERTARGET,
												  D3DFMT_A8R8G8B8,
												  D3DPOOL_DEFAULT,
											      &m_pShadowMap );
	if (FAILED(hr))
	{
		m_strLastError = "Could not Create Shadow ZBuffer";
		return hr;
	}

	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath( "ShadowMap.tga").c_str(),
		2048,
		256,
		1,
		0,
		D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT,
		D3DX_FILTER_NONE,
		D3DX_FILTER_NONE,
		0,
		NULL,
		NULL,
		&m_pShadowGen );

	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath( "tiger.dds").c_str(),
		D3DX_DEFAULT, //w
		D3DX_DEFAULT,	// h
		D3DX_DEFAULT,	// mips
		0,
		D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT,
		D3DX_FILTER_LINEAR,
		D3DX_FILTER_LINEAR,
		0,
		NULL,
		NULL,
		&m_pTigerTexture );

	if (FAILED(hr))
	{
		m_strLastError = "Could not Load Shadow GenTexture " + GetFilePath(objectNameToLoad + ".dds");
		return hr;
	}

	D3DLIGHT8 aLight;

	aLight.Type = D3DLIGHT_SPOT;
	aLight.Diffuse.r = 1.0f;
	aLight.Diffuse.g = 1.0f;
	aLight.Diffuse.b = 1.0f;

	aLight.Specular.r = 0.0f;
	aLight.Specular.g = 0.0f;
	aLight.Specular.b = 0.0f;

	aLight.Ambient.r = 0.0f;
	aLight.Ambient.g = 0.0f;
	aLight.Ambient.b = 0.0f;

	aLight.Position.x = 0.0f;
	aLight.Position.y = 100.0f;
	aLight.Position.z = 0.0f;

	aLight.Range = 100.0f;
	aLight.Falloff = 100.0f;

	aLight.Direction.x =  0.0f;
	aLight.Direction.y = -1.0f;
	aLight.Direction.z =  0.0f;

	aLight.Attenuation0 = 0.0f;
	aLight.Attenuation1 = 1.0f;
	aLight.Attenuation2 = 0.0f;

	aLight.Theta = 0.0f;
	aLight.Phi = 45.0f;

	m_Lights[ 0 ] = aLight;
   
    m_numVertices = m_pObjectMesh->GetSysMemMesh()->GetNumVertices();

	// Load the seafloor x file and extract its mesh
    m_pFloorMesh = new NVMesh();
    hr = m_pFloorMesh->Create(m_pNVDevice, GetFilePath("seafloor.x"));
	if (FAILED(hr))
	{
		m_strLastError = "Could not create seafloor.x";
		return hr;
	}
	m_pFloorMesh->SetFVF(m_pNVDevice, ShadowsVertex::FVF );
	m_pFloorMesh->SetVertexShader(m_dwShadowGenShader);

    IDirect3DVertexBuffer8* pVB;

    // Add some "hilliness" to the terrain
    if( SUCCEEDED( m_pFloorMesh->GetSysMemMesh()->GetVertexBuffer( &pVB ) ) )
    {
        ShadowsVertex* pVertices;
        DWORD   dwNumVertices = m_pFloorMesh->GetSysMemMesh()->GetNumVertices();

        pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );

        for( DWORD i=0; i<dwNumVertices; i++ )
		{
			pVertices[i].Position.y  += (rand()/(FLOAT)RAND_MAX);
			pVertices[i].Position.y  += (rand()/(FLOAT)RAND_MAX);
			pVertices[i].Position.y  += (rand()/(FLOAT)RAND_MAX);
			pVertices[i].Texture.x *= 10;
			pVertices[i].Texture.y *= 10;
		}

        pVB->Unlock();
        pVB->Release();
    }

    m_pFloorMesh->RestoreDeviceObjects(m_pNVDevice);

    // set up render state
    m_pD3DDev->SetRenderState( D3DRS_LIGHTING,	     FALSE );
    m_pD3DDev->SetRenderState( D3DRS_STENCILENABLE,  FALSE );

    m_pD3DDev->SetRenderState( D3DRS_CULLMODE,       D3DCULL_NONE ); 
    m_pD3DDev->SetRenderState( D3DRS_FOGENABLE,      FALSE);

    m_pD3DDev->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
    m_pD3DDev->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
    m_pD3DDev->SetRenderState( D3DRS_ZENABLE,        TRUE );

	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE );

    m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
    m_pD3DDev->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    // Setup render states
    m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2);
	m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

	m_pD3DDev->SetVertexShaderConstant(CV_CONSTANTS, D3DXVECTOR4(0.0f,1.0f,0.5f,2.0f), 1);
	
    // Projection set up
    D3DXMATRIX        matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
	m_pNVDevice->SetProjectionTransform(&matProj);
	return S_OK;
}
#pragma optimize ("", on)

HRESULT CShaderShadows::Free()
{
	SAFE_DELETE( m_pMouseUI );

⌨️ 快捷键说明

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