2013年6月24日星期一(离屏表面blitter)

2023-11-06

粗略看了一下,感觉这章也是个大餐,把所有以前的全屏过程综合起来了。

1,               总流程:SURFACE,不只是只有主缓冲和后备缓冲,还有离屏表面,离屏表面不只是一个,它装载各种位图,然后被blt到后备缓冲,再primarysurface->flip()页面切换到主表面。

2,               离屏表面blt到后备缓冲:离屏表面[(0,0), (宽度-1,高度-1)]blt到后备缓冲[(x,y),(x+宽度-1,y+高度-1 );(如果两个矩形大小不同,则缩放源图象以适应目的矩形)。

3,               创建离屏表面,标志DDSD_CAPS | DDSD_WIDTH|DDSD_HEIGHT|DDSD_CKSBLT(或者DDSD_CKDESTBLT,分别代表源色彩键或者目标色彩键),然后分别设定离屏表面的宽高、离屏表面标志DDSCAPS_OFFSCREENPLAIN|mem_flags,设定颜色键高低值,

4,               色彩键是位图所在矩形不要的颜色,分高低色,在这两者之间的颜色不要了。如果两者一样,则去掉一种颜色。8位则是这个范围的索引,或者某值的索引。如果是色彩范围,则加上标志DDCKEY_COLORSPACE。用surface->SetColorKey()设置色彩键。在blt时,则在backsurface->blt()中,加上DDBLT_KEYSRC标志。

依照惯例,先印屏

 

这是个3帧外星人图象。

结构体如下,分别说了3帧,位置和速度,目前帧,动画帧指针。

typedef struct ALIEN_OBJ_TYP

{

     LPDIRECTDRAWSURFACE7   frames[3];

     int                         x, y;

     int                         velocity;

     int                         current_frame;

     int                         counter;

 

}ALIEN_OBJ, * ALIEN_OBJ_PTR;

加了几个函数

 

int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap, LPDIRECTDRAWSURFACE7 lpdds, int cx,int cy);

 

LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, int mem_flags, int color_key);

 

int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, int x, int y,

                      int width, int height, LPDIRECTDRAWSURFACE7 dest,

                      int transparent);   

 

int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds);

设定了一个机器人数组和一个背景图片

 

ALIEN_OBJ            aliens[3];

LPDIRECTDRAWSURFACE7  lpddsbackground = NULL;

int DDraw_Draw_Surface( LPDIRECTDRAWSURFACE7 source, int x, int y, int width, int height, LPDIRECTDRAWSURFACE7 dest, int transparent = 1 )

此函数就是从源矩形到目标矩形位置(x,y)的blt,并且判断是否为透明色

代码如下

int DDraw_Draw_Surface( LPDIRECTDRAWSURFACE7 source, int x, int y, int width, int height, LPDIRECTDRAWSURFACE7 dest, int transparent = 1 )

{

     RECT          dest_rect, source_rect;

     dest_rect.left                            = x;

     dest_rect.top                        = y;

     dest_rect.right                           = x + width - 1;

     dest_rect.bottom                     = y + height - 1 ;

 

     source_rect.left                     = 0;

     source_rect.top                           = 0;

     source_rect.right                    = width - 1;

 

     if( transparent )

     {

         if( FAILED( dest->Blt( & dest_rect, source, & source_rect, ( DDBLT_WAIT | DDBLT_KEYSRC ), NULL ) ) )

              return ( 0 );

     }

     else

     {

         if( FAILED( dest->Blt( & dest_rect, source, & source_rect, ( DDBLT_WAIT ), NULL ) ) )

              return ( 0 );

     }

    

     return ( 1 );

 

}

 

将位图信息读取到一个离屏表面上。

 

int      Scan_Image_Bitmap( BITMAP_FILE_PTR bitmap, LPDIRECTDRAWSURFACE7 lpdds, int cx, int cy )

