DirectX从专家到小白

DirectX

DirectX是由微软开发的一组API(应用程序编程接口),旨在为Windows应用程序提供高性能的音频、视频和游戏功能。

通过硬件抽象层(HAL)和硬件仿真层(HEL)来保证设备无关性和让你的程序正常运行。

DirectDraw

DirectDraw 主要用于2D图形加速,而DirectX还包括Direct3D(用于3D图形渲染)、DirectSound(音频处理)、DirectInput(游戏设备输入)等。

DirectDraw 是 Microsoft DirectX 的显示组件,使软件设计人员能够直接操作显示内存、硬件分片、硬件覆盖和翻转图面。 提供对直接 32 位路径中特定于设备的显示功能的独立于设备的访问权限,直接访问显示卡的驱动程序中调用重要函数,而无需 Windows 图形设备接口 (GDI) 或与设备无关的位图 (DIB) 引擎。

DirectDraw提供了与硬件无关性的同时允许直接操作显存。与Windows 图形系统接口(GDI)相兼容,可直接操作显示设备,是DirectX技术中进行图像处理的基础,是DirectX中的关于视频输入输出的基本部分,只要使用的硬件支持DirectDraw,开发人员就可以使用DirectDraw可以方便地编制出高效的视频处理、图像处理的程序来。

COM

部件对象模型(Component Object Model, COM)是OLE 的基础。COM 为OLE提供了编程模型和二进制标准。COM定义并实现了软部件(如应用程序、数据对象、控件及服务)机制,并把它们统称为“对象”。每个软部件对象由数据以及访问数据的函数组成,访问软部件对象数据的函数的集合称为“接口”。

所有的COM接口都是从Iunknown接口继承而来的,IUnknown接口是所有COM接口的根。IUnknown接口具有3个方法:

  • QueryInterface():此方法查询新接口,并在新接口存在时返回之。
  • AddRef():此方法在接口或其它应用程序连编到此COM对象上时将引用计数值递加1。
  • Release():此方法将COM对象的引用计数递减1。当引用计数递减到0时,该COM对象自动释放。

DirectX是基于COM的一套软件编程接口。

色彩

采用标准的24位RGB模式定义一个颜色(3字节,分别代表红,绿,蓝三基色的颜色、值,从0到255)。

绘图基础

设备无关位图(DIB)

Windows中,当然还包括DirectX,都使用设备无关位图DIB(Device-Independent Bitmap)作为其最基本的图象文件格式。在大多数情况下,我们将其简称为位图(Bitmap)。

DIB是一个包含了图象的各种信息的文件,包括图象的尺寸,使用的颜色个数及其颜色值,还有每个像素的颜色数据等。

位深度(Bit depth)

通常用位深度来代表位图中的颜色值所使用的位个数(有多少种颜色)。

1字节能且最多只能反映出256( 2 8 2^8 28)种不同的状态。在位图中,如果用其中每一种状态代表图象中某一个点的颜色,那么最多可以得到256种不同的颜色,这就是我们常见的8位(256色)的位图。

DirectDraw采用24位RGB模式,16M( 2 2 4 2^24 224)种颜色。24位,即3字节,分别代表红,绿,蓝三基色的颜色、值,从0到255。

调色板(Palette)

显示器及显示卡与显示器的接口都采用模拟方式来处理色彩,因此,它们都具有几乎无限的色彩显示和传输能力。但主机和显示卡只能用数字方式来表示和处理色彩,如果要获得更丰富,更细腻的色彩就需要增加色彩的位深度,这就需要更大容量的显示存储器、更高的处理速度,同时分辨率的提高也对显示存储器的容量提出了很高的要求。

调色板(Palette)表示法:一种间接的色彩表示方法,降低对显存的需求。用一个颜色索引(Color Index)来代表各个像素点的颜色。色彩表(调色板)是一个包含了若干颜色索引和该索引所对应的真实颜色值的表。

16色模式下显示一幅256色或更高位深度的的图象时,本应色彩鲜艳的图片变得面目全飞。原因:同时显示在屏幕上的不同颜色最多只能有16种,于是Windows首先从图象中挑选了16种使用频率最高的颜色指定给调色板。对于所有其它的颜色,从调色板中挑选一个最接近的颜色显示出来。

图形设备接口GDI(Graphics device interface)

