directdraw 学习总结

来源:互联网 发布:模特兼职知乎 编辑:程序博客网 时间:2024/04/30 16:09

ddraw可以直接操作显存,而gdi或者你的办法是对内存处理,然后从内存copy数据到显存,所以DDRAW比GDI高效!

DirectX学习:

DirectX中最重要的部分就是DirectDraw了,它是微软最先开发的组件,其中有个概念图像协处理器。图像协处理器主要用于处理显示,它与CPU是并行工作的,由于对图形显示来说,最多的操作时把某块内存的内容移动到另一块内存,所以最初的图形协处理器只提供一称为位转换器(Blitter)的操作----这个名字是从图形协处理器导出来的首要功能,即从BLT(位转移)中得来的。

      当硬件位转换器功能出现后,中央处理器(cpu)所需做的仅仅是用几条指令建立起位转换器,然后协处理器将继续后面的图形操作。它与中央处理器并行工作,把某块内存中的数据搬到另—处。后来,图形协处理器的功能越来越复杂,它能执行收缩、拉伸、格式转换等一系列功能,甚至有些协处理器还专门设计了一些功能以加速windows的操作。然而BLT操作仍旧是其他许多图形操作的基础,因此,BLT速度的快慢(带宽)是显示卡的重要性能指标。

 

 

显卡内存:

系统内存物理上位于主板中,它用于存储所有的应用程序数据,系统内存可以很轻易地由cpu来访问,但图形协议处理器不能自由访问,所以cpu必须处理所有的系统内存和显示内存之间的内存数据拷贝操作(通过扩展总线)。

硬件设计技术的进步的给我们带来丁两个互相独立的内存系统:一片用于协处理器,另一片用于cpu,介于它们之间的是相对慢速的扩展总线。图形协处理器完全不能访问系统内存,而cpu访问显示内存必须通过总线。

 

AGP结构:

通过把显示系统移到扩展总线的另一边并提供给它一个通向系统内存的端口,AGP技术解决了总线拥挤总是和内存使用合适性问题。显示系统通过使用这个端口可快速访问经过特殊设汁的系统内存,而且数据经由这个端口的传输速率要比经过总线快很多。我们把这种内存称为非本地显示内存。

DirectDraw之前,windows开发人员不得不是用图形设备接口(GDI)来开发应用程序。GDI提供很多设备无关性的图形接口,这些接口包含从字体处理到位图操作几乎所有的功能。GDI通过一个被称为显示驱动接口(DDI)的驱动程序来操作具体的图形硬件。DDI层的功能由硬件生产商开发的,它们为自己的产品提供了显示驱动程序。一个好的显示驱动程序能够利用显示卡的绝大部分潜能,并在可能的情况下还支持硬件加速的windows操作。GDI最主要的任务是提供设备的无关性和一个高层的抽象,像直接访问显示内存之类的底层操作,它是不支持的。另外对overlay等高层功能,也不支持。

 

创建图面:

所有的DriectDraw图面都是由CreateSurface开始它们的生命周期的;

主图面:

      DriectDraw的术语来说,主图面就是用户能够看到的当前界面,每个DirectDraw对象只有一个主图面。主图面就是GDI用于绘制windows用户界面的图面。

Off-screen图面:

  Off-screen图面是不能直接看到的,它主要是作为存储可视部件的存储缓冲区,这些缓冲区可用于组成主图面或切换图面。

 

调入图面:

      图面被创建之后,如果应用程序没有在其中装入数据,那么它基本上没有什么用。在这里,很多已有windows的功能可以帮助我们节省大量的时间——为了设备独立性,Windows擅长于把位图格式转化为其他的格式。首先要做的事情是确定数据来源——将使用文件、windows资源或者是定制的格式?图像以什么格式保存?在这里我们将介绍以windows DIB s(设备无关位图)格式保存的位图,这样在以后遇到定制格式时也可以用同样的方法来处理。

调入图面看起来很简单,但实际上所至做的事情要比想象中复杂。如果所保存图像的大小和像素格式与目标图面不一致,那么就要进行转换和放缩,而进行这些操作却不是那么轻松的。幸运的是我们可以调用某些window s的功能来解决这个问题。

 

