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

📄 techniqueapplication.cpp

📁 real-time(实时渲染技术DirectX)30(2)-36
💻 CPP
字号:
/***************************************************************
* 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_SPRITEVERTEX (D3DFVF_XYZ | D3DFVF_TEX3)

struct SPRITE_VERTEX
{
	float x, y, z;
	float u1, v1;
	float u2, v2;
	float u3, v3;
};

CTechniqueApplication::CTechniqueApplication()
{
	m_pSpriteVertexBuffer     = NULL;
	m_pColorCurve             = NULL;
	m_ImageShader             = 0;
}

CTechniqueApplication::~CTechniqueApplication()
{
}

BOOL CTechniqueApplication::PostInitialize()
{	
	D3DDISPLAYMODE CurrentMode;
	if (SUCCEEDED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
								                &CurrentMode)))
	{
		ZeroMemory(&m_PresentParameters, 
				   sizeof(D3DPRESENT_PARAMETERS));
		m_PresentParameters.Windowed = TRUE;
		m_PresentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
		m_PresentParameters.BackBufferFormat = CurrentMode.Format;
		m_PresentParameters.EnableAutoDepthStencil = TRUE;
		m_PresentParameters.AutoDepthStencilFormat = D3DFMT_D24S8;

		m_CreationParameters.AdapterOrdinal = 
											D3DADAPTER_DEFAULT;
		m_CreationParameters.hFocusWindow   = m_hWnd;


		D3DCAPS8 Caps;
		m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps);
		if (Caps.VertexShaderVersion == D3DVS_VERSION(1,1) &&
			Caps.PixelShaderVersion == D3DPS_VERSION(1,4))
		{
			m_CreationParameters.DeviceType     = D3DDEVTYPE_HAL;
			m_CreationParameters.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING |
			                                     D3DCREATE_MULTITHREADED;
		}
		else
		{
			m_CreationParameters.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING |
			                                     D3DCREATE_MULTITHREADED;
			m_CreationParameters.DeviceType     = D3DDEVTYPE_REF;
		}

		if (FAILED(CreateDevice(&m_CreationParameters, &m_PresentParameters)))
			return FALSE;
	}

	//Set the basics
	SetupDevice();
	
	//Create the image processing shader
	if (FAILED(CreateShader()))
		return FALSE;

	//the texture must be created first to get the proper dimensions
	if (FAILED(CreateSpriteBuffer()))
		return FALSE;

	if (FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, 
		                                 "..\\media\\ColorCurve.bmp", 
										 &m_pColorCurve)))
		return FALSE;

	if (FAILED(m_VideoTexture.CreateFromAVIFile(m_pD3DDevice,
												"..\\media\\bikerace.avi")))
		return FALSE;

	return TRUE;
}

void CTechniqueApplication::Render()
{		
	//Set the projection matrix for percent based sprites
	m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &m_PercentProjection);

	//Set the background texture.
	m_pD3DDevice->SetTexture(0, m_VideoTexture.m_pTexture);
	m_VideoTexture.CheckForLoop();

	//Set the color curve textures for the color curve shader
//	m_pD3DDevice->SetTexture(1, m_pColorCurve);
//	m_pD3DDevice->SetTexture(2, m_pColorCurve);
//	m_pD3DDevice->SetTexture(3, m_pColorCurve);

//  or...

	//Set the other stages for the edge shader
	m_pD3DDevice->SetTexture(1, m_VideoTexture.m_pTexture);
	m_pD3DDevice->SetTexture(2, m_VideoTexture.m_pTexture);


	//These states apply equally well to any filter
	m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDevice->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDevice->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDevice->SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDevice->SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);

	//Set the current shader. Remember, some shaders require more stages (uncomment
	//lines above). Also, see CreateShaders below for a list of shaders.
	m_pD3DDevice->SetPixelShader(m_ImageShader);

	//The delta only affects brightness and contrast. All others ignore this.
	float Delta = -0.2f;
	m_pD3DDevice->SetPixelShaderConstant(0, 
		                                 &D3DXVECTOR4(Delta, Delta, Delta, 1.0f),
										 1);
	//Draw the sprite the "easy" way
	DrawSpriteEx(0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f);

	m_pD3DDevice->SetPixelShader(0);
}

BOOL CTechniqueApplication::PostReset()
{
	SetupDevice();

	return TRUE;
}


BOOL CTechniqueApplication::PreTerminate()
{
	m_pD3DDevice->DeletePixelShader(m_ImageShader);
	
	//Clean up
	if (m_pSpriteVertexBuffer)
	{
		m_pSpriteVertexBuffer->Release();
		m_pSpriteVertexBuffer = NULL;
	}

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

	return TRUE;
}


HRESULT CTechniqueApplication::SetupDevice()
{
	D3DXMatrixOrthoLH(&m_PercentProjection, 
		             (float)1.0f, 
					 (float)1.0f, 
					 0.0f, 100.0f);

	//Initialize everything
	D3DXMatrixIdentity(&m_ViewMatrix);
	D3DXMatrixIdentity(&m_SpriteTranslation);
	D3DXMatrixIdentity(&m_SpriteRotation);
	D3DXMatrixIdentity(&m_SpriteScaling);

	//Set the default view transform
	m_pD3DDevice->SetTransform(D3DTS_VIEW,  &m_ViewMatrix);

	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);	
	m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	return S_OK;
}

HRESULT CTechniqueApplication::CreateSpriteBuffer()
{
	//Also, create the mask vertex buffer
	if (FAILED(m_pD3DDevice->CreateVertexBuffer(4 * sizeof(SPRITE_VERTEX), 
		                                        0, D3DFVF_SPRITEVERTEX,
									            D3DPOOL_MANAGED,
												&m_pSpriteVertexBuffer)))
		return E_FAIL;

	//Create a set of 4 vertices for the texture viewing surface
	SPRITE_VERTEX *pSpriteVertices;

	//Lock the vertex buffer, but allow writing.
	m_pSpriteVertexBuffer->Lock(0, 4 * sizeof(SPRITE_VERTEX), (BYTE **)&pSpriteVertices, 0);

	//NOTE!!!  this assumes that the texture has been properly initialized
	float UMax = (float)m_VideoTexture.m_VideoWidth / (float)m_VideoTexture.m_TextureWidth;
	float VMax = (float)m_VideoTexture.m_VideoHeight / (float)m_VideoTexture.m_TextureHeight;

	//Set up the 4 corners of a small square The second and third sets of texture coordinates
	//are ignored by most of the shaders.
	pSpriteVertices[0].x = -0.5f;   pSpriteVertices[0].y =  -0.5f;
	pSpriteVertices[0].z =  1.0f;
	pSpriteVertices[0].u1 =  0.0f;   pSpriteVertices[0].v1 =   0.0f;
	pSpriteVertices[0].u2 = pSpriteVertices[0].u1 - 1.0f / 1024.0f;
	pSpriteVertices[0].v2 = pSpriteVertices[0].v1;
	pSpriteVertices[0].u3 = pSpriteVertices[0].u1 + 1.0f / 1024.0f;
	pSpriteVertices[0].v3 = pSpriteVertices[0].v1;

	pSpriteVertices[1].x = -0.5f;   pSpriteVertices[1].y =   0.5f;
	pSpriteVertices[1].z =  1.0f;
	pSpriteVertices[1].u1 =  0.0f;   pSpriteVertices[1].v1 =   VMax;
	pSpriteVertices[1].u2 = pSpriteVertices[1].u1 - 1.0f / 1024.0f;
	pSpriteVertices[1].v2 = pSpriteVertices[1].v1;
	pSpriteVertices[1].u3 = pSpriteVertices[1].u1 + 1.0f / 1024.0f;
	pSpriteVertices[1].v3 = pSpriteVertices[1].v1;

	pSpriteVertices[2].x =  0.5f;   pSpriteVertices[2].y =  -0.5f;
	pSpriteVertices[2].z =  1.0f;
	pSpriteVertices[2].u1 =  UMax;   pSpriteVertices[2].v1 =   0.0f;
	pSpriteVertices[2].u2 = pSpriteVertices[2].u1 - 1.0f / 1024.0f;
	pSpriteVertices[2].v2 = pSpriteVertices[2].v1;
	pSpriteVertices[2].u3 = pSpriteVertices[2].u1 + 1.0f / 1024.0f;
	pSpriteVertices[2].v3 = pSpriteVertices[2].v1;

	pSpriteVertices[3].x =  0.5f;   pSpriteVertices[3].y =   0.5f;
	pSpriteVertices[3].z =  1.0f;
	pSpriteVertices[3].u1 =  UMax;   pSpriteVertices[3].v1 =   VMax;
	pSpriteVertices[3].u2 = pSpriteVertices[3].u1 - 1.0f / 1024.0f;
	pSpriteVertices[3].v2 = pSpriteVertices[3].v1;
	pSpriteVertices[3].u3 = pSpriteVertices[3].u1 + 1.0f / 1024.0f;
	pSpriteVertices[3].v3 = pSpriteVertices[3].v1;

	m_pSpriteVertexBuffer->Unlock();

	//Set the defaults
	m_pD3DDevice->SetVertexShader(D3DFVF_SPRITEVERTEX);
	m_pD3DDevice->SetStreamSource(0, m_pSpriteVertexBuffer, sizeof(SPRITE_VERTEX));

	return S_OK;
}

void CTechniqueApplication::DrawSpriteEx(float X, float Y, float Z,
										 float Angle, float XScale, float YScale)
{
	D3DXMatrixTranslation(&m_SpriteTranslation, X, Y, Z);
	D3DXMatrixRotationZ(&m_SpriteRotation, Angle);
	D3DXMatrixScaling(&m_SpriteScaling, XScale, YScale, 1.0f);
	m_pD3DDevice->SetTransform(D3DTS_WORLD, 
		         &(m_SpriteScaling * m_SpriteRotation * m_SpriteTranslation));
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);	
}

HRESULT CTechniqueApplication::CreateShader()
{	
	ID3DXBuffer* pShaderBuffer;
	ID3DXBuffer* pShaderErrors;

	//The available shaders are:
	// AdjustBrightness.psh
	// AdjustContrast.psh
	// BlackAndWhite.psh
	// ChangeLevels.psh
	// ChangeLevelsGrayScale.psh
	// FindEdges.psh
	// Negative.psh
	// Sepia.psh
	// Solarize.psh

	//See the text for the care and feeding of each shader. If you are using ChangeLevels,
	//you should be careful to set more texture stages during render. This applies
	//to FindEdges as well.
	if (FAILED(D3DXAssembleShaderFromFile("..\\media\\Shaders\\FindEdges.psh", 
		                            0, NULL, &pShaderBuffer, &pShaderErrors)))
		return E_FAIL;

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

	pShaderBuffer->Release();

	return S_OK;
}

⌨️ 快捷键说明

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