techniqueapplication.cpp

来自「real-time(实时渲染技术DirectX)25-30(1)」· C++ 代码 · 共 634 行 · 第 1/2 页

CPP
634
字号
	
	//Clean up
	if (m_pPlaneVertexBuffer)
	{
		m_pPlaneVertexBuffer->Release();
		m_pPlaneVertexBuffer = NULL;
	}

	if (m_pTestVertexBuffer)
	{
		m_pTestVertexBuffer->Release();
		m_pTestVertexBuffer = NULL;
	}

	if (m_pMeshVertexBuffer)
	{
		m_pMeshVertexBuffer->Release();
		m_pMeshVertexBuffer = NULL;
	}

	if (m_pMeshIndexBuffer)
	{
		m_pMeshIndexBuffer->Release();
		m_pMeshIndexBuffer  = NULL;
	}

	if (m_pMesh)
	{
		m_pMesh->Release();
		m_pMesh = NULL;
	}

	if (m_pMeshMaterials)
	{
		delete m_pMeshMaterials;
		m_pMeshMaterials = NULL;
	}

	return TRUE;
}


HRESULT CTechniqueApplication::SetupDevice()
{
	//Do all the basic setup
	RECT WindowRect;
	GetClientRect(m_hWnd, &WindowRect);
	D3DXMatrixPerspectiveFovLH(&m_ProjectionMatrix,
					D3DX_PI / 4,
					(float)(WindowRect.right - WindowRect.left) / 
					(float)(WindowRect.bottom - WindowRect.top),
				    1.0f, 1000.0f);

	D3DXMatrixIdentity(&m_WorldMatrix);

	//Create the shadow render target. This will be used to render the light
	//view depth.
	if (FAILED(D3DXCreateTexture(m_pD3DDevice, TEX_DIMENSION, TEX_DIMENSION, 1, 
		                         D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8,
								 D3DPOOL_DEFAULT, &m_pShadowTexture)))
		return E_FAIL;

	//Create the target depth buffer
	if (FAILED(m_pD3DDevice->CreateDepthStencilSurface(TEX_DIMENSION, 
		                                               TEX_DIMENSION,
													   D3DFMT_D24S8,
													   D3DMULTISAMPLE_NONE,
													   &m_pShadowZSurface)))
		return E_FAIL;


    //Keep a handle to the back buffer for easy swapping
	if (FAILED(m_pD3DDevice->GetRenderTarget(&m_pBackBuffer)))
		return E_FAIL;

    //Same for the depth buffer
	if (FAILED(m_pD3DDevice->GetDepthStencilSurface(&m_pZBuffer)))
		return E_FAIL;

	//Get the top level surface of the target texture.
	if (FAILED(m_pShadowTexture->GetSurfaceLevel(0, &m_pShadowTextureSurface)))
		return E_FAIL;


	return S_OK;
}

HRESULT CTechniqueApplication::ExtractBuffers()
{
	//Get the buffers
	m_pMesh->GetVertexBuffer(&m_pMeshVertexBuffer);
	m_pMesh->GetIndexBuffer(&m_pMeshIndexBuffer);

	MESH_VERTEX *pMeshVertices;
	short       *pIndices;
	DWORD       *pAttribs;

	//Lock the vertex buffer, but allow writing.
	m_pMeshVertexBuffer->Lock(0, 
		                      m_pMesh->GetNumVertices() * sizeof(MESH_VERTEX),
		                      (BYTE **)&pMeshVertices, 0);


	//We only need to read the indices
	m_pMeshIndexBuffer->Lock(0, 3 * m_pMesh->GetNumFaces() * sizeof(short),
	                         (BYTE **)&pIndices, D3DLOCK_READONLY);

	//The attribute buffer maps the materials to each face.
	m_pMesh->LockAttributeBuffer(D3DLOCK_READONLY, &pAttribs);

	//Loop through each face and set the vertex color based on the material.
	//This is a pretty simple example, but you could also use this to preload
	//other data, such as converting colors to data that the vertex shader
	//may use in computations.
	for (long Face = 0; Face < m_pMesh->GetNumFaces(); Face++)
	{
		D3DXCOLOR Diffuse = (D3DXCOLOR)m_pMeshMaterials[pAttribs[Face]].Diffuse;

		pMeshVertices[pIndices[Face * 3 + 0]].color = Diffuse;
		pMeshVertices[pIndices[Face * 3 + 1]].color = Diffuse;
		pMeshVertices[pIndices[Face * 3 + 2]].color = Diffuse;
	}

	//Give back all of our buffers.
	m_pMeshVertexBuffer->Unlock();
	m_pMeshIndexBuffer->Unlock();
	m_pMesh->UnlockAttributeBuffer();

	return S_OK;
}

HRESULT CTechniqueApplication::CreateShaders()
{
	//Set up the declaration to match the FVF and to
	//read from stream zero.
	DWORD Declaration[] =
	{
		D3DVSD_STREAM(0),
		D3DVSD_REG(D3DVSDE_POSITION,D3DVSDT_FLOAT3),
		D3DVSD_REG(D3DVSDE_NORMAL,  D3DVSDT_FLOAT3),
		D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
		D3DVSD_END()
	};

	
	ID3DXBuffer* pShaderBuffer;
	ID3DXBuffer* pShaderErrors;

	//Assemble and create the first shader. Under real circumstances, you would 
	//probably want to do more error handling.
	if (FAILED(D3DXAssembleShaderFromFile("..\\media\\Shaders\\CompareDepth.vsh", 
		                            0, NULL, &pShaderBuffer, &pShaderErrors)))
		return E_FAIL;

	if (FAILED(m_pD3DDevice->CreateVertexShader(Declaration, 
		                           (DWORD *)pShaderBuffer->GetBufferPointer(),
								   &m_CompareShader, 0)))
		return E_FAIL;

	//release the working buffers
	pShaderBuffer->Release();

	//Assemble and create the second shader. Under real circumstances, you would 
	//probably want to do more error handling.
	if (FAILED(D3DXAssembleShaderFromFile("..\\media\\Shaders\\EncodeDepth.vsh", 
		                            0, NULL, &pShaderBuffer, &pShaderErrors)))
		return E_FAIL;

	if (FAILED(m_pD3DDevice->CreateVertexShader(Declaration, 
		                           (DWORD *)pShaderBuffer->GetBufferPointer(),
								   &m_DistanceShader, 0)))
		return E_FAIL;

	//release the working buffers
	pShaderBuffer->Release();

	//Assemble and create the pixel shader. Under real circumstances, you would 
	//probably want to do more error handling.
	if (FAILED(D3DXAssembleShaderFromFile("..\\media\\Shaders\\ShadowMap.psh", 
		                            0, NULL, &pShaderBuffer, &pShaderErrors)))
		return E_FAIL;

	if (FAILED(m_pD3DDevice->CreatePixelShader(
		                           (DWORD *)pShaderBuffer->GetBufferPointer(),
								   &m_PixelShader)))
		return E_FAIL;

	//release the working buffers
	pShaderBuffer->Release();

	return S_OK;
}

void CTechniqueApplication::PreRender()
{
	//Clear the device
	m_pD3DDevice->Clear(0, NULL,
						D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
						D3DCOLOR_XRGB(100, 100, 200), 1.0f, 0);

	//Call BeginScene to set up the device
	m_pD3DDevice->BeginScene();
		
	return;
}


