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

📄 shader_brdf.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************NVMH2****
Path:  E:\devrel\NV_SDK_4\DX8\NVEffectsBrowser\Effects\BRDF
File:  shader_BRDF.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 "nvinc.h"
#include "shader_BRDF.h"

// constant memory definitions for the vertex/pixel shader
#include "Constants.h"

#define MINNAERT_CONSTANT .22456
class TLVertex
{
public:
	D3DXVECTOR4 Position;
	DWORD Diffuse;
	DWORD Specular;
	D3DXVECTOR2 Texture;
};

#define D3DFVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)

#define DRESS_INDEX 1
//#define TESTQUAD 1

using namespace std;

DECLARE_EFFECT_MAIN()

extern "C"
{
	
	__declspec(dllexport) unsigned int GetNumEffects() { return 1; }
	
	__declspec(dllexport) EBEffect* CreateEffect(unsigned int EffectNum)
	{	
		switch(EffectNum)
		{
		case 0:
			return new CShaderBRDF();
			break;
		default:
			return NULL;
		}
	}
	
}

HRESULT CreateNormalizationCubeMap(LPDIRECT3DDEVICE8 pD3DDev, DWORD dwWidth, WORD dwMipmaps, LPDIRECT3DCUBETEXTURE8* pTextureReturn)
{
	HRESULT hr;
	LPDIRECT3DCUBETEXTURE8 pCubeTexture;

	assert(pTextureReturn);

	*pTextureReturn = NULL;

	hr = D3DXCreateCubeTexture(pD3DDev, dwWidth, dwMipmaps, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &pCubeTexture);
	if(FAILED(hr))
	{
		return hr;
	}

	for (int i = 0; i < 6; i++)
	{
		D3DLOCKED_RECT Locked;
		D3DXVECTOR3 Normal;
		float w,h;
		D3DSURFACE_DESC ddsdDesc;
		
		pCubeTexture->GetLevelDesc(0, &ddsdDesc);

		pCubeTexture->LockRect((D3DCUBEMAP_FACES)i, 0, &Locked, NULL, 0);

		for (int y = 0; y < ddsdDesc.Height; y++)
		{
			h = (float)y / ((float)(ddsdDesc.Height - 1));
			h *= 2.0f;
			h -= 1.0f;

			for (int x = 0; x < ddsdDesc.Width; x++)
			{
				w = (float)x / ((float)(ddsdDesc.Width - 1));
				w *= 2.0f;
				w -= 1.0f;

				DWORD* pBits = (DWORD*)((BYTE*)Locked.pBits + (y * Locked.Pitch));
				pBits += x;

				switch((D3DCUBEMAP_FACES)i)
				{
					case D3DCUBEMAP_FACE_POSITIVE_X:
						Normal = D3DXVECTOR3(1.0f, -h, -w);
						break;
					case D3DCUBEMAP_FACE_NEGATIVE_X:
						Normal = D3DXVECTOR3(-1.0f, -h, w);
						break;
					case D3DCUBEMAP_FACE_POSITIVE_Y:
						Normal = D3DXVECTOR3(w, 1.0f, h);
						break;
					case D3DCUBEMAP_FACE_NEGATIVE_Y:
						Normal = D3DXVECTOR3(w, -1.0f, -h);
						break;
					case D3DCUBEMAP_FACE_POSITIVE_Z:
						Normal = D3DXVECTOR3(w, -h, 1.0f);
						break;
					case D3DCUBEMAP_FACE_NEGATIVE_Z:
						Normal = D3DXVECTOR3(-w, -h, -1.0f);
						break;
					default:
						assert(0);
						break;
				}

				D3DXVec3Normalize(&Normal, &Normal);

				// Scale to be a color from 0 to 255 (127 is 0)
				Normal += D3DXVECTOR3(1.0f, 1.0f, 1.0f);
				Normal *= 127.0f;

				// Store the color
				*pBits = (DWORD)(((DWORD)Normal.x << 16) | ((DWORD)Normal.y << 8) | ((DWORD)Normal.z << 0));

			}
		}
		pCubeTexture->UnlockRect((D3DCUBEMAP_FACES)i, 0);
	}

	if ((dwMipmaps == 0) || (dwMipmaps > 1))
		D3DXFilterCubeTexture(pCubeTexture, NULL, 0, D3DX_FILTER_LINEAR);

	*pTextureReturn = pCubeTexture;

	return S_OK;
}