函数说明:

      DEFINE_GUID(IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56);

DEFINE_GUID(IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27);

 

定义2GUID,一个是DirectDraw对象,一个是DirectDrawSurface对象;其中IID_IDirectDraw2是一个常量,同理IID_IDirectDrawSurface2也是一个常量,用来表示GUID

 

 

1) IDirectDrawSurface2_IsLost函数;

#define IDirectDrawSurface2_IsLost(p)                   (p)->lpVtbl->IsLost(p)

因此,DirectDraw可以随意将任何一个或者所有的基于显示RAM的表面从非激活应用程序中移走。这种情况就是所谓的表面丢失。从技术上讲,程序仍具有表面,但它们不再同任何内存相关。要使用丢失的表面会导致DDERR-SURFACELOST错误。IsLost()函数可用于确定一个表面是否丢失了内存。

2) IDirectDrawSurface2_Restore函数;

#define IDirectDrawSurface2_Restore(p)                  (p)->lpVtbl->Restore(p)
  
表面内存丢失后可通过Restore()函数恢复,但只能在应用程序被重新激活之后才可恢复。这会导致应用程序无法将处于最小化状态的所有表面复原。

Restore()
函数可恢复附属于表面的任一内存,但并不恢复内存的内容。表面被复原后,应用程序就可以恢复表面内容了。

 

3) IDirectDrawSurface2_Flip函数

#define IDirectDrawSurface2_Flip(p,a,b)                 (p)->Flip(a,b)

Flip()执行页面翻转,使back缓冲区可见。

Flip()函数用于页面翻转操作。调用Flip()函数可隐藏屏幕上先前可见的表面,并使一个后备缓冲区显现。只有被明确地创建为翻转表面的表面,才响应该函数的调用。
必须牢记,真正的翻转操作不可能总是成功。页面翻转要求有足够的显示RAM容纳两整屏有效数据。如果满足不了这一要求,系统RAM中将创建一个后备缓冲区。这时调用Flip()函数进行的是blt操作而不是页面翻转。基于系统RAM的后备缓冲区中的内容被拷贝到主表面上。这样会严重影响性能,但是,在真正的页面翻转中如果没有足够的显示RAM,又不退出程序,也只能如此了。如果你的应用程序要求最佳性能,就得设法避免激活不能进行真正页面翻转的显示模式。

4) IDirectDrawSurface2_Blt函数

#define IDirectDrawSurface2_Blt(p,a,b,c,d,e)            (p)->lpVtbl->Blt(p,a,b,c,d,e)

      Blt()函数是一个主要函数。Blt()函数能够进行常规的blting(无特殊影响的简单的表面到表面的blt),同时支持延伸、旋转、镜像和颜色填充的操作。当用于同剪裁器关联的表面时,Blt()可进行剪裁blt操作。

      函数原型如下:

      HRESULT Blt(
  
LPRECT lpDestRect,
  
LPDIRECTDRAWSURFACE7 lpDDSrcSurface,
  
LPRECT lpSrcRect,
  
DWORD dwFlags,
  
LPDDBLTFX lpDDBltFx
)

lpDestRect
:这是指定一个目标位图的地址,就是你要拷贝到页面的那个位置。如果为NULL则是整个页面。

lpDDSrcSurface
:这是源页面的指针,就是从哪个页面拷贝。如果为NULL就不指定。
lpSrcRect
:这是源页面的位图地址。就是拷贝页面的哪个部分。如果为NULL就是全部。
dwFlags
:指定哪些DDBLTFX成员有效,本例中使用DDBLT_COLORFILL指定对位图进行色彩填充,DDBLT_WAIT用来强制Blt等待硬件刷新。
lpDDBltFx
ddbltfx结构的地址指针。

 

      调用如下:

      lpDestSurface->Blt( &dest_rect, lpSourceSurface, &source_rect, (DDBLT_WAIT | DDBLT_KEYSRC), NULL)

5) IDirectDraw_WaitForVerticalBlank函数

