📄 shader_shadows.cpp
字号:
/******************************************************************************
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 + -