阅读背景:

图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑

来源:互联网 
/********************************
*  Author: rabbit729
*  E-mail: [email protected]
*  Date:   2012-10-08
*  Description: 图像的平滑
********************************/
#include <d3dx9.h>

//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D                 = NULL;  //Direct3D对象
LPDIRECT3DDEVICE9       g_pd3dDevice           = NULL;  //Direct3D设备对象

LPDIRECT3DTEXTURE9      g_pTextureScreen        = NULL; //待处理图片

ID3DXEffect*            g_pEffect               = NULL;  //效果指针
//常量句柄
D3DXHANDLE              hTechScreen             = NULL;  //Effect句柄
D3DXHANDLE              hTexScreen              = NULL;  //纹理句柄
D3DXHANDLE              hViewPortWidthInv       = NULL;  //视口宽倒数句柄
D3DXHANDLE              hViewPortHeightInv      = NULL;  //视口高倒数句柄

LPDIRECT3DVERTEXBUFFER9 g_pScreenSpaceQuad      = NULL;  //背板VB

const int WIDTH  = 465;
const int HEIGHT = 669;

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)

struct Vertex
{
	Vertex(){}
	Vertex(float x, float y, float z, float w)
	{
		_x = x;   _y = y;   _z = z; _w = w;
	}

	float _x, _y, _z, _w;

	static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZW;


//-----------------------------------------------------------------------------
// Desc: 设置世界矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
	//创建并设置世界矩阵
	D3DXMATRIXA16 matWorld, matRotateX, matRotateY;
	D3DXMATRIXA16 matScale;
	D3DXMatrixIdentity(&matScale);
	matScale._11 = matScale._22 = matScale._33 = 0.5f;

	D3DXMatrixIdentity(&matWorld);
	D3DXMatrixIdentity(&matRotateX);
	D3DXMatrixIdentity(&matRotateY);
	D3DXMatrixRotationX( &matRotateX, D3DX_PI / 3.0 );
	D3DXMatrixRotationY( &matRotateY, -D3DX_PI / 8.0 );
	D3DXMatrixMultiply(&matWorld, &matRotateX, &matRotateY);

	D3DXMatrixMultiply(&matWorld, &matScale, &matWorld);
	g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}


//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetViewAndProjMatrix()
{
	//创建并设置观察矩阵
	D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-250.0f );
	D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
	D3DXMATRIXA16 matView;
	D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

	//创建并设置投影矩阵
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
	//创建Direct3D对象, 该对象用于创建Direct3D设备对象
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
		return E_FAIL;

	//设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;

	//创建Direct3D设备对象
	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, &g_pd3dDevice ) ) )
	{
		return E_FAIL;
	}

	//创建Effect
	ID3DXBuffer* errBuffer = NULL;
	if (FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, L"zhognzhilvbo.fx", NULL, NULL, D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, NULL, &g_pEffect, &errBuffer)))
	{
		if (errBuffer)
		{
			char* pErr = (char*)errBuffer->GetBufferPointer();
			errBuffer->Release();
		}
		return E_FAIL;
	}

	//获取常量句柄
	hTechScreen         = g_pEffect->GetTechniqueByName("Screen");
	hTexScreen          = g_pEffect->GetParameterByName(0, "TexScreen");
	hViewPortWidthInv   = g_pEffect->GetParameterByName(0, "viewport_inv_width");
	hViewPortHeightInv  = g_pEffect->GetParameterByName(0, "viewport_inv_height");

	//设置环境光
	g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );

	//设置观察矩阵和投影矩阵
	SetViewAndProjMatrix();

	return S_OK;
}