HRESULT CTechniqueApplication::CreatePlaneBuffers()
{
	//Create as managed so we don't have to worry about recreating it
	//if the device is lost.
	if (FAILED(m_pD3DDevice->CreateVertexBuffer(4 * sizeof(MESH_VERTEX), 
		                                        0, D3DFVF_MESHVERTEX,
									            D3DPOOL_MANAGED,
												&m_pPlaneVertexBuffer)))
		return E_FAIL;

	//Create a set of 4 vertices for the plane
	MESH_VERTEX *pVertices;

	//Lock the vertex buffer, but allow writing.
	m_pPlaneVertexBuffer->Lock(0, 4 * sizeof(MESH_VERTEX), (BYTE **)&pVertices, 0);

	//Initialize everything to zero. If I don't set a certain attribute,
	//assume it's zero..
	memset(pVertices, 0x00, 4 * sizeof(MESH_VERTEX));

	//WARNING - this is a bit confusing. I'm setting X and Z positions, but
	//I'm setting the y *Normal* value. If you don't read closely, it 
	//might be very confusing.
	float Size = 50.0f;
	pVertices[0].x = -Size; pVertices[0].ny = 1.0f; pVertices[0].z = -Size;
	pVertices[1].x =  Size; pVertices[1].ny = 1.0f; pVertices[1].z = -Size;
	pVertices[2].x = -Size; pVertices[2].ny = 1.0f; pVertices[2].z =  Size;
	pVertices[3].x =  Size; pVertices[3].ny = 1.0f; pVertices[3].z =  Size;

	pVertices[0].color = pVertices[1].color = 
		                 pVertices[2].color = pVertices[3].color = 0xffffffff;

	m_pPlaneVertexBuffer->Unlock();

	//Also, create the mask vertex buffer
	if (FAILED(m_pD3DDevice->CreateVertexBuffer(4 * sizeof(TEST_VERTEX), 
		                                        0, D3DFVF_TESTVERTEX,
									            D3DPOOL_MANAGED,
												&m_pTestVertexBuffer)))
		return E_FAIL;

	//Create a set of 4 vertices for the texture viewing surface
	TEST_VERTEX *pTestVertices;

	//Lock the vertex buffer, but allow writing.
	m_pTestVertexBuffer->Lock(0, 4 * sizeof(TEST_VERTEX), (BYTE **)&pTestVertices, 0);

	//Set up the 4 corners of a small square
	pTestVertices[0].x = 500.0f; pTestVertices[0].y = 0.0f;
	pTestVertices[0].z = 1.0f;   pTestVertices[0].rhw = 1.0f;
	pTestVertices[0].u = 0.0f;   pTestVertices[0].v = 0.0f;

	pTestVertices[1].x = 500.0f; pTestVertices[1].y = 100.0f;
	pTestVertices[1].u = 0.0f;   pTestVertices[1].v = 1.0f;
	pTestVertices[1].z = 1.0f;   pTestVertices[1].rhw = 1.0f;

	pTestVertices[2].x = 600.0f; pTestVertices[2].y = 0.0f;
	pTestVertices[2].u = 1.0f;   pTestVertices[2].v = 0.0f;
	pTestVertices[2].z = 1.0f;   pTestVertices[2].rhw = 1.0f;

	pTestVertices[3].x = 600.0f; pTestVertices[3].y = 100.0f;
	pTestVertices[3].u = 1.0f;   pTestVertices[3].v = 1.0f;
	pTestVertices[3].z = 1.0f;   pTestVertices[3].rhw = 1.0f;

	m_pTestVertexBuffer->Unlock();

	return S_OK;
}

void CTechniqueApplication::RenderPlane()
{
	//Draw the mesh
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	m_pD3DDevice->SetStreamSource(0, m_pPlaneVertexBuffer, sizeof(MESH_VERTEX));
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}

void CTechniqueApplication::CleanUpTarget()
{
	if (m_pShadowTexture)
	{
		m_pShadowTexture->Release();
		m_pShadowTexture = NULL;
	}

	if (m_pShadowTextureSurface)
	{
		m_pShadowTextureSurface->Release();
		m_pShadowTextureSurface = NULL;
	}

	if (m_pShadowZSurface)
	{
		m_pShadowZSurface->Release();
		m_pShadowZSurface = NULL;
	}

	if (m_pBackBuffer)
	{
		m_pBackBuffer->Release();
		m_pBackBuffer = NULL;
	}

	if (m_pZBuffer)
	{
		m_pZBuffer->Release();
		m_pZBuffer = NULL;
	}
}

⌨️ 快捷键说明

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