zoukankan      html  css  js  c++  java
  • DirectDraw 学习:

     一、创建Primary Surface

    Primary Surface是当前可视的设备表面,它通过DDSAPS_PRIMARYSURFACE属性来标识。对于每一个DirectDraw对象,你只能拥有一个Primary Surface。

    创建Primary Surface时要注意,尺寸和像素格式都隐性地匹配了当前的显示模式,所以,这里就不需要你去设置这些了;如果你一定要设置的话,程序将创建失败并返回DDERR_INVALIDPARAMS,即使你提供的信息与当前的显示模式相匹配。

    下面这段代码展示了当创建primary surface时如何填充相应的 DDSURFACEDESC结构体成员的:

    1 DDSURFACEDESC ddsd; 
    2 ddsd.dwSize = sizeof(ddsd); //便于后续此结构体的扩展
    3  
    4 // Tell DirectDraw which members are valid. 
    5 ddsd.dwFlags = DDSD_CAPS; 
    6  
    7 // Request a primary surface. 
    8 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 


    当你创建primary surface后,你就可以通过method( IDirectDrawSurface::GetSurfaceDesc)来获取此主surface的尺寸和像素格式等信息。

    这里有必要说一下这个结构体DDSUFACEDESC,它呢是用来描述一张surface属性信息的,为什么首先要填充此结构体的大小呢?因为后续可能此结构体会增加成员也说不定,便于成员的扩充;而配置下面的那个dwFlags成员用来表明现在起作用的是那些成员用的。

    二、创建离屏表面(Off-Screen Surface)

    它就常用来缓存那些稍后将要位传到primary surface或者back buffer上面的bitmap图片用的。创建这种表面就需要明确的声明它的尺寸,这里一定要记得先设置成员dwFlags包含到DDSD_WIDTH 和 DDSD_HEIGHT,然后再相应的设置成员dwWidth 和 dwHeight .

    默认DirectDraw创建的表面都用的是显存,除非不合适,才会使用系统内存,但是我们也可指明,这就要设置成员dwCapsDDSCAPS_SYSTEMMEMORY 和DDSCAPS_VIDEOMEMORY二者之一;

     1 //创建前的准备工作
     2 DDSURFACEDESC ddsd; 
     3 ddsd.dwSize = sizeof(ddsd); 
     4  
     5 // Tell DirectDraw which members are valid. 
     6 ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; 
     7  
     8 // Request a simple off-screen surface, sized 
     9 // 100 by 100 pixels. 
    10 //
    11 // (This assumes that the off-screen surface that is about 
    12 // to be created will match the pixel format of the 
    13 // primary surface.)它这里的假设分辨率是和primary surface的像素格式相匹配的
    14 ddsd.dwHeight = 100; 
    15 ddsd.dwWidth = 100; 

    也可以不相匹配,但是有一个缺点:你使用系统内存时将被限制;

     1 //这里就是在一个显示模式不是8bit每像素的设备上创建一个8-bit调色板
     2 //表面所要做的准备工作
     3 memset(&ddsd, 0, sizeof(ddsd));
     4 ddsd.dwSize  = sizeof(ddsd);
     5 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
     6 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
     7 ddsd.dwHeight = 100;
     8 ddsd.dwWidth  = 100;
     9 ddsd.ddpfPixelFormat.dwSize  = sizeof(DDPIXELFORMAT);
    10 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
    11  
    12 // Set the bit depth for an 8-bit surface, but DO NOT 
    13 // specify any RGB mask values. The masks must be zero
    14 // for a palettized surface.
    15 ddsd.ddpfPixelFormat.dwRGBBitCount = 8;

    三、复合表面和翻转链(Complex Surfaces and Flipping Chains)

    何为复合表面?通过单一调用CreateSurface创建的一系列表面就是复合表面。怎么说呢,举个例吧

    1     int i = 0;
    2     do {
    3         ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];
    4         hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
    5     } while (hRet != DD_OK && (++i < PF_TABLE_SIZE));

    上面呢就是基于不用像素格式创建了多个surface的实例,这样创建出来的就是complex surfaces;

    而且使用CreateSurface时一旦指定DDSCAPS_FLIP,除了你明确指定,不然DirectDraw会隐式创建一到多个表面;

    你可以把复合表面就当作一张表面来处理,所以处理起来也没什么特别之处;

    那现在来说到翻转链,复合表面就是被用于翻转链的。通常一个primary surface和一到多个back buffers来组成一条翻转链。而且有DDSCAPS_FLIP标识创建出来的表面就表明了它也是翻转链的一组成部分;

     1 //这里是创建一个主表面翻转链时先要配置的参数
     2 DDSURFACEDESC ddsd; 
     3 ddsd.dwSize = sizeof(ddsd); 
     4  
     5 // Tell DirectDraw which members are valid. 
     6 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
     7  
     8 // Request a primary surface with a single 
     9 // back buffer 
    10 ddsd.ddsCaps.dwCaps = DDSCAPS_FLIP | 
    11 DDSCAPS_PRIMARYSURFACE; 
    12 ddsd.dwBackBufferCount = 1; 

    创建成功后就可以翻转了(primary surface和back buffer之间):

    1 hRet = g_pDDSPrimary->Flip(NULL, 0);

    如果上面的ddsd.dwBackBufferCount = 2;那么每调用一次上面的flip,就在这三个surface之间循环,这就是a triple-buffered flipping environment。下面要讲到。。。

    四、Flipping Surfaces

    这个就更有意思了。。。

  • 相关阅读:
    linux查找杀死进程
    设计模式
    解决导出excel数字为科学计数法问题
    K8S 容器运行时安全设置
    记一次dirty_ratio引起的线上事故
    配置rabbitmq
    k8s集群数据的备份和恢复
    ZK集群安装简易步骤
    Zookeeper 集群环境搭建
    Xcode
  • 原文地址:https://www.cnblogs.com/EmbeddedBoy/p/2172814.html
Copyright © 2011-2022 走看看