GDI不是为具有高表现力的多媒体软件和游戏而设计的。只提供了访问系统主存的能力,而不提供直接访问显存的能力,并不能从具有某些加速特性的显卡中获得其优良特性。

DirectDraw可以提供给开发者代表了真实显示内存的绘图页面。可以直接操纵显卡上的内存,图形显示变得出奇的快速。而且这些页面代表了显存中连续的内存块,使得在页面中寻址和读写变得非常方便。

位块传送(Blit,Bit block transfer)

将某一内存块的数据传送(变换转移,不是复制)到另一内存块。

光栅操作代码(ROP,Raster operation code):变换方式。

IDirectDrawSurface3::Blt可以利用硬件加速特性,可异步执行的,不需要等待blit结束才返回,然后系统在后台进行blit操作;还支持带源和目标关键色以及z缓存和alpha 通道的blit操作,完成各种效果变得极更为容易。

关键色(Color Key)

DirectDraw的blit函数,支持带关键色(Color key)的透明blit操作。如果在源页面上指定了一个颜色为关键色,那么在blit操作中,将视具有这种颜色的区域为透明,不会被传送到目标页面上。矩形区域中只有属于精灵的像素被映射了,其余带关键色的像素全被视为透明,对目标页面不会产生任何影响。

在包含精灵图像(不规则形状)的矩形内,将不属于精灵图像的部分全部使用同一种颜色,或使其在一个颜色范围之内(关键色,精灵图像中所没有用到的)。

源关键色(Source color key):在Blit过程中,不被复制;或在覆盖页面中,对目标层来说是不可见的。
目标关键色(Destination color key)在Blit过程中,将被替换;在覆盖页面中,将被目标层所覆盖。

视频RAM读写

如果你的应用程序要写视频RAM,内存中的位图并不需要占据连续的内存块。

图像dwWidth vs lpitch

lpitch的单位是字节,dwWidth的单位是像素。
lpitch中的字节数有时还包含了高速缓冲区的内存字节数。

dwWidth:内存中位图的一条线的开始和结束位置的内存地址之差(位图的宽度)。
pitch:内存中位图的一条线到下一条线开始位置的内存地址之差(宽度 + 缓存)。

[引擎笔记]ddsp.lpitch是什么

使用教程

下载DirectX SDK库

头文件包含

#include <ddraw.h>

创建DirectDraw的对象实体

DirectDraw的对象实体代表了微机显示适配器,表示显示硬件,它包括了显示器和显卡还有显存,用它来代表整个显示系统。

LPDIRECTDRAW lpDD;

初始化DirectDrawCreate

HRESULT ddrval = DirectDrawCreate (NULL, &lpDD, NULL);

lpDD接受初始化成功的DirectDraw对象的地址,是整个DirectDraw接口的最高层领导。

显示设置SetCooperativeLevel()

lpDD->SetCooperativeLevel (GetActiveWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);

使DirectDraw对象与主窗口的消息挂上勾,期望DirectDraw以独占和全屏方式工作。

必须在创建DirectDraw对象之后,立即调用。

设置显示器的显示模式SetDispalyMode()

显示模式指的是显示器的当前设置,描述了显示器的分辨率和位深度。随着显示模式的尺寸和位深度的增加,它所需要的视频RAM也随之增加。

lpDD->SetDisplayMode( 640, 480, 8 );

把显示模式设为640*480,8位色彩模式(即256色)。可以调用EnumDisplayModes()来列举出显示器所支持的所有显示模式。

只有当DirectDraw对象为独占访问的控制程度时才能改变显示器的显示模式,如果DirectDraw对象运行为窗口模式,调用该函数会返回一个错误。

创建页面

翻页(Page flipping)

每一个页面都可以被轮流翻页至显示屏幕,静止的图象便开始运动起来。

主页面(primary surface):当前正好位于显示屏幕的页面。
后台缓存(Back buffers):其后等待翻页至屏幕的页面。

设置好一个翻页链结构。

一般至少建立前后两页(两块画板)。一边给别人看已经画好的另一块,等这块画好了,两块板就对调一下,让别人看新画好的这块。

页面DirectDrawSurface对象

DirectDrawSurface对象表示页面,用于绘制图像。代表了内存里的一个连续的线性的数据区。

页面可以有很多种表现形式,它既可以是可见的(屏幕的一部分或全部),称之为主页面(Primary Surface);也可以是作换页用的不可见页面,称之后台缓存(Back Buffer),在换页后,它成为可见;还有一种始终不可见的,称之为离屏页面(Off-screen Surface),用它来存储图象。其中,最重要的页面是主页面,每个DirectDraw应用程序都必须创建至少一个主页面,用它来代表屏幕上可见的区域(显示屏幕)。

