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

📄 shader_trees.cpp

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

  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:
    
      
        
******************************************************************************/

#include "eb_effect.h"
#include "nvmesh.h"
#include "nvdevice.h"
#include "shader_Trees.h"
#include "trees.h"
#include <algorithm>

using namespace nv_objects;
using namespace std;


DECLARE_EFFECT_MAIN()

extern "C"
{

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

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

}

// Old-style D3D vertices
class Vertex
{
public:
	Vertex(const D3DXVECTOR3& Pos, const D3DXVECTOR3& Norm, const D3DXVECTOR2& Tex)
		: Position(Pos), Normal(Norm), Texture(Tex)
	{}

	Vertex()
	{}

	D3DXVECTOR3 Position;
	D3DXVECTOR3 Normal;
	D3DXVECTOR2 Texture;
};

class TLVertex
{
public:
	D3DXVECTOR4 Position;
	DWORD Diffuse;
	DWORD Specular;
	D3DXVECTOR2 Texture;
};

#define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
#define D3DFVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)


// Function to compare two trees relative to the eye.
class CompareToEye
{
private:
	D3DXVECTOR3 m_EyePoint;

public:
	CompareToEye(D3DXVECTOR3 EyePoint)
		: m_EyePoint(EyePoint)
	{}

	bool operator()(const Tree& lhs, const Tree& rhs) const
	{
		D3DXVECTOR3 lPos = lhs.vPos;
		lPos.y = 0.0f;

		D3DXVECTOR3 rPos = rhs.vPos;
		rPos.y = 0.0f;

		D3DXVECTOR3 vEye = m_EyePoint;
		vEye.y = 0.0f;

		lPos -= vEye;
		rPos -= vEye;

		return D3DXVec3LengthSq(&lPos) < D3DXVec3LengthSq(&rPos);
	}
};

CShaderTrees::CShaderTrees(TreeType Type)
      : mbWireFrame(false),
        m_TreeType(Type),
	    m_pTerrain(NULL),
		m_pTreeTexture(NULL),
		m_pFishViewVB(NULL),
		m_pTreeVB(NULL),
		m_pNVDevice(NULL),
		m_pFishViewTexture(NULL),
		m_dwTerrainShader(0),
		m_dwTreeShader(0),
		m_bPause(false),
		m_fDuration(0.0f)
{
    ;
}

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

// Simple function to define "hilliness" for terrain
float CShaderTrees::HeightField( FLOAT x, FLOAT y )
{
    return 9*(cosf(x/20+0.2f)*cosf(y/15-0.2f)+1.0f);
}