{

     UCHAR    *    source_ptr, * dest_ptr;

    

     DDSURFACEDESC2     ddsd;

     ddsd.dwSize                      = sizeof( ddsd );

     lpdds->Lock( NULL, & ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORY, NULL );

 

     cx                               = cx * ( ddsd.dwWidth + 1 ) + 1;

     cy                               = cy * ( ddsd.dwHeight + 1 ) + 1;

 

     gwidth                           = ddsd.dwWidth;

     gheight                          = ddsd.dwHeight;

 

     source_ptr                       = bitmap->buffer + cy * bitmap->bitmapinfoheader.biWidth + cx;

     dest_ptr                    = ( UCHAR * ) ddsd.lpSurface;

 

     for( int index_y = 0; index_y < ddsd.dwHeight; index_y ++ )

     {

         memcpy( dest_ptr, source_ptr, ddsd.dwWidth );

         dest_ptr               += ( ddsd.lPitch );

         source_ptr                  += bitmap->bitmapinfoheader.biWidth;

     }

     lpdds->Unlock( NULL );

 

     return ( 1 );

 

 

    

 

}

 

下面创建离屏表面,带着颜色键,memory_flags指的是放到哪个内存(系统内存DDSCAPS_SYSTEMMEMORY或者显存DDSCAPS_VIDEOMEMORY )LPDIRECTDRAWSURFACE7 DDraw_Create_Surface( int width ,int height, int mem_flags, int color_key = 0 )

{

     DDSURFACEDESC2     ddsd;

     LPDIRECTDRAWSURFACE7   lpdds;

     memset( & ddsd, 0, sizeof( ddsd ) );

     ddsd.dwSize                                    = sizeof( ddsd );

     ddsd.dwFlags                              = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

 

     ddsd.dwWidth                              = width;

     ddsd.dwHeight                             = height;

     ddsd.ddsCaps.dwCaps                            = DDSCAPS_OFFSCREENPLAIN | mem_flags;

    

     lpdd->CreateSurface( & ddsd, & lpdds, NULL );

 

     if( color_key >= 0 )

     {

         DDCOLORKEY    color_key;

         color_key.dwColorSpaceLowValue       = 0;

         color_key.dwColorSpaceHighValue      = 0;

        

         lpdds->SetColorKey( DDCKEY_SRCBLT, & color_key );

     }

     return lpdds;

 

 

}

 

下面就是写文字。

 

int Draw_Text_GDI( char * text, int x, int y, COLORREF color, LPDIRECTDRAWSURFACE7 lpdds )

{

     HDC           xdc;

     lpdds->GetDC( & xdc );

     SetTextColor( xdc, color );

     SetBkMode( xdc, TRANSPARENT );

     TextOut( xdc, x, y, text, strlen( text ) );

 

     lpdds->ReleaseDC( xdc );

 

     return 1;

 

}

 

在 GAME_MAIN()循环中,不再是缩定再复制,而是从离屏表面blt到内存中,再FLIP到主表面。在这个例子中,先把背景blt到后备缓冲,再把机器人移动位置计算好,blt机器人,最后都flip到主表面,sleep(30),

     DDraw_Draw_Surface( lpddsbackground, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, lpddsback, 0 );

     for( int index = 0; index < 3; index ++ )

     {

         aliens[index].x ++;

         if( aliens[index].x > SCREEN_WIDTH )

              aliens[index].x                  -= 80;

         if( ++ aliens[index].counter >= ( 8 - aliens[index].velocity ) )

         {

              aliens[index].counter       = 0;

              if( ++ aliens[index].current_frame > 3 )

                   aliens[index].current_frame               = 0;

         }

     }

 

     for( int index = 0; index < 3; index ++ )

     {

         DDraw_Draw_Surface( aliens[index].frames[animation_seq[aliens[index].current_frame]],

              aliens[index].x, aliens[index].y,

              72, 80,

              lpddsback );

     }

 

     while( FAILED( lpddsprimary->Flip( NULL, DDFLIP_WAIT ) ) );

 

     Sleep( 30 );

 

在game_init()中,先加载了背景图片,并逐行扫描,

     if( !Load_Bitmap_File( & bitmap, "alley8.bmp" ) )

         return ( 0 );

    

     lpddpal->SetEntries( 0, 0, MAX_COLORS_PALETTE, bitmap.palette );

     lpddsbackground                      = DDraw_Create_Surface( 640, 480, 0, -1 );

 

     UCHAR    *    image_buffer       = ( UCHAR * ) ddsd.lpSurface;

     if( ddsd.lPitch == SCREEN_WIDTH )

     {

         memcpy( ( void * ) image_buffer, ( void * ) bitmap.buffer, SCREEN_WIDTH * SCREEN_HEIGHT );

     }

     else

     {

         UCHAR    * dest_ptr             = image_buffer;

         UCHAR    * src_ptr          = bitmap.buffer;

 

         for( int y = 0; y < SCREEN_HEIGHT; y ++ )

         {

              memcpy( ( void * ) dest_ptr, ( void * ) src_ptr, SCREEN_WIDTH );

 

              dest_ptr               += ddsd.lPitch;

              src_ptr                     += SCREEN_WIDTH;

         }

     }

 

     lpddsbackground->Unlock( NULL );

     Unload_Bitmap_File( & bitmap );

接下来产生随机数,

//产生随机数

     srand( GetTickCount() );

再加载三个机器人。

     aliens[0].x                          = rand() % SCREEN_WIDTH;

     aliens[0].y                          = 116 -72;

     aliens[0].velocity               = 2 + rand() % 4;

     aliens[0].current_frame          = 0;

     aliens[0].counter                = 0;

 

     aliens[1].x                          = rand() % SCREEN_WIDTH;

     aliens[1].y                          = 246 - 72;

     aliens[1].velocity               = 2 + rand() % 4;

     aliens[1].current_frame          = 0;

     aliens[1].counter                = 0;

 

     aliens[2].x                          = rand() % SCREEN_WIDTH;

     aliens[2].y                          = 382 - 72;

     aliens[2].velocity               = 2 + rand() % 4;

     aliens[2].current_frame          = 0;

     aliens[2].counter                = 0;

 

     for( int index = 0; index < 3; index ++ )

     {

          aliens[0].frames[index]     = DDraw_Create_Surface( 72, 80, 0 );

         Scan_Image_Bitmap( & bitmap, aliens[0].frames[index], index, 0 );

     }

     Unload_Bitmap_File( & bitmap );

 

     for( int index = 0; index < 3; index ++ )

         aliens[1].frames[index]     = aliens[2].frames[index]   = aliens[0].frames[index];

 

 

     改掉几个笔误,终于运行OK了

现在看看如何封装这几个函数,到引擎中。

 

 

机器人结构属于特殊,故在main()函数里面写。

     此时,出现问题,该问题是

在ddraw_init()中的

DDSCAPS2      ddscaps;,实际上,不应该这样弄,而是用ddsd.ddscaps,否则不是一回事。解决方法,直接删除变量ddscaps即可。

另外,ddsd随时使用,随时分配。.

 

现在进行下T3DLIB结合,到此时,应该是全屏图形有个大概了结了。

先看下,initdraw(),还有哪些没有弄进去的。发现除了窗口外,没有了。

DDraw_Attach_Clipper()一致了,

DDraw_Create_Surface()在设置色彩键时,更科学了,更改后一致了。

DDraw_Flip()一致

DDraw_Fill_Surface()基本一致

DDraw_Lock_Surface()一致。

DDraw_Unlock_Surface()一致。

DDraw_Lock_Back_Surface()一致,

DDraw_Lock_Primary_Surface()一致

DDraw_Unlock_Back_Surface()一致。

DDraw_Unlock_Primary_Surface()一致

 

Ddraw()接口函数,只剩下DDRAW_INIT()和DDRAW_SHUTDOWN()的窗口部分了。

 

位图部分:

Load_Bitmap_File()一致。

Flip_Bitmap()一致。

 

 

Draw_Text_GDI()一致

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2013年6月24日星期一(离屏表面blitter) 的相关文章

  • 开关电源环路稳定性分析(05)-传递函数

    大家好 这里是大话硬件 经过前面4篇文章的梳理 估计很多人已经等不及了 什么时候可以开始环路的分析 为了尽快进入到大家关心的部分 这一讲我们正式进入环路分析的第一部分 传递函数 传递函数 简单的理解就是输入和输出之间的关系 为了方便我们仅仅
  • 【linux】linux 基础正则表达式、字符串截取、比较、分支、while循环

    1 概述 正则表达式用来在文件中匹配符合条件的字符串 正则是包含匹配 grep awk sed等命令可以支持正则表达式 通配符用来匹配符合条件的文件名 通配符是完全匹配 ls find cp这些命令不支持正则表达式 所以只能使用shell自
  • IDEA中设置vue vue3+ts项目的@跳转

    网上基本都是这个方法但是试了对我不适用 idea vue项目通过 跳转 vue设置完 映射路径之后在IDEA中无法跳转 兜兜转转原来只需 在tsconfig json中加入如下配置就行 compilerOptions baseUrl pat
  • leetcode 5749. 邻位交换的最小次数

    邻位交换的最小次数 给你一个表示大整数的字符串 num 和一个整数 k 如果某个整数是 num 中各位数字的一个 排列 且它的 值大于 num 则称这个整数为 妙数 可能存在很多妙数 但是只需要关注 值最小 的那些 例如 num 54893
  • 使用stylecop 规范C#编码

    可直接在VS操作完成 简单易懂 第一步 打开VS 第二步 安装软件 第三步 规则修改 第四步 规则生效 stylecop 是代码静态检查分析的一大利器 可以自定义检查规则 安装操作使用方便 相信很多写C 的朋友都会使用的到 下面详细介绍安装
  • XP下采用DirectShow采集摄像头

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 需要示例源码的请独自联系我 前提 摄像头能正常工作 摄像头有创建directshow filter 即 大家可以对比我的另一
  • 数据规约

    主成分的计算步骤 主成分的代码实现 设置工作空间 把 数据及程序 文件夹拷贝到F盘下 再用setwd设置工作空间 setwd F 数据及程序 chapter4 示例程序 数据读取 inputfile lt read csv data pri

