游戏编程之十一 图像页CPICPAGE介绍

简介: 游戏编程之十一 图像页CPICPAGE介绍

 图像页指的是内存中保存图像数据的各种表面,屏幕缓存,各种图片数据,窗口界面的界面数据等,不要只依靠DirectX的表面,最好单独用一个对象来管理这些内容,避免直接与DirectX打交道,这样改变引擎和移植到别的操作系统的工作量会小得多.

 

 在我们的引擎设计中,CPICPAGE是一个功能强大而且扩充性极好的对象,比如我们不想使用DirectX表面,而想自己设计一种表面结构,游戏的其余部分不须任何改变,只要从CPICPAGE发展出CSELFPAGE的对象即可.象我知道的"腾图"公司的余雪松和吴冬黎(两个非常优秀的程序师,我从他们那里收益非浅,他们也是国内比较早的"xx"游戏站点的主人)就有一套自己的功能强大的图像表面,他们不使用DirectX表面.

 

 游戏对图像的操作一般不是直接对具体类型的表面操作,而是调用他们的根对象CPICPAGE.

 

   在我们的游戏引擎中,图像页的结构是这样的:

 CPICPAGE

   CBitmapPage  //标准windows的位图,如果使用16M色模式,对于一些不常更新的图像,使用

          //16M色的DirectXDraw是种巨大的浪费,比如背景,我们可以保存一块比视

                //口大的DirectXDraw表面作为背景区,只在一定条件下才将256色原图

                //CBitmapPage写入背景区(使用任意调色版可保证非常高的图像质量,特别

                //是使用Potoshop 5.0或Animatorfor Window 作为真彩转换256色工具,颜

                //色失真极小),平时游戏读的是高速的DirectXDraw背景表面

   CDirectXDrawPage//标准的DirectXDraw表面,

   CGifPage//Gif动画表面,随着时间自动修改图像内容,继承CDirectXDrawPage

   CAviPage//AVi动画表面,随着时间自动修改图像内容,继承CDirectXDrawPage,可以带自己线程

   CFlcPage//Flc动画表面,随着时间自动修改图像内容,继承CDirectXDrawPage  

目前我们只设计了这些类型,但可以供据需要随时扩充.

