GAPI简介

GAPI简介
概述
同所有的Windows平台一样,WinCE平台通过GDI实现图形和文字的绘制工作,但是由于其中存在大量的转换和判断,导致其速度相对比较慢。为了提高渲染速度,微软提出了DirectDraw和Direct3D,然而对于嵌入式系统的WinCE,在WinCE5.0版本前是不能使用的。为此,微软在WinCE3.0后提供了GAPI来直接提供了对于帧缓存和按键输入的管理功能。  
GAPI提供的函数相对较少,功能也有限,但是却足以支持各种主要的应用。基于GAPI的开发工作主要是实现对于帧缓存的数据管理。由于GAPI不提供基本的图形绘制功能,需要自己开发相关算法。
 
函数介绍
GAPI提供的函数有限,下面是主要函数列表
函数
PPC
SP
描述
X
X
准备进行绘制。
X
X
释放所有GAPI使用的资源。
X
X
释放GAPI使用的输入相关的资源, 并重新启用按键消息。
X
X
当绘制完成后调用。
X
X
返回一系列定义游戏控制方式的虚键码。
X
X
返回保存显示硬件详细信息的结构体。
X
X
返回设备是否是标准设备。
X
X
打开显示,并确保帧缓存可用。
X
X
打开非过滤按键消息模式。
X
X
继续GAPI操作。
X
X
定义一个GAPI视口。
X
X
暂停GAPI操作。
   
对于各个函数,下面作比较详细的说明:
(一)按键输入相关
(1)GXDLL_API int GXOpenDisplay ( HWND hWnd, DWORD dwFlags );
如果成功返回1,否则返回0。可以使用GetLastError得到详细错误信息。
 
(2)GXDLL_API int GXCloseInput ();
如果成功返回1,否则返回0。可以使用GetLastError得到详细错误信息。
 
(3)GXDLL_API GXKeyList GXGetDefaultKeys ( int iOptions );
获得一系列虚键,以定义对于游戏最适合的按键布局。参数iOptions为定位模式,只能取GX_NORMALKEYS(绘图定位模式)或者GX_LANDSCAPEKEYS(场景定位模式)。
struct GXKeyList
{
 short vkUp;                           //向上键
POINT ptUp;                           //按键位置坐标(相对于屏幕设备坐标)
Short vkDown;                         //向下键
POINT ptDown;                         //按键位置坐标(相对于屏幕设备坐标)
Short vkLeft;                         //向左键
POINT ptLeft;                         //按键位置坐标(相对于屏幕设备坐标)
Short vkRight;                        //向右键
POINT ptRight;                        //按键位置坐标(相对于屏幕设备坐标)
Short vkA;                             //A
POINT ptA;                             //按键位置坐标(相对于屏幕设备坐标)
Short vkB;                             //B
POINT ptB;                             //按键位置坐标(相对于屏幕设备坐标)
Short vkC;                             //C
POINT ptC;                             //按键位置坐标(相对于屏幕设备坐标)
Short vkStart;                        //开始键
POINT ptStart;                        //按键位置坐标(相对于屏幕设备坐标)
};
其它说明可以参考MSDN。
 
(二)显示相关
(1)GXDLL_API int GXOpenDisplay ( HWND hWnd, DWORD dwFlags );
其中:
hWnd 全屏时指向全屏窗口的句柄
dwFlags 指定屏幕模式选项 ,可以为:
说明
KfFullScreen
使用全屏模式 (Pocket PC).
GX_FULLSCREEN
使用全屏模式 (Smartphone).
如果成功返回1,否则返回0。可以使用GetLastError得到详细错误信息。
 
(2) GXDLL_API int GXCloseDisplay ();
如果成功返回1,否则返回0。可以使用GetLastError得到详细错误信息。
 
(3) GXDLL_API GXDisplayProperties GXGetDisplayProperties ();
返回结构体,得到所有的显示属性。结构体定义如下
struct GXDisplayProperties
{
DWORD cxWidth;                //屏幕的像素宽度
DWORD cyHeight;               //屏幕的像素高度
long cbxPitch;                //为获得向右方向下个像素位置所需要移动的字节数
long cbyPitch;                //为获得向下方向下个像素位置所需要移动的字节数
long cBPP;                     //每个像素的位数,必须是2的次方
DWORD ffFormat;               //像素格式,具体见下表
};
像素格式:
标识
说明
kfLandscape
Display is oriented on its side; 0,0 is in the lower-left corner; increasing addresses move up the screen. Generally, it is not an issue if you use cbxPitch and cbyPitch.
kfPalette
Display is palette based.
kfDirect
Display is direct mapped, no palette. This is a "helper" bit, so you do not have to check all the direct flags manually.
kfDirectInverted
Indicates the display colors are inverted. For example, with black and white colors, white is black.
kfDirect555
kfDirect565
kfDirect888
Format of a direct mapped pixel. Numbers specify bits per color in red-green-blue order. The Intel byte order is assumed: for kfDirect565, a left shift of 11 puts the low-order bits of a short or long into the red position.
特别说明:
对于每个像素的位数小于8(一个字节)的情况,为得到下一像素位置仅使用cbxPitch和cbyPitch是不够的,需要使用cBPP。下面是两个常见的情况:
unsigned char * pb;
if (cBPP < 8)                             // 每个像素4
address = pb + ((x * cBPP) >> 3) + (y * cbyPitch);
else                                       //每个像素8位或以上
address = pb + (x * cbxPitch) + (y * cbyPitch);
 
