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

📄 effect_reflectivebumpdynamic.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************NVMH2****
Path:  C:\DEV\devrel\NV_SDK_4\DX8\NVEffectsBrowser\Effects\ReflectiveBumpDynamic
File:  Effect_ReflectiveBumpDynamic.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:


******************************************************************************/



#include "eb_effect.h"

#include "CA_Water.h"

#include "nvdevice.h"
#include "NV_Error.h"

#include "SimpleObject8.h"
#include "Dot3_util.h"
#include "Effect_ReflectiveBumpDynamic.h"

#include "Constants.h"
#include "PixelConstants.h"

#include <vector>

using namespace nv_objects;
using namespace std;


/////////////////////////////////////////////////

#define INIT_BUMPSCALE		0.12f

/////////////////////////////////////////////////

#ifndef ASSERT_IF_FAILED
	#define ASSERT_IF_FAILED( hres )	\
	{									\
		if( FAILED(hres) )				\
		   assert( false );				\
	}
#endif


/////////////////////////////////////////////////

DECLARE_EFFECT_MAIN()
DECLARE_EFFECT_COUNT(1)
DECLARE_EFFECT_CREATE_BEG()
DECLARE_EFFECT_CREATE(0, NVEffect_DynamicReflection())
DECLARE_EFFECT_CREATE_END()


///////////////////////////////////////////////////////////////////////////


HRESULT NVEffect_DynamicReflection::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
	if (!(pCaps->TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
	{
		m_strLastError = "Device does not support cubemaps!";
		return E_FAIL;
	}

	if (!(pCaps->TextureCaps & D3DPTEXTURECAPS_PROJECTED))
	{
		m_strLastError = "Device does not support 3 element texture coordinates!";
		return E_FAIL;
	}

	if (!(pCaps->MaxTextureBlendStages >= 4))
	{
		m_strLastError = "Not enough texture blend stages!";
		return E_FAIL;
	}

	if(D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion) < 1)
	{
		m_strLastError = "Device does not support pixel shaders!";
		return E_FAIL;
	}

    if(!(pCaps->DevCaps & D3DDEVCAPS_RTPATCHES) )
    {
        m_strLastError = "Device does not support RTPATCHES!";
        return E_FAIL;
    }

	return S_OK;
}

#define STR_INCREASEBUMPSCALE "Bump scale increase (+)"
#define STR_DECREASEBUMPSCALE "Bump scale decrease (-)"
#define STR_RESETPATCH "Reset patch offset (HOME)"
#define STR_MOREOPTION "Hit F1 for more options!"


void NVEffect_DynamicReflection::UpdateProperties()
{
	EBEffect::UpdateProperties();

	AddProperty(new EBTriggerProperty(STR_INCREASEBUMPSCALE));
	AddProperty(new EBTriggerProperty(STR_DECREASEBUMPSCALE));
	AddProperty(new EBTriggerProperty(STR_RESETPATCH));
	AddProperty(new EBTriggerProperty(STR_MOREOPTION));

    EBEnumProperty* pEnumProp = new EBEnumProperty("Display Options", OBJECT_MEMBER(m_eDisplayOption), EBTYPE_DWORD_PROP);

	if (m_bSupportsQWVU)
		pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "8 Bit Signed BumpMap",
		(DWORD)DISPLAY_BLINN8BITSIGNED, EBTYPE_DWORD_PROP));


	AddProperty(pEnumProp);
    
	if (m_bSupportsPatches)
	{
		AddProperty(new EBProperty("Show Bezier-Patch", OBJECT_MEMBER(m_bUsePatch), EBTYPE_BOOL_PROP));
	}

	AddProperty(new EBProperty("Wireframe", OBJECT_MEMBER(m_bWireframe), EBTYPE_BOOL_PROP));
	AddProperty(new EBProperty("Pause geometry animation", OBJECT_MEMBER(m_bPause), EBTYPE_BOOL_PROP));

	//////////////////////////////////////////////////////////////

    string aboutText = "file://";
    aboutText += GetFilePath("NVEffectsExplained.htm");
    aboutText += "#DynamicTrueReflectiveBumpMapping";
	SetAboutInfo( NULL, _T("Dynamic Normal Map"), _T(aboutText.c_str()));
	SetAboutInfo( NULL, _T("Developer Relations"), _T("http://www.nvidia.com/developer"));
	SetAboutInfo( NULL, _T("NVIDIA Corporation"), _T("http://www.nvidia.com"));
	SetAboutInfo( _T("Date"), _T("April 2001"));


	//////////////////////////////////////////////////////////////////////////
	// Add vertex & pixel shader display to the tabbed text boxes:
	// No need to GetFilePath() with these.  The Add..() function does it for you

	// Vertex shaders
	AddShaderCodeFile( SHADERTYPE_VERTEX, "Texture Space",		"blinn_reflect.nvv" );
	AddShaderCodeFile( SHADERTYPE_VERTEX, "Simple Transform",	"dot3_transform.nvv");


	// Pixel shaders
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Per-pixel Bump Reflections",	"blinn_reflect.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Neighbor Sampling Setup",		"TexCoord_4_Offset.nvv");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Force: Step 1",			"NeighborForceCalc.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Force: Step 2",			"NeighborForceCalc2.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Apply Force",				"ApplyForceShader.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Apply Velocity",			"ApplyVelocityShader.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Smooth",				"EqualWeightCombine_PostMult.nvp");
	AddShaderCodeFile( SHADERTYPE_PIXEL, "Gray to NormalMap",	"NormalMapCreate2_Scale.nvp");

}


NVEffect_DynamicReflection::NVEffect_DynamicReflection()
:	m_eDisplayOption(DISPLAY_BLINN8BITSIGNED),
	m_pPatchBuffer(NULL),
	m_pVertexBuffer(NULL),
    m_pIndexBuffer(NULL),
	m_fAngle(0.0f),
	m_pNVDevice(NULL),
	m_pBumpMapQWVU(NULL),
    m_bUsePatch(true),
	m_dwBlinnPixelShader(0),
	m_dwBlinnVertexShader(0),
	m_dwTransformShader(0),
	m_dwBlinnPatchVertexShader(0),
	m_dwTransformPatchShader(0),
	m_pCubeTexture(NULL),
	m_bSupportsPatches(true),
	m_pUI(NULL),
	m_bWireframe(false),
	m_bPause(true),
	m_fBumpScale(INIT_BUMPSCALE),
	m_pCA_Water(NULL)
{
	m_strEffectName = "Dynamic Normal Map";	// A string holding the name of the effect
	m_strEffectLocation = "Effects\\Bump Mapping";
	m_strEffectPixelShader = GetFilePath("blinn_reflect.nvp");
	m_strEffectVertexShader = GetFilePath("blinn_reflect.nvv");
	m_strEffectVersion  = "1.0";
}

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



#define TEX_SCALE 3.0f

HRESULT NVEffect_DynamicReflection::GenerateSphere(D3DXVECTOR3& vCenter, FLOAT fRadius, WORD wNumRings,
											WORD wNumSections, FLOAT scale_x, FLOAT scale_y, FLOAT scale_z)
{

	SimpleObject8	* pObj = new SimpleObject8();
	assert( pObj != NULL );

	pObj->InitSphere( fRadius, wNumRings, wNumSections );


	////////////////////////////////////////////////
	// Make vertex buffer & index buffer from it

	HRESULT hr;
	D3DXVECTOR3 vPoint;
	DWORD i;

	SAFE_RELEASE(m_pVertexBuffer);
    SAFE_RELEASE(m_pIndexBuffer);

	assert( pObj->m_PrimType == D3DPT_TRIANGLELIST );


	DWORD	wNumTriangles	= pObj->m_wNumInd / 3;
    DWORD   dwNumIndices	= pObj->m_wNumInd;
    DWORD   dwNumVertices	= pObj->m_wNumVerts;

	m_dwNumVertices = dwNumVertices;
	m_dwNumIndices = wNumTriangles * 3;
	m_dwNumFaces = wNumTriangles;	


	hr = m_pD3DDev->CreateVertexBuffer(dwNumVertices * sizeof(Dot3Vertex), 0, 0, D3DPOOL_DEFAULT,
										&m_pVertexBuffer);
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;

	hr = m_pD3DDev->CreateIndexBuffer(3 * wNumTriangles * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT,
										&m_pIndexBuffer);
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;


	Dot3Vertex* pVertices;
	WORD* pIndices;
	
	m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertices, 0);
	m_pIndexBuffer->Lock(0, 0, (BYTE**)&pIndices, 0);

	
	float x,y,z, nx, ny, nz, u, v;

	// copy positions into VB
    for( i = 0; i < dwNumVertices; i++ )
    {
		x = scale_x * pObj->m_pVertices[i].pos.x	+ vCenter.x;
		y = scale_y * pObj->m_pVertices[i].pos.y	+ vCenter.y;
		z = scale_z * pObj->m_pVertices[i].pos.z	+ vCenter.z;

		nx = pObj->m_pVertices[i].nrm.x;
		ny = pObj->m_pVertices[i].nrm.y;
		nz = pObj->m_pVertices[i].nrm.z;

		u = pObj->m_pVertices[i].t0.x * TEX_SCALE;
		v = pObj->m_pVertices[i].t0.y * TEX_SCALE;

		pVertices[i] = Dot3Vertex(	D3DXVECTOR3( x, y, z ),
									D3DXVECTOR3( nx, ny, nz ),
									D3DXVECTOR2( u, v ) );
	}



    // Generate triangle index buffer from simple object's indices

    for( i = 0; i < dwNumIndices; i++ )
    {
        pIndices[i] = pObj->m_pIndices[i];
	}


	// All done - unlock the buffers:

	hr = m_pVertexBuffer->Unlock();
	ASSERT_IF_FAILED(hr);

	hr = m_pIndexBuffer->Unlock();
	ASSERT_IF_FAILED(hr);


	// Free the SimpleObject

	delete( pObj );
	pObj = NULL;


	// Compute the tangent space
	// Degenerate vertices (same position, different coords) are
	//  found and averaged in the CreateBasis

	hr = CreateBasisVectors( m_pVertexBuffer, m_pIndexBuffer);
	ASSERT_IF_FAILED(hr);


    return S_OK;
}



HRESULT NVEffect_DynamicReflection::GenerateQuad(D3DXVECTOR3& vCenter, FLOAT fRadius)
{
	SAFE_RELEASE(m_pVertexBuffer);
	SAFE_RELEASE(m_pIndexBuffer);

	m_dwNumVertices = 4;
	m_dwNumIndices = 6;
	m_dwNumFaces = m_dwNumIndices / 3;	

	m_pD3DDev->CreateVertexBuffer(m_dwNumVertices * sizeof(Dot3Vertex), 0, 0, D3DPOOL_MANAGED, &m_pVertexBuffer);
	m_pD3DDev->CreateIndexBuffer(m_dwNumIndices * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIndexBuffer);

	Dot3Vertex* pVertices;
	WORD* pIndices;
	
	m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertices, 0);
	m_pIndexBuffer->Lock(0, 0, (BYTE**)&pIndices, 0);

	pVertices[0] = Dot3Vertex(D3DXVECTOR3(vCenter.x - fRadius, vCenter.y + fRadius, 0.0f), D3DXVECTOR3(0.0f, 0.0f, -1.0f), D3DXVECTOR2(0.0f, 0.0f));
	pVertices[1] = Dot3Vertex(D3DXVECTOR3(vCenter.x + fRadius, vCenter.y + fRadius, 0.0f), D3DXVECTOR3(0.0f, 0.0f, -1.0f), D3DXVECTOR2(1.0f * TEX_SCALE, 0.0f));
	pVertices[2] = Dot3Vertex(D3DXVECTOR3(vCenter.x - fRadius, vCenter.y - fRadius, 0.0f), D3DXVECTOR3(0.0f, 0.0f, -1.0f), D3DXVECTOR2(0.0f, 1.0f * TEX_SCALE));
	pVertices[3] = Dot3Vertex(D3DXVECTOR3(vCenter.x + fRadius, vCenter.y - fRadius, 0.0f), D3DXVECTOR3(0.0f, 0.0f, -1.0f), D3DXVECTOR2(1.0f * TEX_SCALE, 1.0f * TEX_SCALE));

	pIndices[0] = 0;
	pIndices[1] = 1;
	pIndices[2] = 2;
	pIndices[3] = 2;
	pIndices[4] = 1;
	pIndices[5] = 3;

	m_pVertexBuffer->Unlock();
	m_pIndexBuffer->Unlock();

    return S_OK;
}

HRESULT NVEffect_DynamicReflection::GenerateSplinePatch()
{
	HRESULT hr;
	SAFE_RELEASE(m_pPatchBuffer);

    // first alloc the buffers
    int const   kNumCtrlPts = 4 * 4;

    hr = m_pD3DDev->CreateVertexBuffer(kNumCtrlPts * sizeof(Dot3Vertex), 
                                  D3DUSAGE_RTPATCHES|D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 
                                  0, D3DPOOL_DEFAULT, &m_pPatchBuffer);

    // then do not do anything with it: AnimateSplinePatch will generate *all* data!
    return hr;
}

