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

📄 shader_dot3_directional.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 "nvdevice.h"
#include "nvmesh.h"

#include "shader_Dot3_Directional.h"
#include "shader_Dot3_Point.h"
#include "dot3.h"
#include "nvtexture.h"

using namespace nv_objects;
using namespace std;

DECLARE_EFFECT_MAIN()

extern "C"
{

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

__declspec(dllexport) EBEffect* CreateEffect(unsigned int EffectNum)
{
	switch(EffectNum)
	{
		case 0:
			return new CShaderDot3Directional();
		case 1:
			return new CShaderDot3Point();
		default:
			return NULL;
	}
}

}

void CShaderDot3Directional::UpdateProperties()
{
	EBEffect::UpdateProperties();
	EBEnumProperty* pEnumProp = new EBEnumProperty("Display Options", OBJECT_MEMBER(m_eDisplayOption), EBTYPE_DWORD_PROP);
	
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Show Bump Map", (DWORD)DISPLAY_BUMPMAP, EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Show Texture Space Light Vector", (DWORD)DISPLAY_LIGHTVECTOR, EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Show Base Texture", (DWORD)DISPLAY_BASETEXTURE, EBTYPE_DWORD_PROP));
	pEnumProp->AddEnumerant(new EBEnumValue(pEnumProp, "Show Bumped Light + Base Texture", (DWORD)DISPLAY_RESULT, EBTYPE_DWORD_PROP));
	AddProperty(pEnumProp);

	// Vertex shaders
	m_pVertexShaderEnum->AddEnumerant(new EBEnumValue(m_pVertexShaderEnum, "Texture Space Calculation", GetFilePath("dot3_directional.nvv"), EBTYPE_STRING_PROP));

	AddProperty(new EBProperty("Wireframe", OBJECT_MEMBER(m_bWireframe), EBTYPE_BOOL_PROP));
	AddProperty(new EBProperty("Pause lights", OBJECT_MEMBER(m_bPause), EBTYPE_BOOL_PROP));
}

CShaderDot3Directional::CShaderDot3Directional()
:	m_eDisplayOption(DISPLAY_RESULT),
	m_pSphereVertexBuffer(NULL),
	m_pSphereIndexBuffer(NULL),
	m_fAngle(0.0f),
	m_pLightMesh(NULL),
	m_pNVDevice(NULL),
	m_pBumpMap(NULL),
	m_pBaseTexture(NULL),
	m_dwLightShader(0),
	m_dwDot3Shader(0),
	m_pUI(NULL),
	m_bWireframe(false),
	m_bPause(false)
{
	m_strEffectName = "Dot3 Bump Directional Light";	// A string holding the name of the effect
	m_strEffectLocation = "Vertex Shaders\\Bump Mapping";
	m_strEffectPixelShader = "";
	m_strEffectVertexShader = GetFilePath("dot3_directional.nvv");
}

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

HRESULT CShaderDot3Directional::GenerateSphere(D3DXVECTOR3& vCenter, FLOAT fRadius, WORD wNumRings, WORD wNumSections, FLOAT sx, FLOAT sy, FLOAT sz)
{
    FLOAT x, y, z, v, rsintheta; // Temporary variables
    WORD  i, j, n, m;            // counters
    D3DXVECTOR3 vPoint;
	HRESULT hr;

	SAFE_RELEASE(m_pSphereVertexBuffer);
	SAFE_RELEASE(m_pSphereIndexBuffer);

    //Generate space for the required triangles and vertices.
    WORD       wNumTriangles = (wNumRings + 1) * wNumSections * 2;
    DWORD      dwNumIndices   = wNumTriangles*3;
    DWORD      dwNumVertices  = (wNumRings + 1) * wNumSections + 2;

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

	hr = m_pD3DDev->CreateVertexBuffer(dwNumVertices * sizeof(Dot3Vertex), 0, 0, D3DPOOL_MANAGED, &m_pSphereVertexBuffer);
	if (FAILED(hr))
	{
		return hr;
	}
	hr = m_pD3DDev->CreateIndexBuffer(3 * wNumTriangles * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pSphereIndexBuffer);
	if (FAILED(hr))
	{
		return hr;
	}

	Dot3Vertex* pVertices;
	WORD* pIndices;
	
	m_pSphereVertexBuffer->Lock(0, 0, (BYTE**)&pVertices, 0);
	m_pSphereIndexBuffer->Lock(0, 0, (BYTE**)&pIndices, 0);

    // Generate vertices at the top and bottom points.
    D3DXVECTOR3 vTopPoint  = vCenter + D3DXVECTOR3( 0.0f, +sy*fRadius, 0.0f);
    D3DXVECTOR3 vBotPoint  = vCenter + D3DXVECTOR3( 0.0f, -sy*fRadius, 0.0f);
    D3DXVECTOR3 vNormal = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

    pVertices[0]               = Dot3Vertex( D3DXVECTOR3(vTopPoint.x, vTopPoint.y, vTopPoint.z),  D3DXVECTOR3(vNormal.x, vNormal.y, vNormal.z), D3DXVECTOR2(0.0f, 0.0f) );
    pVertices[dwNumVertices-1] = Dot3Vertex( D3DXVECTOR3(vBotPoint.x, vBotPoint.y, vBotPoint.z), D3DXVECTOR3(-vNormal.x, -vNormal.y, -vNormal.z), D3DXVECTOR2(0.0f, 0.0f) );

    // Generate vertex points for rings
    FLOAT dtheta = (float)(D3DX_PI / (wNumRings + 2));     //Angle between each ring
    FLOAT dphi   = (float)(2*D3DX_PI / (wNumSections)); //Angle between each section
    FLOAT theta  = dtheta;
    n = 1; //vertex being generated, begins at 1 to skip top point

    for( i = 0; i < (wNumRings+1); i++ )
    {
        y = fRadius * (float)cos(theta); // y is the same for each ring
        v = theta / D3DX_PI;     // v is the same for each ring
        rsintheta = fRadius * (float)sin(theta);
        FLOAT phi = 0.0f;

        for( j = 0; j < wNumSections; j++ )
        {
            x = rsintheta * (float)sin(phi);
            z = rsintheta * (float)cos(phi);
        
            FLOAT u = 1.0f - (FLOAT)(phi / (2 * D3DX_PI) );
            assert(u <= 1.001f);
				assert(u >= 0.0f);
            vPoint        = vCenter + D3DXVECTOR3( sx*x, sy*y, sz*z );
            vNormal       = D3DXVECTOR3( x/fRadius, y/fRadius, z/fRadius );
			D3DXVec3Normalize(&vNormal, &vNormal);
			pVertices[n] = Dot3Vertex( D3DXVECTOR3(vPoint.x, vPoint.y, vPoint.z), D3DXVECTOR3(vNormal.x, vNormal.y, vNormal.z), D3DXVECTOR2(u, v) );

            phi += dphi;
            ++n;
        }
        theta += dtheta;
    }

    // Generate triangles for top and bottom caps.
    for( i = 0; i < wNumSections; i++ )
    {
        pIndices[3*i+0] = 0;
        pIndices[3*i+1] = i + 1;
        pIndices[3*i+2] = 1 + ((i + 1) % wNumSections);

        pIndices[3*(wNumTriangles - wNumSections + i)+0] = (WORD)( dwNumVertices - 1 );
        pIndices[3*(wNumTriangles - wNumSections + i)+1] = (WORD)( dwNumVertices - 2 - i );
        pIndices[3*(wNumTriangles - wNumSections + i)+2] = (WORD)( dwNumVertices - 2 - 
                ((1 + i) % wNumSections) );
    }

    // Generate triangles for the rings
    m = 1;            // first vertex in current ring,begins at 1 to skip top point
    n = wNumSections; // triangle being generated, skip the top cap 
        
    for( i = 0; i < wNumRings; i++ )
    {
        for( j = 0; j < (wNumSections); j++ )
        {
            pIndices[3*n+0] = m + j;
            pIndices[3*n+1] = m + wNumSections + j;
            pIndices[3*n+2] = m + wNumSections + ((j + 1) % wNumSections);
            
            pIndices[3*(n+1)+0] = pIndices[3*n+0];
            pIndices[3*(n+1)+1] = pIndices[3*n+2];
            pIndices[3*(n+1)+2] = m + ((j + 1) % wNumSections);
            
            n += 2;
        }
      
        m += wNumSections;
    }

	m_pSphereVertexBuffer->Unlock();
	m_pSphereIndexBuffer->Unlock();

    return S_OK;
}


HRESULT CShaderDot3Directional::Initialize(IDirect3DDevice8* pDev)
{
	HRESULT hr;
	vector<DWORD> Declaration;

	m_pD3DDev = pDev;
	pDev->AddRef();

	//initialize mouse UI
	RECT rect;
	rect.left = rect.top = 0;
	D3DVIEWPORT8 viewport;
	m_pD3DDev->GetViewport(&viewport);
	rect.bottom = viewport.Height;
	rect.right  = viewport.Width;
	m_pUI = new MouseUI((const RECT)rect);

	m_pNVDevice = new NVDot3DirectionalDevice(pDev, this);

	m_pLightMesh = new NVMesh();
	hr = m_pLightMesh->Create(m_pNVDevice, GetFilePath("arrow.x"));
	if (FAILED(hr))
	{
		m_strLastError = "Could not load arrow.x";
		return hr;
	}
	m_pLightMesh->SetFVF(m_pNVDevice, D3DFVF_NORMAL | D3DFVF_XYZ | D3DFVF_TEX1);

	hr = GenerateSphere(D3DXVECTOR3(0.0f, 0.0f, 0.0f), 1.0f, 10, 20, 1.0f, 1.0f, 1.0f);
	if (FAILED(hr))
	{
		m_strLastError = "Could not generate sphere";
		return hr;
	}

	// Create the shaders
	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_FLOAT2)); // Texture
	Declaration.push_back(D3DVSD_END());
	hr = LoadAndCreateShader(GetFilePath("dot3_lightobject.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwLightShader);
	if (FAILED(hr))
		return hr;

	m_pLightMesh->SetVertexShader(m_dwLightShader);

	Declaration.clear();
	Declaration.push_back(D3DVSD_STREAM(0));
	Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3)); // Position
	Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT3)); // Normal
	Declaration.push_back(D3DVSD_REG(2, D3DVSDT_FLOAT3)); // Diffuse
	Declaration.push_back(D3DVSD_REG(3, D3DVSDT_FLOAT2)); // Texture
	Declaration.push_back(D3DVSD_REG(5, D3DVSDT_FLOAT3)); // S
	Declaration.push_back(D3DVSD_REG(6, D3DVSDT_FLOAT3)); // T
	Declaration.push_back(D3DVSD_REG(4, D3DVSDT_FLOAT3)); // SxT
	Declaration.push_back(D3DVSD_END());
	hr = LoadAndCreateShader(GetFilePath("dot3_directional.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwDot3Shader);
	if (FAILED(hr))
		return hr;

	LPDIRECT3DTEXTURE8 pHeightMap;
	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath("bump_map_nvidia.dds").c_str(),
		D3DX_DEFAULT,
		D3DX_DEFAULT,
		0,
		0,
		D3DFMT_A8R8G8B8,
		D3DPOOL_MANAGED,
		D3DX_FILTER_LINEAR,
		D3DX_FILTER_LINEAR,
		0,
		NULL,
		NULL,
		&pHeightMap);
	if (FAILED(hr))
	{
		m_strLastError = "Could not create brickb.dds";
		return hr;
	}
	m_pBumpMap = NVTexture2::CreateNormalMap(m_pD3DDev, pHeightMap, D3DFMT_A8R8G8B8);
	SAFE_RELEASE(pHeightMap);

	hr = D3DXCreateTextureFromFileEx(m_pD3DDev, 
		GetFilePath("gloss_map_nvidia.dds").c_str(),
		D3DX_DEFAULT,
		D3DX_DEFAULT,
		0,
		0,
		D3DFMT_UNKNOWN,
		D3DPOOL_MANAGED,
		D3DX_FILTER_LINEAR,
		D3DX_FILTER_LINEAR,
		0,
		NULL,
		NULL,
		&m_pBaseTexture);
	if (FAILED(hr))
	{
		m_strLastError = "Could not create gloss_map_nvidia.dds";
		return hr;
	}


	// Setup constants
	m_pD3DDev->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
	m_pD3DDev->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1);

	// Camera stuff
	D3DXMATRIX matProj;
	D3DXMATRIX matView;

	D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -3.5f );
	D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

	// View
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);

	// Projection
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 0.1f, 50.0f);

	m_pNVDevice->SetViewTransform(&matView);
	m_pNVDevice->SetProjectionTransform(&matProj);

	m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, FALSE);


	if (m_pLightMesh)
		m_pLightMesh->RestoreDeviceObjects(m_pNVDevice);

	CreateBasisVectors(m_pSphereVertexBuffer, m_pSphereIndexBuffer);

	// Point at the vertex data
	hr = m_pD3DDev->SetStreamSource(0, m_pSphereVertexBuffer, sizeof(Dot3Vertex));
	if (FAILED(hr))
	{
		m_strLastError = "Could not set VB source";
		return hr;
	}
	
	// Point at the index data
	hr = m_pD3DDev->SetIndices(m_pSphereIndexBuffer, 0);

⌨️ 快捷键说明

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