LPDIRECTDRAWSURFACE lpDDSPrimary;
DDSURFACEDESC页面描述
DDSURFACEDESC surfaceDesc;
memset (&surfaceDesc, 0, sizeof(surfaceDesc));
surfaceDesc.dwSize = sizeof(surfaceDesc);  //结构的大小
surfaceDesc.dwFlags = DDSD_CAPS;  //指定DDSURFACEDESC结构的ddsCaps成员为可用
surfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  //指定要创建的是主页面
CreateSurface()

创建我们所请求的页面或换页链,并且返回指向主页面的IDirectDrawSurface接口的指针。

lpDD->CreateSurface (&surfaceDesc, &lpDDSPrimary, NULL);

如果函数调用成功,lpDDSPrimary将代表一个合法的主页面对象。在主页面上所绘制的图形将立即反映到你的显示屏幕上。

裁剪版Clipper

在窗口下,为了防止 DirectDraw 画到窗口外面去,需要加一个画框(裁剪板)。

LPDIRECTDRAWCLIPPER	lpClipper;
//Create a clipper to ensure that our drawing stays inside our window.
lpDD->CreateClipper (0, &lpClipper, NULL);
//Setting it to our hWnd gives the clipper the coordinates from our window.
lpClipper->SetHWnd (0, hwnd);
//Attach the clipper to the primary surface.
lpDDSPrimary->SetClipper (lpClipper);

绘制

输出文字
if ( lpDDSPrimary->GetDC(&hdc) != DD_OK) return FALSE; //获得设备环境句柄
SetBkColor( hdc, RGB( 0, 0, 255 ) ); //设置背景颜色
SetTextColor( hdc, RGB( 255, 255, 0 ) ); //设置文字颜色
TextOut( hdc, 220, 200, szMsg1, lstrlen(szMsg1)); //输出文字
TextOut( hdc, 280, 240, szMsg2, lstrlen(szMsg2));
lpDDSPrimary->ReleaseDC(hdc); //释放资源

与Windows的GDI(图形设备接口)一致。

调用IDirectDrawSurface::Lock()方法和IDirectDrawSurface::UnLock()方法来给后台缓冲区加锁和解锁。

只对主表面(Surface)进行写操作。完成第一次弹出表面(Surface)操作时,会有一个明显的延时,所以只对主表面(Surface)缓冲区进行写操作是为了防止程序刚开始时显示不连贯。初始化函数和标题页只能放在主表面(Surface)缓冲区中。

只有表面(Surface)处于开锁状态,应用程序才能把它们由后台弹至前台。

调用IDirectDrawSurface::Unlock对表面(Surface)解锁后,指向表面(Surface)存储单元的指针就失效。

当把文本写到缓冲区后,调用IDirectDrawSurface::ReleaseDC()方法或者IDirectDrawSurface::Unlock()来解锁Surface,并释放句柄。

释放对象

f( lpDD != NULL ) //判断DirectDraw对象是否为空
{
	if( lpDDSPrimary != NULL ) //判断主页面对象是否为空
	{
		lpDDSPrimary->Release(); //释放
		lpDDSPrimary = NULL;
	}
	lpDD->Release(); //释放
	lpDD = NULL;
}

抖动处理(Dithering)

在低位深度的图象中,由于颜色总数的限制,有些颜色无法显示出来。抖动处理(dithering)的方法指用交替的点图案去模拟在图象中不能使用的颜色,以提高显示效果。

在原始照片上,叠加一层白色噪声,让每个像素点的值都有所起伏。并且每个像素点起伏的概率为一个确定的值。(适度地)叠加了一层噪声之后,非但没有降低信号的质量,反而会带来提升。(想不通!!!)
信号的抖动处理

Direct3D

从DirectX 8.0开始,微软开始推荐开发人员使用Direct3D来处理2D图形,因为Direct3D提供了更加强大和灵活的图形处理能力。

DirectX Graphics

跨平台的图形API

如OpenGL和Vulkan

资料

DirectX中文手册
DirectDraw 参考
两个小时学会DirectDraw编程
游戏编程之十五 DirectDraw 的基本知识
游戏开发新手入门之DirectX入门

GDI

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值