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

📄 techniqueapplication.cpp

📁 real-time(实时渲染技术DirectX)37-40
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************
* TechniqueApplication.cpp                                     *
*                                                              *
* This file contains the implementation of the                 *
* TechniqueApplication class.    	        				   *
* To compile correctly, this file must be linked with:         *
* kernel32.lib                                                 *
* user32.lib                                                   *
* d3dx8dt.lib                                                  *
* d3d8.lib                                                     *
*                                                              *
***************************************************************/

#include "TechniqueApplication.h"

#define D3DFVF_MESHVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE)
#define D3DFVF_STENCILVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)

struct MESH_VERTEX
{
	float x, y, z;
	float nx, ny, nz;
	DWORD color;
};

struct STENCIL_VERTEX
{
	float x, y, z, rhw;
	float u, v;
};

#define CIRCLE_RES 15
#define NUM_VERTICES 29

CTechniqueApplication::CTechniqueApplication()
{
	m_pStencilVertexBuffer     = NULL;
	m_pMeshVertexBuffer        = NULL;
	m_pMeshIndexBuffer         = NULL;
	m_pMesh                    = NULL;
	m_pMeshMaterials           = NULL;
	m_pCrossHairTexture        = NULL;
	m_NumMaterials             = 0;
	m_BasicShader              = 0;
}

CTechniqueApplication::~CTechniqueApplication()
{
}

BOOL CTechniqueApplication::PostInitialize()
{	
	D3DCAPS8 Caps;
	m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps);
	if (Caps.VertexShaderVersion == D3DVS_VERSION(1,1))
	{
		if (FAILED(EasyCreateWindowed(m_hWnd, D3DDEVTYPE_HAL, 
						  D3DCREATE_HARDWARE_VERTEXPROCESSING)))
			return FALSE;
	}
	else
	{
		if (FAILED(EasyCreateWindowed(m_hWnd, D3DDEVTYPE_HAL, 
						  D3DCREATE_SOFTWARE_VERTEXPROCESSING)))
			return FALSE;
	}

	//Do the basic camera positioning, etc.
	SetupDevice();
	
	//Load the mesh object
	LoadMesh();

	//Create the buffers we're actually going to use
	ExtractBuffers();

	if (FAILED(CreateStencilVertexBuffer()))
		return FALSE;

	//Create the shader
	if (FAILED(CreateShaders()))
		return FALSE;

	if (FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, 
		                                 "..\\media\\CrossHair.dds",
										 &m_pCrossHairTexture)))
		return FALSE;


	return TRUE;
}