随机推荐

  • z系列主板能装服务器系统吗,Intel Z390主板搭配8代酷睿现身:还能安装WIN7系统吗?...

    Intel今年为发烧友带来了最多18核心的Core X系列 搭配X299顶级主板 主流领域则有最多6核心的八代酷睿Coffee Lake S 搭配Z370主板 但坑爹的是 尽管八代和六七代酷睿都是LGA1151接口 但却被故意整成不兼容 因
  • 基于power bi上手业务数据可视化

    分析背景 偶然得到一份关于某连锁火锅品牌在2020年1月 8月的线上平台业务数据 如下图 心想正好利用这份数据 模拟实际业务中基于数据库与bi工具 实践开发可视化图表 一开始考虑用tableau 因为在大学跟刚工作的时候曾系统学习使用过 但
  • 栈的链性表的c语言实现方式 linkstack.h 和 linkstack.c

    linkstack h 文件 ifndef LINK STACK H define LINK STACK H include
  • 数据库 关系代数 投影概念理解

    关系R上的投影是从R 中选择出若干属性列组成新的关系 记作 A R t A t R 其中A 为R 中的属性列 投影操作是从列的角度进行的运算 例3 查询学生的姓名和所在系 即求Student关系在学生姓名和所在系两个属性上的投影 Sname
  • k8s集群新增节点

    如何动态的为k8s集群增加worknode节点 本文将详细介绍 kubeadm搭建k8集群详见 https blog csdn net wangqiubo2010 article details 101203625 一 VMWare xSp
  • 每日算法题(Day5)----取石子

    题目描述 有一种有趣的游戏 玩法如下 玩家 2 人 道具 N 颗石子 规则 游戏双方轮流取石子 每人每次取走若干颗石子 最少取 1 颗 最多取 K 颗 石子取光 则游戏结束 最后取石子的一方为胜 假如参与游戏的玩家都非常聪明 问最后谁会获胜
  • Linux Kafka 2.11-1.1.1 安装搭建

    Kafka是最初由Linkedin公司开发 是一个分布式 支持分区的 partition 多副本的 replica 基于zookeeper协调的分布式消息系统 它的最大的特性就是可以实时的处理大量数据以满足各种需求场景 比如基于hadoop
  • iframe无边框实现

  • Android 11 绕过反射限制

    1 问题出现的背景 腾讯视频在集成我们 replay sdk 的时候发现这么个错误 导致整个 db mock 功能完全失效 Accessing hidden field Landroid database sqlite SQLiteCurs
  • LeetCode1477-找两个和为目标值且不重叠的子数组

    给你一个整数数组 arr 和一个整数值 target 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target 可能会有多种方案 请你返回满足要求的两个子数组长度和的 最小值 请返回满足要求的最小长度和 如果无法找到这样的
  • 餐馆点餐系统(Java GUI + mysql)

    餐馆点餐系统 Java GUI mysql 开发环境 eclipse mysql 开发语言 Java SQL 本系统采用MVC模式开发的 果冻点餐系统 适合Java初级选手学习 本系统实现了用户注册登录 点餐 商家管理订单等一系列功能 首先
  • crc32碰撞_hash碰撞的概率和可能性比你直觉中大得多

    注 这篇文章源自我10年前写的博客 今天看到有人谈密码安全的 再发一遍和大家讨论下 我发现哪怕10年后 这文章也没过时 很多人还是没拎清 冲突概率和样本空间的关系 前段时间跟某大牛叽歪的时候 被提到我写的一篇文章 用CRC32实现短网址的一
  • 基于Spring Boot的酒店客房管理系统

    文章目录 项目介绍 主要功能截图 后台 前台 部分代码展示 设计总结 项目获取方式 作者主页 超级无敌暴龙战士塔塔开 简介 Java领域优质创作者 简历模板 学习资料 面试题库 关注我 都给你 文末获取源码联系 项目介绍 基于Spring
  • 奇偶校验c语言ascii,奇偶校验(parity check)

    parity check 奇偶校验 N a check made of computer data to ensure that the total number of bits of value 1 or 0 in each unit o
  • 查看Linux的用户权限(转载)

    转 Linux查看用户及其权限管理 查看用户 请打开终端 输入命令 who am i 或者 who mom likes 输出的第一列表示打开当前伪终端的用户的用户名 要查看当前登录用户的用户名 去掉空格直接使用 whoami 即可 第二列的
  • ASP.NET MVC - Model Binding

    Http Request 到Input Model的绑定按照model的类型可分为四种情况 Primitive type Collection of primitive type Complex type Collection of com
  • ROC曲线-阈值评价标准

    ROC曲线指受试者工作特征曲线 接收器操作特性曲线 receiver operating characteristic curve 是反映敏感性和特异性连续变量的综合指标 是用构图法揭示敏感性和特异性的相互关系 它通过将连续变量设定出多个不
  • UE4导入3dmax模型并在场景中添加第三人称角色

    1 3dmax安装Datasmith插件 插件下载位置 https www unrealengine com zh CN datasmith plugins 2 3dmax导出模型 3 UE4导入模型 从3dmax导出datasmith的格
  • Pytorch模型保存与加载模型继续训练

    1 网络模型定义与模型参数保存 定义网络模型与基本参数 以及模型训练和模型保存 使用torch save 方法保存模型 在save dict 中可以保存epoch model optimizer scheduler loss等参数 my n
  • 2013年6月24日星期一(离屏表面blitter)

    粗略看了一下 感觉这章也是个大餐 把所有以前的全屏过程综合起来了 1 总流程 SURFACE 不只是只有主缓冲和后备缓冲 还有离屏表面 离屏表面不只是一个 它装载各种位图 然后被blt到后备缓冲 再primarysurface gt fli