HRESULT NVEffect_DynamicReflection::AnimateSplinePatch(EBTimer* pTimer)
{
 	Dot3Vertex*         pVertices; 
	static const float fZOffset = 0.0f;
	m_pPatchBuffer->Lock(0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD);

    // re-initialize positions
    int i, j;
	for(i = 0; i < 4; i++)
	{
		for(j = 0; j < 4; j++)
		{
            pVertices[4*i + j].Position = D3DXVECTOR3(j - 1.5f, 1.5f - i, fZOffset);
			pVertices[4*i + j].Position *= 0.25f;
		}
	}


	float anim_disp_scale = 0.65f;

	if (!m_bPause)
	{
		// modify central control points
		m_ctrl1 = (fZOffset + anim_disp_scale * sinf(1.0f + 0.5f  * pTimer->GetDuration())); 
		m_ctrl2 = (fZOffset + anim_disp_scale * sinf(2.0f + 0.35f * pTimer->GetDuration())); 
		m_ctrl3 = (fZOffset + anim_disp_scale * sinf(3.0f + 0.6f  * pTimer->GetDuration())); 
		m_ctrl4 = (fZOffset + anim_disp_scale * sinf(4.0f + 0.1f  * pTimer->GetDuration())); 
	}
	
    pVertices[4*1 + 1].Position.z = m_ctrl1;
    pVertices[4*2 + 1].Position.z = m_ctrl2;
    pVertices[4*1 + 2].Position.z = m_ctrl3;
    pVertices[4*2 + 2].Position.z = m_ctrl4;

	// compute d position / dv 
    D3DXVECTOR3     mesh[16];

	for(i=0; i < 3; i++)
		for(j=0; j < 4; j++)
			mesh[4*i + j] = pVertices[4*(i+1) + j].Position - pVertices[4*i + j].Position;

	// If the positions are reversed, the basis will be inverted and "high"
	//  bumps will appear as depressions instead
	// ie, if you were to do:
	//			mesh[4*i + j] = pVertices[4*i + j].Position - pVertices[4*(i+1) + j].Position;
	// the bumps would be reversed in that axis.

    ElevateToCubicMesh(mesh, 4, 3);

	for(i=0; i < 4; i++)
		for(j=0; j < 4; j++)
			pVertices[4*i + j].T = mesh[4*i + j];

	///////////////////////////////////////////////
    // d position / du 
    for(i=0; i < 4; i++)
        for(j=0; j < 3; j++)
	        mesh[4*i + j] = pVertices[4*i + j+1].Position - pVertices[4*i + j].Position ; 

	// If the positions are reversed, the basis will be inverted and "high"
	//  bumps will appear as depressions instead
	// ie, if you were to do:
	//	        mesh[4*i + j] = pVertices[4*i + j].Position - pVertices[4*i + j+1].Position; 
	// the bumps would be reversed in that axis.
		
    ElevateToCubicMesh(mesh, 3, 4);

    for(i=0; i < 4; i++)
        for(j=0; j < 4; j++)
	        pVertices[4*i + j].S = mesh[4*i + j];


    return S_OK;
}

void NVEffect_DynamicReflection::ElevateToCubicMesh(D3DXVECTOR3    *pControlMesh, 
                                             unsigned int    uOrder, 
                                             unsigned int    vOrder) const
{
    // Can transform constant, linear, quadratic, or cubic in either u/v
    // to fully cubic in both u and v.
    assert(uOrder >= 1 && uOrder <= 4);
    assert(vOrder >= 1 && vOrder <= 4);

    // mesh is assumed to be a 4x4 grid of D3DXVECTOR3, the upper left
    // uOrder by vOrder corner is assumed to be populated with values and 
    // the elevation result is returned in the full 4x4 mesh.
    D3DXMATRIX const  allElevators[3] = {D3DXMATRIX(1.0f, 1.0f,    1.0f,    1.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f), 
                                         D3DXMATRIX(1.0f, 0.75f,   0.25f,   0.0f, 
                                                    0.0f, 0.25f,   0.75f,   1.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f), 
                                         D3DXMATRIX(1.0f, 1.f/3.f, 0.0f,    0.0f, 
                                                    0.0f, 2.f/3.f, 2.f/3.f, 0.0f, 
                                                    0.0f, 0.0f,    1.f/3.f, 1.0f, 
                                                    0.0f, 0.0f,    0.0f,    0.0f)  };

    D3DXMATRIX  const   *pElevator;
    float       const   *pConstVec3Base;
    float               *pVec3Base;

    int     const        kFloatsInVec = 3;

⌨️ 快捷键说明

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