HRESULT CreateMinnaertMap(LPDIRECT3DDEVICE8 pD3DDev, DWORD dwWidth, DWORD dwHeight, WORD dwMipmaps, 
						  LPDIRECT3DTEXTURE8* pTextureReturn, double MinnaertPower)
{
	HRESULT hr;
	LPDIRECT3DTEXTURE8 pTexture;
	D3DLOCKED_RECT Locked;
	D3DSURFACE_DESC ddsdDesc;
	int x,y;

	assert(pTextureReturn);

	*pTextureReturn = NULL;

	hr = D3DXCreateTexture(pD3DDev, dwWidth, dwHeight, dwMipmaps, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &pTexture);
	if(FAILED(hr))
	{
		return hr;
	}
	
	pTexture->GetLevelDesc(0, &ddsdDesc);

	pTexture->LockRect(0, &Locked, NULL, 0);

	for (y = 0; y < dwHeight; y++)
	{
		for (x = 0; x < dwWidth; x++)
		{
			DWORD* pBits = (DWORD*)((BYTE*)Locked.pBits + (y * Locked.Pitch));
			pBits += x;

			double lPower;
			double ePower;
			double lePower;
			BYTE power;
			double w, h;

			w = ((double)(x+1)/(double)dwWidth);
			h = ((double)(dwHeight-y)/(double)dwHeight);

			lPower = pow(w, MinnaertPower);
			ePower = pow(h, 1-MinnaertPower);

			lePower = lPower * ePower;
			lePower = max(min(lePower, 1.0), 0.35);

			power = (BYTE)(lePower * 255.0f);

			*pBits = (DWORD)(((DWORD)power << 16) | ((DWORD)power << 8) | ((DWORD)power << 0));

		}

	}

	pTexture->UnlockRect(0);

	if ((dwMipmaps == 0) || (dwMipmaps > 1))
		D3DXFilterTexture(pTexture, NULL, 0, D3DX_FILTER_LINEAR);

	*pTextureReturn = pTexture;

	return S_OK;
}

// ------------------------------------------------------------------------------
// CShaderBRDF Constructor
//
// Description: Nothing to it -- just straight-forward construction
// ------------------------------------------------------------------------------ 
CShaderBRDF::CShaderBRDF()
:	m_pWomanTexture(NULL),
	m_bWireframe(false),
	m_mUI(NULL),
	m_bUseTrilinear(true),
	m_eDisplayOption(BRDFDISPLAY_MINNAERT),
	m_MinnaertPower(MINNAERT_CONSTANT),
	m_pMinnaertTexture(NULL),
	m_pVelvetBumpMapTexture(NULL),
	m_pNormalizingTexture(NULL),
	m_bAutoRotate(false),
	m_curYaw(0.0f),
	m_curPitch(0.0f),
	m_pTestQuadVB(NULL),
	m_pTexture2DVB(NULL)

{
	DWORD i;

	m_strEffectLocation = "Pixel Shaders\\Minnaert Reflection Lighting";
	m_strEffectName = "BRDF Shading";
	m_strEffectVertexShader = GetFilePath("BRDF.nvv");
	m_strEffectPixelShader = "";
	
#ifdef TESTQUAD
	m_LightDir.x = 0.0f;
	m_LightDir.y = 0.0f;
	m_LightDir.z = 1.0f;
#else
	m_LightDir.x = -1.0f;
	m_LightDir.y = -1.0f;
	m_LightDir.z = 1.0f;
//	m_LightDir.x = 0.5f;
//	m_LightDir.y = -0.5f;
//	m_LightDir.z = 0.5f;
#endif
	D3DXVec3Normalize(&m_LightDir, &m_LightDir);

	m_VRotation.x = 0.5f;
	m_VRotation.y = -0.5f;
	m_VRotation.z = 0.5f,
	D3DXVec3Normalize(&m_VRotation, &m_VRotation);

	for (i=0; i< NUM_OBJECTS; i++)
	{
		m_pVertexBuffer[i] = NULL;
		m_pIndexBuffer[i] = NULL;
		m_pAttributes[i] = NULL;
		m_pMaterials[i] = NULL;
		m_dwCurrentVShader[i] = NULL;
		m_dwCurrentPShader[i] = NULL;
		m_SaveMouse_X[i] = 0;
		m_SaveMouse_Y[i] = 0;
		m_SaveMouse_bDown[i] = FALSE;
	}

	D3DXMatrixIdentity(&m_MatWorld);
	D3DXMatrixIdentity(&m_MatView);
	D3DXMatrixIdentity(&m_MatProj);
}

// ------------------------------------------------------------------------------
// CShaderBRDF Destructor
//
// Description: Nothing to it -- just straight-forward destruction
// ------------------------------------------------------------------------------ 
CShaderBRDF::~CShaderBRDF()
{
	Free(); 
}