#define IDirectDraw_WaitForVerticalBlank(p, a, b)  (p)->lpVtbl->WaitForVerticalBlank(p, a, b)

This method helps the application synchronize itself with the vertical-blank interval.

1.                                                                                                                                                                                                                                                                       HRESULT WaitForVerticalBlank(

2.                                                                                                                                                                                                                                                                         DWORD dwFlags, 

3.                                                                                                                                                                                                                                                                         HANDLE hEvent

4.                                                                                                                                                                                                                                                                       ); 

Parameters

dwFlags

Determines how long to wait for the vertical blank.                              The following table shows the possible flags.

Flag

Description

DDWAITVB_BLOCKBEGIN

Returns when the vertical-blank interval begins.

DDWAITVB_BLOCKBEGINEVENT

Triggers an event when the vertical blank begins.

This value is not supported.

DDWAITVB_BLOCKEND

Returns when the vertical-blank interval ends and the display begins.

hEvent

Handle of the event to be triggered when the vertical blank begins. This parameter is not currently used.

 

6) IDirectDraw2_GetCaps函数

#define IDirectDraw2_GetCaps(p, a, b)               (p)->lpVtbl->GetCaps(p, a, b)

HRESULT GetCaps(

 LPDDCAPS lpDDDriverCaps,

 LPDDCAPS lpDDEmulCaps

);

Parameters

 

lpDDDriverCaps

Address of a DDCAPS structure that will be filled with the capabilities of the hardware, as reported by the device driver. Set this parameter to NULL if device driver capabilities are not to be retrieved.

lpDDEmulCaps

Address of a DDCAPS structure that will be filled with the capabilities of the software emulation. Set this parameter to NULL if software emulation capabilities are not to be retrieved.

 

If the method succeeds, the return value is DD_OK.

If the method fails, the return value may be one of the following error values:

DDERR_INVALIDOBJECT

DDERR_INVALIDPARAMS

 

7) IDirectDraw_QueryInterface函数

C++:

#define IDirectDraw_QueryInterface(p, a, b)        (p)->lpVtbl->QueryInterface(p, a, b)

C语言:

#define IDirectDraw_QueryInterface(p, a, b)        (p)->QueryInterface(a, b)

 

HRESULT QueryInterface(

 [in]   REFIID riid,

 [out]  void **ppvObject

);

Parameters

riid [in]

The identifier of the interface being requested.

ppvObject [out]

The address of a pointer variable that receives the interface pointer requested in theriid parameter. Upon successful return, *ppvObject contains the requested interface pointer to the object. If the object does not support the interface, *ppvObject is set to NULL.

Return Value

This method returns S_OK if the interface is supported, and E_NOINTERFACE otherwise. IfppvObject is NULL, this method returns E_POINTER.

   

 

8) IDirectDraw_Release函数

C++:

#define IDirectDraw_Release(p)                     (p)->lpVtbl->Release(p)

C语言:

#define IDirectDraw_Release(p)                     (p)->lpVtbl->Release()

 

9) IDirectDraw2_SetCooperativeLevel函数

#define IDirectDraw2_SetCooperativeLevel(p, a, b)   (p)->SetCooperativeLevel(a, b)

SetCooperativeLevel()函数用来设置DirectDrawWindows系统的协作/控制级别,简单说就是 决定应用程序是运行与窗口模式还是全屏模式(具有独占访问系统内存的特性)。

注:这里的独占指在绘图时,其他应用程序将不可改变显示模式及调色板。

常用的有:

      SetCooperativeLevelhwndDDSCL_NORMAL   //普通窗口模式

      SetCooperativeLevelhwndDDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
                           DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT
//全屏

函数原型:

      

10)             IDirectDraw2_CreateClipper

#define IDirectDraw2_CreateClipper(p, a, b, c)      (p)->CreateClipper(a, b, c)

函数功能:This method creates aDirectDrawClipper object.

HRESULT CreateClipper(

 DWORD dwFlags,

 LPDIRECTDRAWCLIPPER FAR* lplpDDClipper,

 IUnknown FAR* pUnkOuter

);

Parameters

dwFlags

This parameter is currently not used and must be set to zero.

lplpDDClipper

Address of a variable that will be set to a validIDirectDrawClipper interface pointer if the call succeeds.

pUnkOuter

Allows for future compatibility with COM aggregation functionality. Presently, this method will return CLASS_E_NOAGGREGATION if this parameter is anything but NULL.

Return Values

If the method succeeds, the return value is DD_OK.

11)             IDirectDrawClipper_SetHWnd

#define IDirectDrawClipper_SetHWnd(p, a, b)        (p)->SetHWnd(a, b)

HRESULT SetHWnd(

 DWORD dwFlags,

 HWND hWnd

);

Parameters

dwFlags

This parameter is currently not used and must be set to zero.

hWnd

Window handle that obtains the clipping information.

Return Values

If the method succeeds, the return value is DD_OK.

 

12)              IDirectDrawSurface_SetClipper

#define IDirectDrawSurface_SetClipper(p,a)             (p)->SetClipper(a)

TheSetClipper method attaches a DirectDrawClipper to a DirectDrawSurface. This function is primarily used by surfaces that are being overlayed on or blitted to the primary surface, but it can be used on any surface. Once a DirectDrawClipper has been attached, and a clip list associated with it, it will be used for Blt,BltBatch, and UpdateOverlay operations involving the parent DirectDrawSurface. This method can also be used to detach a DirectDrawSurface's current Clipper.

Syntax

HRESULT SetClipper(

 LPDIRECTDRAWCLIPPERlpDDClipper

 );

Parameters

lpDirectDrawClipper

Either NULL, or points to theIDirectDrawClipper interface representing the DirectDrawClipper that will be attached to the DirectDrawSurface. If NULL, the current clipper will be detached.

Return Values

Value

Description

DD_OK

The method succeeded.

DDERR_INVALIDPARAMS

One or more of the input parameters is invalid.

DDERR_INVALIDOBJECT

DirectDraw received a pointer that was an invalid DirectDraw object.

DDERR_NOCLIPPERATTACHED

No clipper object attached to surface object.

 

13)             IDirectDrawClipper_Release

#define IDirectDrawClipper_Release(p)              (p)->Release()

      函数功能:释放Clipper对象

 

14)             IDirectDrawSurface2_Lock函数

#define IDirectDrawSurface2_Lock(p,a,b,c,d)             (p)->Lock(a,b,c,d)

HRESULT Lock(LPRECT   lpDestRect,      // destination RECT to lock
     LPDDSURFACEDESC2 lpDDSurfaceDesc, // address of struct to receive info
     DWORD            dwFlags,         // request flags
     HANDLE           hEvent);         // advanced, make NULL

Parameters

lpDestRect

Address of aRECT structure that identifies the region of surface that is being locked. If NULL, the entire surface will be locked.

lpDDSurfaceDesc

Address of aDDSURFACEDESC2 structure that will be filled with the relevant details about the surface.

dwFlags

The following table shows the possible flags.

Flag

Description

DDLOCK_EVENT

This flag is not implemented.

Triggers the event whenIDirectDrawSurface5::Lock can return the surface memory pointer requested.

This flag is set if an event handle is being passed toIDirectDrawSurface5::Lock.

If multiple locks of this type are placed on a surface, events are triggered in FIFO order.

DDLOCK_READONLY

Indicates that the surface being locked will only be read.

DDLOCK_SURFACEMEMORYPTR

Indicates that a valid memory pointer to the top of the specified rectangle should be returned.

If no rectangle is specified, a pointer to the top of the surface is returned. This is the default.

DDLOCK_WAIT

If a lock cannot be obtained because a blit operation is in progress, the method retries until a lock is obtained or another error occurs, such asDDERR_SURFACEBUSY.

DDLOCK_WRITEONLY

Indicates that the surface being locked will be write-enabled.

DDLOCK_NOSYSLOCK

This flag is not supported in Windows CE.

hEvent

This parameter is not used and must be set to NULL.

Return Values

If the method succeeds, the return value is DD_OK.

 

15)             IDirectDrawSurface2_Unlock函数

#define IDirectDrawSurface2_Unlock(p,b)                 (p)->Unlock(b)

 

HRESULT Unlock(

 LPRECT lpRect

);

Parameters

lpRect

Address of theRECT structure that was used to lock the surface in the corresponding call to theIDirectDrawSurface5::Lock method. This parameter can be NULL only if the entire surface was locked by passing NULL in thelpDestRect parameter of the corresponding call to the IDirectDrawSurface5::Lock method.

Return Values

If the method succeeds, the return value is DD_OK.

 

16)             IDirectDrawSurface2_GetDC函数

#define IDirectDrawSurface2_GetDC(p,a)                  (p)->GetDC(a)

函数功能:创建GDI兼容的句柄

HRESULT GetDC(

 HDC FAR* lphDC

);

Parameters

lphDC

Address for the returned handle to a device context.

Return Values

If the method succeeds, the return value is DD_OK.

 

17)             IDirectDrawSurface2_ReleaseDC

#define IDirectDrawSurface2_ReleaseDC(p,a)              (p)->ReleaseDC(a)

函数功能:TheReleaseDC method releases the hDC previously obtained with GetDC. It also Unlocks the surface previously locked when GetDC was called.

Syntax

HRESULT ReleaseDC(

 HDChDC

 );

Parameters

hDC

Handle to a device context previously obtained by callingGetDC.

Return Values

 

 

Value

Description

DD_OK

The method succeeded.

DDERR_INVALIDPARAMS

One or more of the input parameters is invalid.

DDERR_INVALIDOBJECT

DirectDraw received a pointer that was an invalid DirectDraw object.

DDERR_SURFACELOST

Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.

DDERR_GENERIC

Generic failure.

DDERR_UNSUPPORTED

Action not supported.

 

18)             IDirectDraw2_CreateSurface

 

ddraw.h中找到:

#define IDirectDraw_CreateSurface(p, a, b, c)      (p)->CreateSurface(a, b, c)

函数原型:

1.     该函数为该DirectDraw对象创建一个DirectDrawSurface对象。

HRESULT CreateSurface(

LPDDSURFACEDESC lpDDSurfaceDesc,

LPDIRECTDRAWSURFACE FAR *lplpDDSurface,

IUnknown FAR *pUnkOuter

);

参数:

lpDDSurfaceDesc

一个DDSURFACEDESC结构的地址,用来描述所请求创建的页面的页面信息。在调用这个函数之前,你应该设置DDSURFACEDESC结构所有成员的值为0DDSCAPS结构是DDSURFACEDESC的一个成员。

lplpDDSurface

如果该函数调用成功,该参数将接收到指向新创建的DirectDrawsurface对象的指针的地址。

pUnkOuter

该参数将允许与今后的COM集合特性相兼容。目前,只要这个参数不是NULLIDirectDraw2::CreateSurface返回一个错误。

返回值:

如果函数调用成功,返回DD_OK

如果函数调用失败,返回值可能是下列错误值之一:

DDERR_INCOMPATIBLEPRIMARY

DDERR_INVALIDCAPS

DDERR_INVALIDOBJECT

DDERR_INVALIDPARAMS

DDERR_INVALIDPIXELFORMAT

DDERR_NOALPHAHW

DDERR_NOCOOPERATIVELEVELSET

DDERR_NODIRECTDRAWHW

DDERR_NOEMULATION

DDERR_NOEXCLUSIVEMODE

DDERR_NOFLIPHW

DDERR_NOMIPMAPHW

DDERR_NOOVERLAYHW

DDERR_NOZBUFFERHW

DDERR_OUTOFMEMORY

DDERR_OUTOFVIDEOMEMORY

DDERR_PRIMARYSURFACEALREADYEXISTS

DDERR_UNSUPPORTEDMODE

 

  调用举例:

          /* Create the video surface */

   LPDIRECTDRAWSURFACE surface_v1;

   if (IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &surface_v1, NULL) != DD_OK)

       return VLC_EGENERIC;

 

19)             IDirectDrawSurface_QueryInterface

ddraw.h中定义如下:

