admin 管理员组文章数量: 1184232
Direct3D技术在图像处理、游戏开发等领域用得非常广泛,这里给大家讲解怎么用Direct3D API开发一个简单的图片浏览器。这个图片浏览器的功能有:图像显示,在视图区拖动图层、改变图层大小、图层旋转。先提醒一下,阅读该篇文章的读者最好具有一点D3D的开发基础,因为这篇文章不会讲Directshow的基础知识。如果你完全没有学过Direct3D,建议先学习一下一些Direct3D的入门教程(比如:《DirectX 9.0 3D游戏开发编程基础》 )。
Direct3D概述
Direct3D(简称:D3D)是微软公司开发出来的一套3D绘图编程接口,是DirectX的一部份,是一种更高效的绘图API,支持直接在显存中操作图像,目前广被各家显卡厂商所支援。
Direct3D封装了一个硬件抽象层(HAL),硬件厂商遵守这个硬件层的接口标准,对外以统一的接口形式为用户提供图形图像功能,也就是说开发者可以在无视于设备差异的情况下访问底层的硬件。DirectX 封装了一些 COM(Component Object Model)对象,这些 COM 对象为访问系统硬件提供了一个主要的接口。下面是Direct3D的架构图:
开发Direct3D程序的流程
Driect3D功能非常强大,但是Direct3D程序的结构非常简单清晰,一个Direct3D程序的基本结构如图1所示:
开发Direct3D程序大概可以细分为以下几个步骤:
1. 创建窗口
2. 初始化Direct3D
创建D3D接口对象 -》获取设备性能信息 -》填充D3DPRESENT_PARAMETERS结构 -》创建D3D设备接口对象
3. 处理系统消息循环
获取、转换并调度消息 -》重画客户区
4. 渲染与显示
5. 释放所有D3D对象
例子解析
这个例子功能很简单,从磁盘加载图片进来,显示到中央的视图窗口,接着可以对图像进行一些操作。界面是用Win32 API开发的,上面有个菜单栏。我们打开一张图片后,图片以缩略图形式显示到中间,这时候图片被D3D作为一个图层(即Texture)显示,我们可以对图层进行放大、拖动、旋转和删除操作。目前最多支持两个图层显示(这个读者可以修改)。程序的运行示意图如下:
我们先看看这个例子的程序入口点即WinMain函数是如何实现的:
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR lpCmdLine, INT nCmdShow)
{
HRESULT hr = S_OK;
// UINT uTimerID=0;
// Initialize COM
CoInitialize (NULL);
hInstance = hInst;
g_pPresentation = new CD3DImageDraw();
if( !g_pPresentation )
{
hr = E_OUTOFMEMORY;
Msg( TEXT("Memory allocation error: failed to create CD3DImageDraw object"), E_OUTOFMEMORY);
}
else
{
hr = g_pPresentation->Initialize();
}
m_nCurSel = -1;
if( SUCCEEDED(hr))
{
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
// Main message loop
while( msg.message!=WM_QUIT )
{
if(GetMessage( &msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
// Clean up everything and exit the app
if( g_pPresentation )
{
delete g_pPresentation;
g_pPresentation = NULL;
}
CoUninitialize();
return 0L;
}
上述代码很直观的展示了整个程序的流程:
1. 调用Com库初始化函数(因为D3D库需要加载);
2. 创建一个CImageDraw类型的实例,将指针变量g_pPresentation指向这个实例;
3. 创建窗口;
4. 开始消息循环;
5. 销毁D3D对象,卸载COM库,退出程序。
因为CImageDraw类负责D3D资源的创建和管理,图像的显示绘制也在这个类里面实现,还有跟图层显示相关的类:CImageTexture,我们有必要对这几个类做一下介绍。以下是这些类的声明:
class CDirect3DBase
{
// methods
public:
CDirect3DBase();
~CDirect3DBase();
HRESULT Initialize();
HRESULT Render();
HRESULT InitD3D();
HRESULT SetupMatrices();
void SetWorld();
void SetColor( D3DCOLOR color );
IDirect3DDevice9 * GetDevice();
public:
int m_scnWidth, m_scnHeight;
float m_WorldLeft, m_WorldTop, m_WorldRight, m_WorldBottom;
protected:
void Cleanup(void);
protected:
HWND m_hwnd;
CComPtr<IDirect3D9> m_pD3D;
CComPtr<IDirect3DDevice9> m_pd3dDevice;
D3DCOLOR m_d3dcolorBackground;
};
class CImageTexture
{
public:
CImageTexture();
~CImageTexture();
CDirect3DBase * m_pD3DBase;
D3DXVECTOR3 ScreenToWorld(D3DXVECTOR3 s);
D3DXVECTOR3 WorldToScreen(D3DXVECTOR3 w);
public:
HRESULT Init();
HRESULT LoadImageToTexture(LPCTSTR lpFile);
//HRESULT LoadImagetoTexture(HBITMAP hbmp);
void SetFilePath(LPCTSTR lpszFile);
HRESULT ReLoad();
void ReleaseTexture();
HRESULT BltToTexture(IDirect3DSurface9 *lpSurf, UINT Width, UINT Height);
HRESULT CopyMediaSample( BYTE *pSampleBuffer, LONG lSamplePitch );
int GetImageWidth() { return m_ImageWidth; }
int GetImageHeight() { return m_ImageHeight; }
void SetX(float x) { m_Xpos = x; }
void
版权声明:本文标题:用Direct3D实现一个图片浏览器(支持多图层显示、图层拖动、旋转) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1755026640a3062216.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论