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

📄 shader_simplefog.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************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 + -