void CTechniqueApplication::Render()
{
	//Set the eye position
	D3DXVECTOR4 EyePos(0.0, 60.0f, -60.0f, 0.0f);

	//Set the view matrix based on the position above.
	D3DXMatrixLookAtLH(&m_ViewMatrix, &(D3DXVECTOR3)EyePos,
		               &D3DXVECTOR3(0.0f, 0.0f, 0.0f),
					   &D3DXVECTOR3(0.0f, 1.0f, 0.0f));

	//Set the current light shader
	m_pD3DDevice->SetVertexShader(m_BasicShader);


    //The following matrix operations will transform the mesh
	D3DXMATRIX Rotation;
    D3DXMATRIX Translation;

	//These matrices will rotate and translate the mesh
	D3DXMatrixRotationY(&Rotation, (float)GetTickCount() / 1000.0f);
	D3DXMatrixTranslation(&Translation, 0.0f, 5.0f, 0.0f);
	m_WorldMatrix = Rotation * Translation;

	//Set some lighting constants
	D3DXVECTOR4 Ambient    (0.1,  0.1f, 0.1f, 0.0f);
	m_pD3DDevice->SetVertexShaderConstant(5, &Ambient, 1);

	//The light is moving side to side over the model.
	float Time = (float)GetTickCount() / 1000.0f;
	D3DXVECTOR4 LightPosition(150.0f * sin(Time), 70.0f, 0.0f, 1.0f);

	//Set the light direction based on what was computed for the shadow
	D3DXVECTOR4 LightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - LightPosition;
	D3DXMATRIX InverseWorld;
	D3DXMatrixInverse(&InverseWorld, NULL, &m_WorldMatrix);
	D3DXVec4Transform(&LightDir, &LightDir, &InverseWorld);
	D3DXVec4Normalize(&LightDir, &LightDir);
	m_pD3DDevice->SetVertexShaderConstant(4, &LightDir, 1);


	//Create the concatenated transformation matrix
	D3DXMATRIX ShaderMatrix = m_WorldMatrix * m_ViewMatrix * 
				              m_ProjectionMatrix;

	//Get the transpose
	D3DXMatrixTranspose(&ShaderMatrix, &ShaderMatrix);

	//Pass the transposed matrix to the shader
	m_pD3DDevice->SetVertexShaderConstant(0, &ShaderMatrix, 4);

	m_pD3DDevice->SetStreamSource(0, m_pMeshVertexBuffer, sizeof(MESH_VERTEX));
	m_pD3DDevice->SetIndices(m_pMeshIndexBuffer, 0);


	//The code above has set everything up for the rendering. First, render
	//the usual scene with the usual stuff.
	m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 
    								   m_pMesh->GetNumVertices(), 0,
									   m_pMesh->GetNumFaces());

	//Now, change the viewport and do it again...

	m_pD3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	//First, save the viewport.
	D3DVIEWPORT8 NormalViewport;
	m_pD3DDevice->GetViewport(&NormalViewport);

	//Create a new viewport in the lower right
	D3DVIEWPORT8 ZoomViewport;
	ZoomViewport.X = 400;
	ZoomViewport.Y = 300;
	ZoomViewport.Width  = 200;
	ZoomViewport.Height = 150;
	ZoomViewport.MinZ = 0.0f;
	ZoomViewport.MaxZ = 1.0f;
	m_pD3DDevice->SetViewport(&ZoomViewport);

	//Change the projection matrix and reset the shader matrix accordingly.
	//The new projection matrix has a much smaller field of view than the 
	//original matrix. This creates the zoom effect.
	D3DXMATRIX ZoomProjection;
	D3DXMatrixPerspectiveFovLH(&ZoomProjection,
					D3DX_PI / 32, 1.5f, 1.0f, 1000.0f);

	ShaderMatrix = m_WorldMatrix * m_ViewMatrix * ZoomProjection;
	D3DXMatrixTranspose(&ShaderMatrix, &ShaderMatrix);
	m_pD3DDevice->SetVertexShaderConstant(0, &ShaderMatrix, 4);

	//Draw the stencil circle. Set it up so that everything passes and
	//the new pixels increment the stencil buffer
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
    m_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE,   TRUE);
    m_pD3DDevice->SetRenderState(D3DRS_STENCILFUNC,     D3DCMP_ALWAYS);
    m_pD3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);

	//Set it up so that nothing is drawn to the color buffer
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,   TRUE);
    m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO);
    m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

	//Draw the actual circle
	m_pD3DDevice->SetVertexShader(D3DFVF_STENCILVERTEX);
	m_pD3DDevice->SetStreamSource(0, m_pStencilVertexBuffer, sizeof(STENCIL_VERTEX));
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, CIRCLE_RES - 2);

	//Set most things back to normal
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,   FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);
    m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

	//Only draw if the value is greater than the ref value (zero)
	m_pD3DDevice->SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_LESS);
    m_pD3DDevice->SetRenderState(D3DRS_STENCILREF,   0);

	m_pD3DDevice->SetVertexShader(m_BasicShader);
	m_pD3DDevice->SetStreamSource(0, m_pMeshVertexBuffer, sizeof(MESH_VERTEX));
	m_pD3DDevice->SetIndices(m_pMeshIndexBuffer, 0);
	m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 
    							   m_pMesh->GetNumVertices(), 0,
								   m_pMesh->GetNumFaces());

	//disable stenciling
	m_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE,   FALSE);

	//Draw the crosshairs
	m_pD3DDevice->SetTexture(0, m_pCrossHairTexture);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,   TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
	m_pD3DDevice->SetVertexShader(D3DFVF_STENCILVERTEX);
	m_pD3DDevice->SetStreamSource(0, m_pStencilVertexBuffer, sizeof(STENCIL_VERTEX));
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, CIRCLE_RES, 2);
	m_pD3DDevice->SetTexture(0, NULL);

	//Restore modes
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,   FALSE);

	//Restore the old viewport
	m_pD3DDevice->SetViewport(&NormalViewport);

}

HRESULT CTechniqueApplication::LoadMesh()
{
	LPD3DXBUFFER pD3DXMtrlBuffer;
	LPD3DXMESH   pOriginalMesh;

    //Load and initialize the mesh. This is a repeat of the code
	//from Chapter 10.
	if(FAILED(D3DXLoadMeshFromX("..\\media\\fattorus.x",
								D3DXMESH_MANAGED, 
                                m_pD3DDevice, NULL, &pD3DXMtrlBuffer,
								&m_NumMaterials, &pOriginalMesh)))
        return FALSE;

	D3DXMATERIAL* d3dxMaterials = 
		(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();

    m_pMeshMaterials = new D3DMATERIAL8[m_NumMaterials];

    for(long MatCount = 0; MatCount < m_NumMaterials; MatCount++)
    {
		m_pMeshMaterials[MatCount] = d3dxMaterials[MatCount].MatD3D;
        m_pMeshMaterials[MatCount].Ambient = 
								m_pMeshMaterials[MatCount].Diffuse;
    }

⌨️ 快捷键说明

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