#define IDirectDrawSurface_QueryInterface(p,a,b)       (p)->lpVtbl->QueryInterface(p,a,b)

调用举例;

/* Now that the surface is created, try to get a newer DirectX interface */

   HRESULT hr = IDirectDrawSurface_QueryInterface(surface_v1,

                                                  &IID_IDirectDrawSurface2,

                                                  (LPVOID *)surface);

20)             IDirectDrawSurface_Release函数

#define IDirectDrawSurface_Release(p)                  (p)->lpVtbl->Release(p)

 

21)             DirectDrawCreate函数

函数功能:创建一个DirectDraw对象的实例。

HRESULT WINAPI DirectDrawCreate(
GUID FAR *lpGUID,
LPDIRECTDRAW FAR *lplpDD,
IUnknown FAR *pUnkOuter
);

 

参数:

lpGUID
  
全局唯一标志符(GUID)的地址,代表了要创建的驱动类型。该参数可以是NULL,代表当前所使用的显示驱动;你也可以指定其为下列值之一,以限制当前显示驱动的行为能力,为调试所用。

DDCREATE_EMULATIONONLY
  
DirectDraw对象只使用软件仿真的方式实现所有的特性;它将不会从硬件加速中获得任何好处。

DDCREATE_HARDWAREONLY
  
DirectDraw对象只使用硬件支持的加速特性;对于那些硬件不支持的特性,也绝不会使用软件仿真的方式来完成,而且将返回DDERR_UNSUPPORTED的错误值。

lplpDD
  
如果函数调用成功,该参数将为指向一合法的DirectDraw对象的指针的地址。

pUnkOuter
  
该参数将允许与今后的COM集合特性相兼容。目前,只要这个参数不是NULL,该函数将返回一个错误。

返回值:

如果函数调用成功,返回DD_OK
如果函数调用失败,返回值可能是下列错误值之一:

DDERR_DIRECTDRAWALREADYCREATED
DDERR_GENERIC
DDERR_INVALIDDIRECTDRAWGUID
DDERR_INVALIDPARAMS
DDERR_NODIRECTDRAWHW
DDERR_OUTOFMEMORY

备注:

该函数试图初始化一个DirectDraw对象,如果成功则返回一个指向该对象的指针。

在多显示器的系统上,当设置协作模式为普通,并给lpGUID指定了NULL将导致DirectDraw对象运行于仿真的模式。要在这些系统上获得硬件加速特性,你必须指定设备的GUID

 

 

22)              

/**

 * Create an YUV overlay or RGB surface for the video.

 *

 * The best method of display is with an YUV overlay because the YUV->RGB

 * conversion is done in hardware.

 * You can also create a plain RGB surface.

 * (Maybe we could also try an RGB overlay surface, which could have hardware

 * scaling and which would also be faster in window mode because you don't

 * need to do any blitting to the main display...)

 */

static int DirectXCreateSurface(vout_display_t *vd,

                               LPDIRECTDRAWSURFACE2 *surface,

                               const video_format_t *fmt,

                               DWORD fourcc,

                               bool use_overlay,

                               bool use_sysmem,

                               int backbuffer_count)

{

   vout_display_sys_t *sys = vd->sys;

             

   DDSURFACEDESC ddsd;

      //初始化ddsd结构

      /*其中

The DDSURFACEDESC structure contains a description of a surface to be created by the driver.

typedef struct _DDSURFACEDESC {
  DWORD  dwSize;
  DWORD  dwFlags;
  DWORD  dwHeight;
  DWORD  dwWidth;
  union {
  LONG  lPitch;
  DWORD  dwLinearSize;
  };
  DWORD  dwBackBufferCount;
  union {
  DWORD  dwMipMapCount;
  DWORD  dwZBufferBitDepth;
  DWORD  dwRefreshRate;
  };
  DWORD  dwAlphaBitDepth;
  DWORD  dwReserved;
  LPVOID  lpSurface;
  DDCOLORKEY  ddckCKDestOverlay;
  DDCOLORKEY  ddckCKDestBlt;
  DDCOLORKEY  ddckCKSrcOverlay;
  DDCOLORKEY  ddckCKSrcBlt;
  DDPIXELFORMAT  ddpfPixelFormat;
  DDSCAPS  ddsCaps;
} DDSURFACEDESC;

*/

   ZeroMemory(&ddsd, sizeof(ddsd));

   ddsd.dwSize   = sizeof(ddsd);

   ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);

   ddsd.dwFlags  = DDSD_HEIGHT | DDSD_WIDTH;

   ddsd.dwWidth  = fmt->i_width;

   ddsd.dwHeight = fmt->i_height;

   if (fourcc) {

       ddsd.dwFlags |= DDSD_PIXELFORMAT;

       ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;

       ddsd.ddpfPixelFormat.dwFourCC = fourcc;

}

