📄 shader_simplefog.cpp
字号:
/*********************************************************************NVMH2****
Path: C:\DEV\devrel\NV_SDK_4\DX8\NVEffectsBrowser\Effects\SimpleFog
File: shader_SimpleFog.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.
Comments:
This code doesn't use vertex buffers to render the terrain. For any sort
of serious application, this is a big mistake. You should use vertex buffers
all the time. We have papers on our developer website about this. Switching
to vertex buffers does not change the vertex or pixel shader code in any way.
******************************************************************************/
#include "eb_effect.h"
#include "nvdevice.h"
#include "shader_SimpleFog.h"
#include "SimpleFog.h"
#include "NV_Error.h"
#include "SimpleObject8.h"
using namespace std;
#define DTOR (D3DX_PI / 180.0f)
DECLARE_EFFECT_MAIN()
extern "C"
{
__declspec(dllexport) unsigned int GetNumEffects() { return 1; }
__declspec(dllexport) EBEffect* CreateEffect(unsigned int EffectNum)
{
return new CShaderSimpleFog();
}
}
CShaderSimpleFog::CShaderSimpleFog() :
m_fAngle(0.0f),
m_dwSimpleFogPixelShader(0),
m_dwSimpleFogNoLightShader(0),
m_dwSimpleFogVShader(0)
{
m_strEffectName = "Simple Fog";
m_strEffectLocation = "Pixel Shaders\\Lighting";
m_strEffectPixelShader = GetFilePath("SimpleFog.nvp");
m_strEffectVertexShader = GetFilePath("SimpleFog.nvv");
m_pDecalTexture = NULL;
m_pLightObjTexture = NULL;
m_bWireframe = false;
m_pObjLight = NULL;
m_pObj = NULL;
}
void CShaderSimpleFog::UpdateProperties()
{
EBEffect::UpdateProperties();
// Vertex shaders
m_pVertexShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "SimpleFog", GetFilePath("SimpleFog.nvv"), EBTYPE_STRING_PROP));
// Pixel Shaders
m_pPixelShaderEnum->AddEnumerant(new EBEnumValue(m_pPixelShaderEnum, "SimpleFog", GetFilePath("SimpleFog.nvp"), EBTYPE_STRING_PROP));
}
CShaderSimpleFog::~CShaderSimpleFog()
{
Free();
}
HRESULT CShaderSimpleFog::Free()
{
if( m_pObj != NULL )
{
delete m_pObj;
m_pObj= NULL;
}
if( m_pObjLight != NULL )
{
delete m_pObjLight;
m_pObjLight= NULL;
}
SAFE_RELEASE(m_pDecalTexture);
SAFE_RELEASE(m_pLightObjTexture);
if (m_pD3DDev)
{
m_pD3DDev->DeletePixelShader(m_dwSimpleFogPixelShader);
m_dwSimpleFogPixelShader = NULL;
m_pD3DDev->DeletePixelShader(m_dwSimpleFogNoLightShader);
m_dwSimpleFogNoLightShader = NULL;
m_pD3DDev->DeleteVertexShader(m_dwSimpleFogVShader);
m_dwSimpleFogVShader = NULL;
SAFE_RELEASE(m_pD3DDev);
}
return S_OK;
}
HRESULT CShaderSimpleFog::Initialize(IDirect3DDevice8* pDev)
{
FDebug("\n\n");
FDebug("Begin CShaderSimpleFog::Initialize...\n");
HRESULT hr;
m_pD3DDev = pDev;
pDev->AddRef();
///////////////////////////////////////////////////////////
m_pObj = new SimpleObject8;
assert( m_pObj != NULL );
SetDefaultObj();
// Make light stand-in object:
m_pObjLight = new SimpleObject8;
assert( m_pObj != NULL );
m_pObjLight->InitSphere( 0.12f, 8, 8 );
////////////////////////////////////////////////////////
// Load pixel shaders for objects
hr = LoadAndCreateShader(GetFilePath("SimpleFog.pso"), NULL, 0,
SHADERTYPE_PIXEL, &m_dwSimpleFogPixelShader);
if (FAILED(hr))
{
FDebug("Can't create SimpleFog.pso\n");
return hr;
}
hr = LoadAndCreateShader(GetFilePath("SimpleFogNoLight.pso"), NULL, 0,
SHADERTYPE_PIXEL, &m_dwSimpleFogNoLightShader);
if (FAILED(hr))
{
FDebug("Can't create SimpleFogNoLight.pso\n");
return hr;
}
////////////////////////////////////////////////////////
// Load vertex shader for two-sided lighting
vector<DWORD> Declaration;
// Microsoft's D3DVSD_REG is not working properly, so use
// this STL vector method instead
Declaration.clear();
Declaration.push_back(D3DVSD_STREAM(0));
Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3 )); // Pos
Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT3 )); // Normal
Declaration.push_back(D3DVSD_REG(2, D3DVSDT_D3DCOLOR)); // Diffuse
Declaration.push_back(D3DVSD_REG(3, D3DVSDT_FLOAT2 )); // Texture
Declaration.push_back(D3DVSD_END());
m_dwSimpleFogVShader = 0;
hr = LoadAndCreateShader(GetFilePath("SimpleFog.vso"), &Declaration[0], 0,
SHADERTYPE_VERTEX, &m_dwSimpleFogVShader);
if (FAILED(hr))
{
assert( false );
return hr;
}
////////////////////////////////////////////////////////
m_pD3DDev->SetRenderState(D3DRS_LIGHTING,TRUE);
m_pD3DDev->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);
m_pD3DDev->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESS);
m_pD3DDev->SetRenderState(D3DRS_NORMALIZENORMALS,TRUE);
m_pD3DDev->SetRenderState(D3DRS_LOCALVIEWER,TRUE);
m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
if( m_bWireframe )
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
else
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
}
// Set light color in vertex shader constant
DWORD lcol = 0x00FFFFFF; // white
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_COLOR, &lcol, 1);
hr = D3DXCreateTextureFromFile(m_pD3DDev, GetFilePath("blank.tga").c_str(), &m_pLightObjTexture);
if (FAILED(hr))
{
FDebug("Could not create m_pLightObjTexture texture!");
return E_FAIL;
}
hr = D3DXCreateTextureFromFile(m_pD3DDev, GetFilePath("basetex_01.jpg").c_str(), &m_pDecalTexture);
if (FAILED(hr))
{
FDebug("Could not create m_pDecalTexture texture!");
return E_FAIL;
}
m_pD3DDev->SetTexture(0,(LPDIRECT3DBASETEXTURE8)m_pDecalTexture);
m_pD3DDev->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
m_pD3DDev->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
m_pD3DDev->SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
m_pD3DDev->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU | 0 );
// Camera stuff
SetDefaultView();
m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
// Note how the D3DXVECTOR4 struct knows how to automaticaly cast itself
// to a float* ? Sneaky sneaky!
m_pD3DDev->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
m_pD3DDev->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
// CV_LIGHT_CONST -> x = ambient
// y = ambient for back facing illumination - transparency
// z = back facing const attenuation
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_CONST, D3DXVECTOR4(0.45f, 0.1f, 0.7f, 0.0f), 1);
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_CONST, D3DXVECTOR4(0.15f, 0.1f, 0.7f, 0.0f), 1);
m_vHtFogColor = D3DXVECTOR4(0.90f, 0.90f, 1.0f, 0.0f); // RGBA
//m_vHtFogColor = D3DXVECTOR4(0.20f, 0.20f, 0.5f, 0.0f); // RGBA
m_pD3DDev->SetPixelShaderConstant(CP_HEIGHT_FOG_COLOR, &m_vHtFogColor, 1);
FDebug("End CShaderSimpleFog::Initialize...\n");
return S_OK;
}
void CShaderSimpleFog::SetView()
{
// Create view matrix
D3DXMatrixLookAtLH( &m_matView, &m_EyePos, &m_vLookAt, &m_vUp);
D3DXMatrixInverse( &m_matViewInv, NULL, &m_matView );
}
void CShaderSimpleFog::SetDefaultObj()
{
m_nHDiv = 55;
m_nVDiv = 55;
m_fHtFogFac = 0.4f;
m_fWidth = 15.0f;
GenerateObj();
}
void CShaderSimpleFog::GenerateObj()
{
assert( m_pObj != NULL );
// Init a flat grid of geometry (twist = 0.0f => flat):
m_pObj->InitSpiral( m_fWidth, m_fWidth, m_nHDiv, m_nVDiv, 0.0f );
D3DXVECTOR3 vNoiseDir;
vNoiseDir = D3DXVECTOR3( -1.0f, 0.0f, 0.0f ); // direction of noise perturbation
// Make a fractalish landscape by adding noise of varying roughness
// This is what generates the terrain-like geometry
// 1st param = direction to offset positions
// 2nd param = magnitude of max offset
// 3rd = sets grid width for smoothing a 2D array of noise
// 4th = number of smoothing passes - the more, the smoother
m_pObj->AddPositionNoiseGrid( vNoiseDir, 2.0f, m_nHDiv+2, 38 ); // smooth big lumps
m_pObj->AddPositionNoiseGrid( vNoiseDir, 1.0f, m_nHDiv+2, 18 ); // less smooth smaller lumps
m_pObj->AddPositionNoiseGrid( vNoiseDir, 0.5f, m_nHDiv+2, 2 ); // short rough lumps
m_pObj->TranslateXMinToZero(); // move terrain base back down to x=0
m_pObj->GenerateNormals();
}
void CShaderSimpleFog::SetDefaultView()
{
// also set default object parameters:
SetDefaultObj();
// Set default view:
m_EyePos.x = 0.0f;
m_EyePos.y = -10.0f;
m_EyePos.z = 5.0f;
m_vLookAt.x = 0.0f;
m_vLookAt.y = 0.0f;
m_vLookAt.z = 0.0f;
m_vUp.x = 0.0f;
m_vUp.y = 0.0f;
m_vUp.z = 1.0f;
// Set world matrix to view from an angle
D3DXMatrixIdentity(&m_matWorld);
// Set field of view
D3DXMatrixPerspectiveFovLH(&m_matProj, D3DXToRadian(55.0f),
1.0f,
0.1f, 500.0f); // znear,far
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -