• DDraw笔记使用blitter进行内存填充


    使用blitter进行内存填充

    前面的内存填充都是利用memset()或memcpy()进行的。主要是用cpu进行的,有点慢。特别是当表面非线性时,就得一行一行的填充,就更慢了。

    利用blitter我们可以直接填充或移动大块VRAM和DDraw表面,速度比较快。有两个函数如下:

    IDIRECTDRAWSURFACE7::Blt()
    IDIRECTDRAWSURFACE7::BltFast()

    Blt

    原型如下:

    HRESULT Blt(LPRECT lpDestRect,         // 目标区域,NULL为整个表面
    LPDIRECTDRAWSURFACE7 lpDDSrcSurface,   // 源表面
    LPRECT lpSrcRect,              // 源区域
    DWORD dwFlags,              // 控制标志,见下表
    LPDDBLTFX lpDDBltFx);            // DDBLTFX结构,见下面

     

    Blt()函数dwFlags参数的控制标志

    描述

    DDBLT_COLORFILL

    使用DDBLTFX结构中的dwFillColor成员作为用来填充在目标表面上目标矩形区域的RGB颜色

    DDBLT_DDFX

    使用DDBLTFX结构中的dwDDFX成员指出使用该blit的效果

    DDBLT_DDROPS

    使用DDBLTFX结构中的dwDDROP成员 指出非win32 api部分的光标操作(ROP)

    DDBLT_DEPTHFILL

    使用DDBLTFX结构中的dwFillDepth成员作为 填充到目标尝试缓冲(z-buffer)表面的目标矩形框的深度值

    DDBLT_KEYDESTOVERRIDE

    使用DDBLTFX结构中的ddckDestColorkey成员作为目标表面的色彩键

    DDBLT_KEYSRCOVERRIDE

    使用DDBLTFX结构中的ddckSrcColorkey 成员作为源表面的色彩键

    DDBLT_ROP

    在本次blit的ROP(光栅操作)中使用DDBLTFX结构中的dwROP成员。这些ROP和Win32 API中定义相同

    DDBLT_ROTATIONANGLE

    使用DDBLTFX结构中的dwRotationAngle 成员作为应该表面的旋转角(以1/100度为单位 )。这只被硬件支持,HEL(硬件仿真层)不能进行这样的旋转。

    DDBLT_KEYDEST

    使用和目标表面相关联的色彩关键字

    DDBLT_KEYSRC

    使用和源表面相关联的色彩关键字

    DDBLT_ASYNC

    依接收次序通过FIFO(先进先出)异步地执行转换,或FIFO硬件中没有足够的空间,则该调用失败,它速度快,但有点冒险,应当编写出错处理逻辑以合理地使用该标志

    DDBLT_WAIT

    等待直到blit能被执行,即使blitter正忙也不返回错误信息DDERR_WASSTILLDRAWING

     

    最后一个参数是一个结构如下:

    typedef struct _DDBLTFX
    {
    DWORD dwSize;
    // size of structure
    DWORD dwDDFX; // FX operations
    DWORD dwROP; // Win32 raster operations
    DWORD dwDDROP; // Raster operations new for DirectDraw
    DWORD dwRotationAngle; // Rotation angle for blt
    DWORD dwZBufferOpCode; // ZBuffer compares
    DWORD dwZBufferLow; // Low limit of Z buffer
    DWORD dwZBufferHigh; // High limit of Z buffer
    DWORD dwZBufferBaseDest; // Destination base value
    DWORD dwZDestConstBitDepth; // Bit depth used to specify Z constant for destination
    union
    {
    DWORD dwZDestConst;
    // Constant to use as Z buffer for dest
    LPDIRECTDRAWSURFACE lpDDSZBufferDest; // Surface to use as Z buffer for dest
    } DUMMYUNIONNAMEN(1);
    DWORD dwZSrcConstBitDepth;
    // Bit depth used to specify Z constant for source
    union
    {
    DWORD dwZSrcConst;
    // Constant to use as Z buffer for src
    LPDIRECTDRAWSURFACE lpDDSZBufferSrc; // Surface to use as Z buffer for src
    } DUMMYUNIONNAMEN(2);
    DWORD dwAlphaEdgeBlendBitDepth;
    // Bit depth used to specify constant for alpha edge blend
    DWORD dwAlphaEdgeBlend; // Alpha for edge blending
    DWORD dwReserved;
    DWORD dwAlphaDestConstBitDepth;
    // Bit depth used to specify alpha constant for destination
    union
    {
    DWORD dwAlphaDestConst;
    // Constant to use as Alpha Channel
    LPDIRECTDRAWSURFACE lpDDSAlphaDest; // Surface to use as Alpha Channel
    } DUMMYUNIONNAMEN(3);
    DWORD dwAlphaSrcConstBitDepth;
    // Bit depth used to specify alpha constant for source
    union
    {
    DWORD dwAlphaSrcConst;
    // Constant to use as Alpha Channel
    LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // Surface to use as Alpha Channel
    } DUMMYUNIONNAMEN(4);
    union
    {
    DWORD dwFillColor;
    // color in RGB or Palettized
    DWORD dwFillDepth; // depth value for z-buffer
    DWORD dwFillPixel; // pixel value for RGBA or RGBZ
    LPDIRECTDRAWSURFACE lpDDSPattern; // Surface to use as pattern
    } DUMMYUNIONNAMEN(5);
    DDCOLORKEY ddckDestColorkey;
    // DestColorkey override
    DDCOLORKEY ddckSrcColorkey; // SrcColorkey override
    } DDBLTFX;

    粗体为常用的字段。

    代码如下:源代码下载

    int MainGame()
    {
    if (window_closed)
    return 0;

    if (KEYDOWN(VK_ESCAPE))
    {
    ::PostMessage(main_window_handle, WM_CLOSE,
    0, 0);
    window_closed
    = 1;
    }

    DDBLTFX ddbltfx;
    DDRAW_INIT_STRUCT(ddbltfx);
    ddbltfx.dwFillColor
    = _RGB16BIT565(rand()%256, rand()%256, rand()%256);

    // 随便产生一个矩形区域
    RECT dest_rect;
    dest_rect.left
    = rand()%SCREEN_WIDTH;
    dest_rect.top
    = rand()%SCREEN_HEIGHT;
    dest_rect.right
    = rand()%SCREEN_WIDTH;
    dest_rect.bottom
    = rand()%SCREEN_HEIGHT;

    // blitter
    if (FAILED(lpddsprimary->Blt(&dest_rect, // 目标区域,NULL为整个表面
    NULL, // 源表面
    NULL, // 源区域
    DDBLT_COLORFILL | DDBLT_WAIT, // 控制标志
    &ddbltfx))) // DDBLTFX结构
    {
    return 0;
    }

    Sleep(
    500);

    return 1;
    }

    运行效果

    从一个表面向另一个表面复制位图:源代码下载

    int MainGame()
    {
    if (window_closed)
    return 0;

    if (KEYDOWN(VK_ESCAPE))
    {
    PostMessage(main_window_handle,WM_CLOSE,
    0,0);
    window_closed
    = 1;
    }

    // 随机生成一个源区域
    RECT rectSrc;
    rectSrc.left
    = rand()%SCREEN_WIDTH;
    rectSrc.top
    = rand()%SCREEN_HEIGHT;
    rectSrc.right
    = rand()%SCREEN_WIDTH;
    rectSrc.bottom
    = rand()%SCREEN_HEIGHT;

    // 随机生成一个目标区域
    RECT rectDst;
    rectDst.left
    = rand()%SCREEN_WIDTH;
    rectDst.top
    = rand()%SCREEN_HEIGHT;
    rectDst.right
    = rand()%SCREEN_WIDTH;
    rectDst.bottom
    = rand()%SCREEN_HEIGHT;

    // blitter
    if (FAILED(lpddsprimary->Blt(&rectDst,
    lpddsback,
    &rectSrc,
    DDBLT_WAIT,
    NULL)))
    {
    return 0;
    }

    Sleep(
    500);

    return 1;
    }

    BltFast

    原型如下:

    HRESULT BltFast(
    DWORD dwX,                 
    // 目标表面x坐标
    DWORD dwY,                 // 目标表面y坐标
    LPDIRECTDRAWSURFACE7 lpDDSrcSurface, // 源表面
    LPRECT lpSrcRect,             // 源区域
    DWORD dwTrans);              // blitter操作类型

    BltFast()的blitter操作控制标志

    描述

    DDBLTFAST_SRCCOLORKEY

    指定一次使用源色彩的透明blit

    DDBLTFAST_DESTCOLORKEY

    指定一次使用目标色彩的透明blit

    DDBLTFAST_NOCOLORKEY

    指定一次不使用透明的标准blit。在一些硬件上速度 要快一些。在HEL上速度更快。

    DDBLTFAST_WAIT

    当图形变换器正忙时,强制blitter等待,并且 不返回DDERR_WASSTILLDRAWING。直到该blit能被执行,或者发生严重错误时,BltFast()才返回。

     

    何时用Blt,何时用BltFast

    BltFast比Blt快一些,但是Blt带有裁剪器,而BltFast没有。

    所以需要裁剪时用Blt,不需要要裁剪时用BltFast。


    2011.06.08 方煜宽

    转载请保留下面链接

     http://www.cnblogs.com/fangyukuan/archive/2011/06/08/2075907.html 


  • 相关阅读:
    几种常见SQL分页方式效率比较(转)
    jquery mobile开发笔记之Ajax提交数据(转)
    php 更新array键值
    PHP使用UTF8编码读取ACCESS的乱码问题解决方案(转)
    PropertyGrid控件动态生成属性及下拉菜单 (转)
    山穷水尽出高手,九死一生见功夫
    将MYSQL的GBK数据库转成_UTF-8数据库的简便方法
    CRM销售管理功能
    基于.net开发chrome核心浏览器【一】(转)
    1.Two Sum
  • 原文地址:https://www.cnblogs.com/fangyukuan/p/2075907.html
Copyright © 2020-2023  润新知