//初始时use_overlay=false

   if (use_overlay) {

       ddsd.dwFlags |= DDSD_CAPS;

       ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;

       if (backbuffer_count > 0)

           ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;

 

       if (backbuffer_count > 0) {

           ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;

           ddsd.dwBackBufferCount = backbuffer_count;

       }

   } else {

       ddsd.dwFlags |= DDSD_CAPS;

       ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

       if (use_sysmem)    //初始化时为False

           ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;

       else

           ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;

   }

 

   /* Create the video surface */

   LPDIRECTDRAWSURFACE surface_v1;

   if (IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &surface_v1, NULL) != DD_OK)

       return VLC_EGENERIC;

 

   /* Now that the surface is created, try to get a newer DirectX interface */

   HRESULT hr = IDirectDrawSurface_QueryInterface(surface_v1,

                                                  &IID_IDirectDrawSurface2,

                                                  (LPVOID *)surface);

   IDirectDrawSurface_Release(surface_v1);

   if (hr != DD_OK) {

       msg_Err(vd, "cannot query IDirectDrawSurface2 interface (error %li)", hr);

       return VLC_EGENERIC;

   }

 

   if (use_overlay) {  

       /* Check the overlay is useable as some graphics cards allow creating

        * several overlays but only one can be used at one time. */

       if (DirectXUpdateOverlay(vd, *surface)) {

           IDirectDrawSurface2_Release(*surface);

           msg_Err(vd, "overlay unuseable (might already be in use)");

           return VLC_EGENERIC;

       }

   }

 

   return VLC_SUCCESS;

}

 

调用:

   ret = DirectXCreateSurface(vd, &front_surface, fmt, fourcc, true, false, 2);

      if (DirectXCreateSurface(vd, &surface, fmt, fourcc, false, allow_sysmem, 0))

int ret = DirectXCreateSurface(vd, &surface, fmt, 0, false, allow_sysmem, 0);

 

 

Vlc DirectX.c的结构分析:

 

OpenControl ->DirectXOpen->DirectXCreatePool->DirectCreatePicture->

1)     DirectXCreatePictureResourceYuvOverlay

2)     DirectXCreateResourceYuv

3)     DirectXCreateResourceRgb

 

SetBitmapBits

  函数功能:该函数将位图的颜色数据位设置成指定值。

  函数原型:LONG SetBitmapBits(HBITMAP hmbp, DWORD cBytes, CONST VOID (lpBits)

  参数:

  hbmp:指向要设置的位图的句柄。

  cBytes:指定参数lpBits指向的数组的字节数。

  lpBits:指向字节类型数组的指针。该数组中包含了指定位图的颜色数据。

  返回值:如果该函数执行成功,则返回值就是在设置位图位时使用的字节数;如果失败,则返回值为0

 

调用举例:

      

GetDlgItem函数:

      

RenderSample函数:

 

23)CoCreateInstance函数

STDAPI CoCreateInstance(

 REFCLSID rclsid,

 LPUNKNOWN pUnkOuter,

 DWORD dwClsContext,

 REFIID riid,

 LPVOID* ppv

);

参数:

   Rclsid:要创建的组建的CLSID

   pUnkOuter:用于聚合组件的;

   dwClsContext限定组件的执行环境;

   riid表示接口的IID;(GUID

   ppvout】表示返回的接口指针;

 

 

原创粉丝点击