HRESULT CShaderTrees::Initialize(IDirect3DDevice8* pDev)
{
	HRESULT hr;
	vector<DWORD> Declaration;
	D3DXMATRIX matWorld;
	D3DXMATRIX matView;
	D3DXMATRIX matProj;

	m_pD3DDev = pDev;
	pDev->AddRef();

	m_pNVDevice = new NVTreeDevice(pDev, this);

	DWORD dwVBFlags = D3DUSAGE_WRITEONLY;

	// Create the shader
	Declaration.clear();
	Declaration.push_back(D3DVSD_STREAM(0));
	Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3));
	Declaration.push_back(D3DVSD_REG(1, D3DVSDT_D3DCOLOR));
	Declaration.push_back(D3DVSD_REG(2, D3DVSDT_FLOAT2));
	Declaration.push_back(D3DVSD_END());
	hr = LoadAndCreateShader(GetFilePath("FishEye_Tree.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwTreeShader);
	if (FAILED(hr))
		return hr;

	Declaration.clear();
	Declaration.push_back(D3DVSD_STREAM(0));
	Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3));
	Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT3));
	Declaration.push_back(D3DVSD_REG(2, D3DVSDT_FLOAT2));
	Declaration.push_back(D3DVSD_END());
	hr = LoadAndCreateShader(GetFilePath("FishEye_Terrain.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwTerrainShader);
	if (FAILED(hr))
		return hr;

	// Create the fisheye view
	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath("FishView.dds").c_str(),
		D3DX_DEFAULT,
		D3DX_DEFAULT,
		1,
		0,
		D3DFMT_UNKNOWN,
		D3DPOOL_MANAGED,
		D3DX_FILTER_LINEAR,
		D3DX_FILTER_LINEAR,
		0,
		NULL,
		NULL,
		&m_pFishViewTexture);
	if (FAILED(hr))
	{
		m_strLastError = "Could not load texture FishView.dds";
		return hr;
	}
	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath("tree0.dds").c_str(),
		D3DX_DEFAULT,
		D3DX_DEFAULT,
		0,
		0,
		D3DFMT_UNKNOWN,
		D3DPOOL_MANAGED,
		D3DX_FILTER_LINEAR,
		D3DX_FILTER_LINEAR,
		0,
		NULL,
		NULL,
		&m_pTreeTexture);
	if (FAILED(hr))
	{
		m_strLastError = "Could not load texture tree0.dds";
		return hr;
	}

    // Load a ground object
    m_pTerrain = new NVMesh();
    if( FAILED( m_pTerrain->Create(m_pNVDevice, GetFilePath("seafloor.x") ) ) )
	{
		m_strLastError = "Could not load seafloor.x";
        return E_FAIL;
	}
	DWORD dwFVF = m_pTerrain->GetSysMemMesh()->GetFVF();
	m_pTerrain->SetFVF(m_pNVDevice, D3DFVF_TEX1 | D3DFVF_NORMAL | D3DFVF_XYZ);

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

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

        for( DWORD i=0; i<dwNumVertices; i++ )
            pVertices[i].Position.y = HeightField( pVertices[i].Position.x, pVertices[i].Position.z );

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

	m_vecTrees.resize(NUM_TREES);
    // Initialize the tree data
    for( WORD i=0; i<NUM_TREES; i++ )
    {
        // Position the trees randomly
        FLOAT fTheta  = 2.0f*D3DX_PI*(FLOAT)rand()/RAND_MAX;
        FLOAT fRadius = 25.0f + 55.0f * (FLOAT)rand()/RAND_MAX;
        m_vecTrees[i].vPos.x  = fRadius * sinf(fTheta);
        m_vecTrees[i].vPos.z  = fRadius * cosf(fTheta);
        m_vecTrees[i].vPos.y  = HeightField( m_vecTrees[i].vPos.x, m_vecTrees[i].vPos.z );

        // Size the trees randomly
        FLOAT fWidth  = 1.0f + 0.2f * (FLOAT)(rand()-rand())/RAND_MAX;
        FLOAT fHeight = 1.4f + 0.4f * (FLOAT)(rand()-rand())/RAND_MAX;

        // Each tree is a random color between red and green
        DWORD r = (255-190) + (DWORD)(190*(FLOAT)(rand())/RAND_MAX);
        DWORD g = (255-190) + (DWORD)(190*(FLOAT)(rand())/RAND_MAX);
        DWORD b = 0;
        DWORD dwColor = 0xff000000 + (r<<16) + (g<<8) + (b<<0);

        m_vecTrees[i].v[0].p     = D3DXVECTOR3(-fWidth, 0*fHeight, 0.0f );
        m_vecTrees[i].v[0].color = dwColor;
        m_vecTrees[i].v[0].tu    = 0.0f;   m_vecTrees[i].v[0].tv = 1.0f;
        m_vecTrees[i].v[1].p     = D3DXVECTOR3(-fWidth, 2*fHeight, 0.0f  );
        m_vecTrees[i].v[1].color = dwColor;
        m_vecTrees[i].v[1].tu    = 0.0f;   m_vecTrees[i].v[1].tv = 0.0f;
        m_vecTrees[i].v[2].p     = D3DXVECTOR3( fWidth, 0*fHeight, 0.0f  );
        m_vecTrees[i].v[2].color = dwColor;
        m_vecTrees[i].v[2].tu    = 1.0f;   m_vecTrees[i].v[2].tv = 1.0f;
        m_vecTrees[i].v[3].p     = D3DXVECTOR3( fWidth, 2*fHeight, 0.0f  );
        m_vecTrees[i].v[3].color = dwColor;
        m_vecTrees[i].v[3].tu    = 1.0f;   m_vecTrees[i].v[3].tv = 0.0f;
    }

    // Check the alpha test caps of the device. (The alpha test offers a 
    // performance boost to not render pixels less than some alpha threshold.)
    //m_bUseAlphaTest = ( m_d3dCaps.TriCaps.dwAlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL );
        
    // Create a big square for rendering the fish view mask
    if( FAILED( m_pD3DDev->CreateVertexBuffer( 4*sizeof(TLVertex),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_TLVERTEX, 
                                                  D3DPOOL_MANAGED, &m_pFishViewVB ) ) )
        return E_FAIL;

    // Create a square for rendering each tree.  We modify, but only write
    if( FAILED( m_pD3DDev->CreateVertexBuffer( NUM_TREES * 4*sizeof(TREEVERTEX),
                                                  D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFVF_TREEVERTEX,
                                                  D3DPOOL_DEFAULT, &m_pTreeVB ) ) )
        return E_FAIL;


	IDirect3DSurface8* pBackBuffer;
	m_pD3DDev->GetRenderTarget(&pBackBuffer);
	D3DSURFACE_DESC ddsd;

	pBackBuffer->GetDesc(&ddsd);

	m_dwWidth = ddsd.Width;
	m_dwHeight = ddsd.Height;
	SAFE_RELEASE(pBackBuffer);

	// Create a quad for the final pass
    TLVertex* v;
    FLOAT sx = (FLOAT)m_dwWidth;
    FLOAT sy = (FLOAT)m_dwHeight / 2;
    m_pFishViewVB->Lock( 0, 0, (BYTE**)&v, 0 );

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

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

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

    m_pFishViewVB->Unlock();

   	// Projection doesn't change
	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 0.3f, 100.0f );
	m_pNVDevice->SetProjectionTransform(&matProj);


	// Load values for the distortion shader
	float fXZRatio       = 2.5f;
	float fkDistortion   = 2.0f;
	float fkp1Distortion = fkDistortion + 1.0f;
	m_pD3DDev->SetVertexShaderConstant(CV_FISHEYEINFO, D3DXVECTOR4(fXZRatio, fkDistortion, 0.0f, 1.0f), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_CONSTANTS,   D3DXVECTOR4(fkp1Distortion, 1.0f, 0.0f, 0.0f), 1);

	m_pTerrain->RestoreDeviceObjects(m_pNVDevice);

	return S_OK;

}

HRESULT CShaderTrees::Free()
{
	SAFE_DELETE(m_pNVDevice);
	SAFE_DELETE(m_pTerrain);

    SAFE_RELEASE(m_pFishViewVB )
    SAFE_RELEASE(m_pTreeVB )
    
    SAFE_RELEASE(m_pTreeTexture);
	SAFE_RELEASE(m_pFishViewTexture);

	if (m_pD3DDev)

⌨️ 快捷键说明

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