class CPICPAGE 
{ 
protected: 
      char   picStyle;//图像类型 
      BOOL   CanWrite;//是否可以写 
      int    picWidth,picHeight;//尺寸 
      DWORD  activeMode;//静态,可释放, 
      unsigned short useTimeMark;//使用时间标记,如果长时间未使用,则保存到虚拟文件中 
      char   *programeBuf;//可以用代码来控制图像的改变, 
                         //我们支持脚本语言对图像进行特殊控制 
      char  *lpImgBuf;//图像内存 
      long  imgBufLen;//内存长度 
      HDC    hDC;//标准设备句柄,指对CDirectXDrawPage和它的继承对象有效 
      BOOL   hasChg;//图像内容是否已经改变 
      BOOL   UseClip;//是否设定显示剪裁区 
      RECT   clipRc;//显示剪裁区 
public: 
      CPICPAGE(); 
      ~CPICPAGE(); 
      virtual  void Destroy(void); 
      char  GetPicStyle(void); 
      BOOL  GetSize(int *w,int *h); 
      void  GetRect(RECT *lpRc); 
      char  *GetImgBuf(void); 
      BOOL  Load(char *lpFileName,long  startOfs=0);从文件中读取内容 
      virtual   BOOL  LoadFile(FILE *lpFileHandle,long startOfs=0){return FALSE;}; 
      virtual   void  BeginDraw(){};//如果是标准的DirectXDraw表面,再进行 
                                    //Window的标准图形读写时要获得HDC,如果是连续写,不要 
                                    //马上释放,反复申请和释放HDC会大大降低速度 
      virtual   void  EndDraw(){};//终止Window的标准图形读写,释放HDC 
      virtual   HDC   GetHDC(void){return NULL;}; 
      virtual   void  Line(int bx,int by,int ex,int ey,COLORREF rgb); 
      virtual   void  drawStrgs(char *strg,short bx,short by,char drawBox,short choice); 
      virtual   void  Draw(RECT *lpRc,COLORREF *lpCr,char drawStyle,DWORD otherMess); 
      virtual   void  Fill(RECT *rc=NULL,COLORREF colorFill=0); 
      virtual   void  DrawRect(RECT *rc,COLORREF colorLeft,COLORREF colorRight, 
          COLORREF colorFill,COLORREF colorKey, DWORD drawStyle); 
      virtual   BOOL BltInView( CPICPAGE *lpDec, 
                 int srcInX, int srcInY,     //x,y是souRectBlt相对于整个des表面的位置 
                DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源图片目标区 
                RECT *lpFillRect=NULL)  {return FALSE;}; 
      virtual   BOOL  FillRect(CPICPAGE *lpSou,RECT *lpSouRect=NULL,RECT lpDecRect=NULL) 
                        {return FALSE;}; 
      virtual   BOOL  Scroll(int scrollX,int scrollY,RECT *lpRect=NULL){return FALSE;}; 
      virtual   BOOL ChgSize(int chgWidth,int chgHeight,int mode=0) 
                         {return FALSE;};//0 设置尺寸,1 改变尺寸 
       virtual   BOOL HasLost(void){return FALSE;}; //已经丢失图像数据 
       virtual   BOOL Scroll(int scrollX,int scrollY,COLORREF fillColor=0, 
          RECT *lpScrollRc=NULL){return FALSE;}; 
      virtual   void TimeTrace(vodi);//时间跟踪,动画可以在此时更改自己的图像 
}; 
class CDIBPAGE:public CPICPAGE 
{ 
   HDIB hDIB; 
   LPSTR lpDIBHdr; 
   unsigned aLineByte; 
   BYTE biBitCount; 
   char  style; 
   char *LpGetIMG(void); 
public: 
      CDIBPAGE(){picStyle=BMPPIC;}; 
      BOOL Creat(int width,int height,DWORD mode=0); 
      BOOL SetBmp(char *_lpImgBuf); 
      BOOL LoadFile(FILE *lpFileHandle,long  startOfs=0); 
      BOOL StretchDIBits(HDC  hDC,LPRECT  lpDCRect,LPRECT lpDIBRect,DWORD dwRop,BOOL canChg=FALSE); 
      BOOL Blt(HDC  hDC,LPRECT  lpDCRect,LPRECT  lpDIBRect,DWORD dwRop=SRCCOPY); 
      virtual   BOOL BltInView( CPICPAGE *lpDec, 
     int   srcInX, int srcInY,//x,y是souRectBlt相对于整个des表面的位置 
     DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源图片目标区 
     RECT *lpFillRect=NULL); 
}; 
class CDirectPAGE:public CPICPAGE 
{ 
      LPDIRECTDRAWSURFACE surf; 
public: 
      CDirectPAGE(){surf=NULL;picStyle=DIRECTPIC;} 
      ~CDirectPAGE(); 
      void Destroy(void); 
      BOOL  Creat(int width,int height,DWORD mode=0); 
      LPDIRECTDRAWSURFACE GetSurface(void) {EndDraw();return surf;} 
      virtual BOOL LoadFile(FILE *lpFileHandle,long  startOfs=0); 
      HDC     GetHDC(void); 
      void    BeginDraw(); 
      void    EndDraw(); 
      virtual   BOOL BltInView( CPICPAGE *lpDec, 
     int   srcInX, int srcInY,//x,y是souRectBlt相对于整个des表面的位置 
     DWORD flap=0, RECT *DecView=NULL, RECT *souRectBlt=NULL,//源图片目标区 
     RECT *lpFillRect=NULL); 
      void  Fill(RECT *rc=NULL,COLORREF colorFill=0); 
      BOOL  Scroll(int scrollX,int scrollY,COLORREF fillColor=0, RECT *lpScrollRc=NULL); 
}; 