(4) GXDLL_API BOOL GXIsDisplayDRAMBuffer ();
如果是标准设备返回FALSE,如果是非标准设备返回TRUE。可以不使用此函数,但是请务必设置视口(viewport)。
 
   (5) GXDLL_API int GXSetViewport ( DWORD dwTop, DWORD dwHeight, DWORD dwReserved1, DWORD dwReserved2 );
    其中:
dwTop  视口的顶坐标再屏幕中的位置
dwHeight 视口高度
dwReserved1 保留字,必须为0
dwReserved2 保留字,必须为0
如果成功则返回1,错误则返回0,可以使用GetLastError获得错误的详细信息。此函数仅对于非标准设备有效,标准设备无效。
 
  (6)GXDLL_API void * GXBeginDraw ();
    为绘图作准备,返回显示存储区,如果不能锁定显示设备则返回NULL.
 
 (7)GXDLL_API int GXEndDraw ();
当绘制完成后调用,成功返回1,否则返回0,可以使用GetLastError获得错误的详细信息。
 
(三)状态相关
(1)GXDLL_API int GXSuspend ();
暂停所有GAPI操作。成功返回1,否则返回0,可以使用GetLastError获得错误的详细信息。当存在WM_KILLFOCUS消息时,调用GXSuspend()。不需要和GXResume ()一一对应。
 
(2)GXDLL_API int GXResume ();
继续所有GAPI操作。成功返回1,否则返回0,可以使用GetLastError获得错误的详细信息。当存在WM_SETFOCUS消息时,调用GXResume()。不需要和GXSuspend()一一对应。
 
实际使用
实际使用GAPI的过程中,可以参考下面的步骤:
(1)获取GAPI开发相关文件(SDK)
http://www.microsoft.com/mobile/developer/downloads/gapi.asp
    (2)将SDK的头文件、LIB文件、DLL文件配置到开发环境中
     把“GX.H”包含文件复制到Pocket PC SDK的“Include”目录下,如果存在,说明已经配置好了。依赖CPU(ARM/X86)类型“GX.LIB”文件复制到Pocket PC SDK的相应“Lib”目录下。为支持GAPI程序的运行把依赖CPU类型的“GX.DLL” 文件复制到Pocket PC的“Windows”目录。
 
(3)创建项目,并加入头文件gx.h和gx.lib。
#include <gx.h>
#pragma comment(lib,  "gx.lib")
 
     (4)构建框架
初始化
// 创建窗口为全屏
if (GXOpenDisplay(hWnd, GX_FULLSCREEN) == 0) {
      return FALSE;   // 创建失败
}
// 获取显示属性
g_gxdp = GXGetDisplayProperties();
 
if ( GXIsDisplayDRAMBuffer() ) {
GXSetViewport(dwTop, dwHeight, 0, 0);
}
// 初始输入
GXOpenInput();
// 获取按键及布局信息
g_gxkl = GXGetDefaultKeys(GX_NORMALKEYS);
 
结束清理
GXCloseDisplay();
GXCloseInput();
 
(5)添加必要的响应(在窗口消息处理函数中,使用MFC开发时,重载相应的消息处理函数)
 
           case WM_KILLFOCUS:
                 GXSuspend();
                 break;
 
           case WM_SETFOCUS:
                GXResume();
                break;
 
               case WM_KEYDOWN:
                     vkKey = (short)wParam;
                     if (vkKey == g_gxkl.vkUp) {
                           //处理函数
                           break;
                     }
                    
                     if (vkKey == g_gxkl.vkDown) {
                           //处理函数
                           break;
                     }
                    
                     if (vkKey == g_gxkl.vkLeft) {
                           //处理函数
                           break;
                     }
                    
                     if (vkKey == g_gxkl.vkRight) {
                           //处理函数
                           break;
                     }
                    
                     if (vkKey == g_gxkl.vkStart) {
                           //处理函数
                           break;
                     }
 
(6)在绘制函数中调用相关算法填充显示缓冲区
unsigned short * pusVideoBuffer = (unsigned short *)GXBeginDraw();
//实际图形绘制及图形缓冲区内容填充
GXEndDraw();
 
 
总结
    GAPI提供了游戏制作所需要的主要两个功能:图形和输入控制。对于图形,由于其只是简单的暴露显示缓存(帧缓存),虽然提高了程序使用的自由度和绘制的效率,但是却需要自己实现各种基本的功能,这就加大了开发的难度。
 
发布了3 篇原创文章 · 获赞 0 · 访问量 18万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览