// ------------------------------------------------------------------------------
// CShaderBRDF::UpdateProperties
//
// Description: This adds options to the menu (click on "File" or right-click
// on the display.
// ------------------------------------------------------------------------------ 
void CShaderBRDF::UpdateProperties()
{
	EBEffect::UpdateProperties();
	EBEnumProperty* pEnumProp = new EBEnumProperty("Display Options", OBJECT_MEMBER(m_eDisplayOption), EBTYPE_DWORD_PROP);
	
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Minnaert Reflections", (DWORD)BRDFDISPLAY_MINNAERT, EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Shading only", (DWORD)BRDFDISPLAY_SHADING, EBTYPE_DWORD_PROP));
	AddProperty(pEnumProp);

	AddProperty(new EBProperty("Wireframe", OBJECT_MEMBER(m_bWireframe), EBTYPE_BOOL_PROP));

	pEnumProp = new EBEnumProperty("Move/Rotate Options", OBJECT_MEMBER(m_Rotating), EBTYPE_DWORD_PROP);
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Woman", (DWORD)WOMAN_OBJECT, EBTYPE_ENUM_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Light", (DWORD)LIGHT_OBJECT, EBTYPE_ENUM_PROP));
	AddProperty(pEnumProp);

	AddProperty(new EBProperty("Auto Rotate", OBJECT_MEMBER(m_bAutoRotate), EBTYPE_BOOL_PROP));

	// Vertex shaders
	m_pVertexShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "Minnaert Lighting", GetFilePath("BRDF.nvv"), EBTYPE_STRING_PROP));
	m_pPixelShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "Minnaert Lighting", GetFilePath("BRDF.nvp"), EBTYPE_STRING_PROP));
	m_pVertexShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "Directional Lighting", GetFilePath("dirLight.nvv"), EBTYPE_STRING_PROP));


//ddProperty(new EBProperty("Wireframe", OBJECT_MEMBER(m_bWireframe), EBTYPE_BOOL_PROP));
	


}


// ------------------------------------------------------------------------------
// CShaderBRDF::ConfirmDevice
//
// Description: Performs caps-bit checking to make sure the selected device 
//		supports this demo.  In this particular case we check for nothing!
// ------------------------------------------------------------------------------ 
HRESULT CShaderBRDF::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
	if (!(pCaps->TextureCaps & D3DPTEXTURECAPS_MIPMAP))
	{
		m_strLastError = "Device does not support mipmaps!";
		return E_FAIL;
	}

	if (!(pCaps->TextureCaps & D3DPTFILTERCAPS_MIPFLINEAR))
	{
		m_bUseTrilinear = false;
	}

	if(pCaps->MaxSimultaneousTextures < 2)
	{
		m_strLastError = "Device does not support two simultaneous textuers!";
		return E_FAIL;
	}

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

	return S_OK;
}

// ------------------------------------------------------------------------------
// CShaderBRDF::Initialize
//
// Description: Initialize render-states, vertex shader and vertex buffers
// ------------------------------------------------------------------------------ 
HRESULT CShaderBRDF::Initialize(IDirect3DDevice8* pDev)
{
	HRESULT hr;
	DWORD i;
	
	// get the D3D device 
	m_pD3DDev = pDev;
	pDev->AddRef();
	
	//initialize mouse UI
	RECT rect;
	rect.left = rect.top = 0;
	m_pD3DDev->GetViewport(&m_D3DViewPort);
	rect.bottom = m_D3DViewPort.Height;
	rect.right  = m_D3DViewPort.Width;
	m_mUI = new MouseUI((const RECT)rect);
	
	vector<DWORD> Declaration;
	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());
	
	// Load the vertex shader object file for regular transformed and lit 
	// and create it.
	m_dwCurrentVShader[WOMAN_OBJECT] = NULL;
	hr = LoadAndCreateShader(GetFilePath("BRDF.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, 
					&m_dwCurrentVShader[WOMAN_OBJECT]);
	if (FAILED(hr))
		return hr;

	m_dwCurrentPShader[WOMAN_OBJECT] = NULL;
	hr = LoadAndCreateShader(GetFilePath("BRDF.pso"), NULL, 0, SHADERTYPE_PIXEL, 
				&m_dwCurrentPShader[WOMAN_OBJECT]);
	if (FAILED(hr))
		return hr;

	m_dwCurrentVShader[LIGHT_OBJECT] = NULL;
	hr = LoadAndCreateShader(GetFilePath("dirLight.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, 
					&m_dwCurrentVShader[LIGHT_OBJECT]);
	

	// no pixel shader for this one.
	m_dwCurrentPShader[LIGHT_OBJECT] = NULL;
//	hr = LoadAndCreateShader(GetFilePath("dirLight.pso"), NULL, 0, SHADERTYPE_PIXEL, 
//				&m_dwCurrentPShader[LIGHT_OBJECT]);
	if (FAILED(hr))
		return hr;


	for (i=0; i< NUM_OBJECTS; i++)
	{
		hr = LoadXFile(GetFilePath(LoadObjects[i]).c_str(), TSVERTEX_FVF, i);
		if(FAILED(hr))
			return hr;
	}

#ifdef TESTQUAD
	m_Rotating = LIGHT_OBJECT;
#else
	m_Rotating = WOMAN_OBJECT;
#endif

	m_LastRotating = m_Rotating;

    m_pD3DDev->SetRenderState( D3DRS_CULLMODE,       D3DCULL_CCW ); //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_LINEAR );

⌨️ 快捷键说明

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