这里面我只列举了一些常用的接口,另外还有一些象带alpha通道的BLT,line,以及带亮度的BLT,Line等,可以供据游戏的要求随时扩充.对标准DirectXDraw表面,我们可以在开始时使用一些window的库函数,然后如果时间允许再改为自己的速度更快的函数.系统设计时一般先完成功能,中后期才作优化,不要一开始马上陷入过多的技术细节,除非是决定系统成败的关键的速度要求.

 

 

 通过二,三章的工作,现在系统便可以显示一些图像和动画了,显示部分有关的内容基本就完成,下一章介绍资源管理.声音部分在最后介绍,因为那部分实现起来比较简单.  

目录
相关文章
|
2月前
|
Web App开发 Python
DrissionPage 实战:极简壁纸爬取之旅
本文介绍了如何使用DrissionPage工具自动化爬取极简风格的壁纸图片。通过简单的环境搭建和代码实现,展示了从访问目标网站、定位图片元素到下载保存的全过程。文中还提供了详细的代码示例,帮助读者快速上手。
110 4
图库,设计类软件,App视频截图软件,外加设计图库,在你截取视频就能够实现图片收录,通过设计类网站后台控制系统,可以提前设置好,统计的分类内容,定义好分类,自动收录图片,再将截图汇总整理展示
图库,设计类软件,App视频截图软件,外加设计图库,在你截取视频就能够实现图片收录,通过设计类网站后台控制系统,可以提前设置好,统计的分类内容,定义好分类,自动收录图片,再将截图汇总整理展示
图库,设计类软件,App视频截图软件,外加设计图库,在你截取视频就能够实现图片收录,通过设计类网站后台控制系统,可以提前设置好,统计的分类内容,定义好分类,自动收录图片,再将截图汇总整理展示
|
存储 监控 数据库
大师学SwiftUI第18章Part2 - 存储图片和自定义相机
在前面的示例中,我们在屏幕上展示了图片,但也可以将其存储到文件或数据库中。另外有时使用相机将照片存储到设备的相册薄里会很有用,这样可供其它应用访问。UIKit框架提供了如下两个保存图片和视频的函数。 •
414 0
|
8月前
|
XML 存储 开发框架
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
c#教你网站数据轻松解析抓取,HtmlAgilityPack解析的奇妙之处
254 0
基于PP-Structure急速 30行代码实现表格识别
基于PP-Structure急速 30行代码实现表格识别
621 0
基于PP-Structure急速 30行代码实现表格识别
|
缓存
《QT从基础到进阶·二十二》QGraphicsView显示大量图形项item导致界面卡顿的解决办法
《QT从基础到进阶·二十二》QGraphicsView显示大量图形项item导致界面卡顿的解决办法
725 0
《QT从基础到进阶·十二》QPixmap.load加载图片不更新问题
《QT从基础到进阶·十二》QPixmap.load加载图片不更新问题
287 0
|
数据挖掘 Windows
【Windows 逆向】CE 地址遍历工具 ( CE 结构剖析工具 | 人物数据内存结构 | 人物三维坐标数据分析 )
【Windows 逆向】CE 地址遍历工具 ( CE 结构剖析工具 | 人物数据内存结构 | 人物三维坐标数据分析 )
440 0
【Windows 逆向】CE 地址遍历工具 ( CE 结构剖析工具 | 人物数据内存结构 | 人物三维坐标数据分析 )
|
Android开发 索引
第二十四章:页面导航(十二)
事件在方法调用方法和消息中心通信方法中,信息页面需要知道主页的类型。 如果可以从不同类型的页面调用相同的信息页面,这有时是不合需要的。这个问题的一个解决方案是info类实现一个事件,这就是DataTransfer3中采用的方法。
516 0
|
Android开发 索引
第二十四章:页面导航(十一)
消息中心您可能不喜欢两个页面类直接相互调用方法的想法。 它似乎适用于小样本,但对于具有大量类间通信的大型程序,您可能更喜欢一些不需要实际页面实例的更灵活的东西。这样的工具是Xamarin.Forms MessagingCenter类。
560 0