//-----------------------------------------------------------------------------
// Desc: 创建场景图形
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
	// 创建屏幕板
	g_pd3dDevice->CreateVertexBuffer(
		6 * sizeof(Vertex),
		D3DUSAGE_WRITEONLY,
		Vertex::FVF, 
		D3DPOOL_MANAGED,
		&g_pScreenSpaceQuad,
		0);

	Vertex* vertices;
	g_pScreenSpaceQuad->Lock(0, 0, (void**)&vertices, 0);

	vertices[0] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
	vertices[1] = Vertex(1.0f,  1.0f, 0.5f, 1.0f);
	vertices[2] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
	vertices[3] = Vertex(-1.0f, 1.0f, 0.5f, 1.0f);
	vertices[4] = Vertex( 1.0f, -1.0f, 0.5f, 1.0f);
	vertices[5] = Vertex( -1.0f, -1.0f, 0.5f, 1.0f);

	g_pScreenSpaceQuad->Unlock();

	//加载纹理
	HRESULT hr = D3DXCreateTextureFromFile(g_pd3dDevice, L"meinv.jpg", &g_pTextureScreen);
	if (FAILED(hr))
	{
		return E_FAIL;
	} 

	return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 释放创建的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
	if (g_pScreenSpaceQuad != NULL)
	{
		g_pScreenSpaceQuad->Release();
	}

	if (g_pTextureScreen != NULL)
	{
		g_pTextureScreen->Release();
	}

	if (g_pEffect != NULL)
	{
		g_pEffect->Release();
	}

	//释放Direct3D设备对象
	if( g_pd3dDevice != NULL )
		g_pd3dDevice->Release();

	//释放Direct3D对象
	if( g_pD3D != NULL )
		g_pD3D->Release();
}

VOID RenderScreen()
{
	//将RenderTarget作为纹理
	g_pEffect->SetTexture(hTexScreen, g_pTextureScreen);

	float fWidthInv = 1.0f / WIDTH;
	float fHeightInv = 1.0f / HEIGHT;
	g_pEffect->SetFloat(hViewPortWidthInv, fWidthInv);
	g_pEffect->SetFloat(hViewPortHeightInv, fHeightInv);

	g_pd3dDevice->SetStreamSource(0, g_pScreenSpaceQuad, 0, sizeof(Vertex));
	g_pd3dDevice->SetFVF(Vertex::FVF);

	// 设置要使用的Technique
	g_pEffect->SetTechnique(hTechScreen);

	UINT numPasses = 0;
	g_pEffect->Begin(&numPasses, 0);

	for (int i = 0; i < numPasses; i++)
	{
		g_pEffect->BeginPass(i);

		g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

		g_pEffect->EndPass();
	}
	g_pEffect->End();
}

//-----------------------------------------------------------------------------
// Desc: 渲染场景
//-----------------------------------------------------------------------------
VOID Render()
{    
	// 获取backbuffer
	LPDIRECT3DSURFACE9 pBackbuffer;
	g_pd3dDevice->GetRenderTarget(0, &pBackbuffer);

	//开始渲染场景
	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
	{
		//设回backbuffer
		g_pd3dDevice->SetRenderTarget(0, pBackbuffer);
		RenderScreen();

		//场景渲染结束
		g_pd3dDevice->EndScene();
	}

	//在屏幕上显示场景
	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}


//-----------------------------------------------------------------------------
// Desc: 窗口过程, 处理消息
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage( 0 );
		return 0;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
	//注册窗口类
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		L"ClassName", NULL };
	RegisterClassEx( &wc );

	//创建窗口
	HWND hWnd = CreateWindow( L"ClassName", L"图像平滑", 
		WS_OVERLAPPEDWINDOW, 200, 100, WIDTH, HEIGHT,
		GetDesktopWindow(), NULL, wc.hInstance, NULL );

	//初始化Direct3D
	if( SUCCEEDED( InitD3D( hWnd ) ) )
	{ 
		//创建场景图形
		if( SUCCEEDED( InitGeometry() ) )
		{
			//显示窗口
			ShowWindow( hWnd, SW_SHOWDEFAULT );
			UpdateWindow( hWnd );

			//进入消息循环
			MSG msg; 
			ZeroMemory( &msg, sizeof(msg) );
			while( msg.message!=WM_QUIT )
			{
				if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
				{
					TranslateMessage( &msg );
					DispatchMessage( &msg );
				}
				else
				{
					Render();  //渲染场景
				}
			}
		}
	}

	UnregisterClass( L"ClassName", wc.hInstance );
	return 0;
}/********************************
*  Author: ra



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: