|
来试试新鲜出炉的PainterEngine吧,开源,简单,易用
PainterEngine导引
PainterEngine是一个基于C语言编写的完全开源的图形游戏引擎。你可以在这里下载到PainterEngine的完整代码及相关帮助文档
PainterEnginematrixcascade/PainterEnginePainterEngine独立于操作系统、开发工具链及运行时环境,这意味着PainterEngine可以被移植到任意提供C语言编译环境的平台中,包括但不限windows,linux,android,ios及一系列单片机裸机环境中。
PainterEngine的设计理念精简,学习曲线平缓,你只需要花很少的时间在引擎的学习上,耗费极少的学习时间成本,快速实现你需要的功能。
PainterEngine 目录结构
*Core:PainterEngine基础算法库
*Kernel:PainterEngine模块代码库(基于Core)
Architecture:PainterEngine功能代码库(基于Kernel)
Platform:平台兼容层代码库
Support:相关支持、帮助文档
PainterEngine开发环境
Windows
Visual Studio
1.启动visual studio
2.菜单--文件—新建—项目—创建一个空项目
3.在项目上右键---添加---新建筛选器—命名为PainterEngine(非必须步骤,可跳过)
4.将PainterEngine目录下kernel、core、architecture三个文件夹(所有文件拖到新建的筛选器中,如跳过了步骤3可直接拖到项目中)
5.进入PainterEngine/platform,因为我们开发的是windows程序,因此将windows目录的同样拖动到筛选器中。
6.进入PainterEngine/platform/framework,复制当中的所有文件
7.挑一个你喜欢的地方,新建一个文件夹(作为你的工程代码目录),将上面的文件复制到这个文件夹中(例如D盘中我新建了一个My First PainterEngine Project作为示范)
8.将复制的文件黏贴到这个文件夹中,并将这些文件拖动到项目中
9.选中项目,点击菜单项目—属性
10.将配置改成所有配置---VC++目录---包含目录
11.将PainterEngine的所在目录,windows平台库目录和你工程代码目录添加进来,然后点击确定
12.现在,你可以试运行第一个PainterEngine项目了
MingW(CLoin,Visual Studio code)
1.下载并安装mingw,设置环境变量(请参照mingw相关教程,过程略).
进入PainterEngine/platform/framework,复制当中的所有文件
2.挑一个你喜欢的地方,新建一个文件夹(作为你的工程代码目录),将上面的文件复制到这个文件夹中(例如D盘中我新建了一个MyPainterEngineMingWProject作为示范,注意文件夹名不要带有空格)
3.进入PainterEngine\platform\makefile目录,用记事本打开makefile文件
4.修改makefile的配置,包含生成exe的路径,工程代码的路径和PainterEngine的路径
其中target为生成exe的路径
project_path为工程代码的路径
painterengine_path 为PainterEngine路径
(以上路径注意不要带有空格)
5.双击PainterEngine\platform\makefile\build.bat,编译运行
Android
Android studio
1.打开android studio,File---new—new project—选择No Activity然后点击Next
2.选择一个你喜欢的位置,创建项目文件(以D:\MyPainterEngineForAndroid为例),点击finish
3.在项目目录的app中点击右键,选择show in explorer
4.依次进入\app\src\main
5.打开PainterEngine目录下的platform/android,将AndroidManifest.xml和CMakeList覆盖和复制到\app\src\main
5. 进入PainterEngine/platform/framework,复制当中的所有文件
6.挑一个你喜欢的地方,新建一个文件夹(作为你的工程代码目录),将上面的文件复制到这个文件夹中(例如D盘中我新建了一个PainterEngineProject作为示范,注意文件夹名不要带有空格)
7.打开\app\src\main\CMakeLists.txt,
将
PAINTERENGINE_DIR 修改为你的PainterEngine路径
PAINTERENGINE_PROJECT_DIR 修改为你的工程代码目录路径
8.回到Android Studio,选中App,右键点击Link C++ Project With Gradle
9.选择之前配置好的CMakeLists.txt
10.在Android Studio中按下Ctrl+F9或点击菜单栏上的build
编译成功,现在你可以连接手机运行PainterEngine的Android应用了
PainterEngine基础框架结构
Application 基础架构
PainterEngine architecture包含着PainterEngine默认的运行时配置与执行框架,使用PainterEngine的框架体系开发PainterEngine程序是强烈建议的.
别担心,PainterEngine的框架极为简单,PainterEngine将占用您短短几分钟的时间快速搭建并了解其框架。
打开工程目录,其中:
PainterEngine_Startup PainterEngine运行时框架,在当中定义了内存池大小,运行平台,窗体大小等应用的基本参数.
PainterEngine_Application 为功能逻辑运行框架,是编写用户代码的主要地方.
打开PainterEngine_Application.c,你可以看到三个函数
PX_ApplicationInitialize
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)PainterEngine初始化函数,在该函数中,完成应用的一系列初始化操作,例如,在这个函数中将会先初始化PainterEngine的运行时环境,创建的PainterEngine应用的窗口,或者如果你有对音频播放的需求你可以你加上对音频的支持。
其中
pApp 是应用的描述结构
Screen_width 是当前屏幕的像素宽度
Screen_height是当前屏幕的像素高度
当然为了减少PainterEngine部署难度,你可以看到在这个函数已经调用了一个默认的初始化函数
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
这个函数将初始化一个最初默认的运行时环境,并依据当前的屏幕创建了一个窗口。你可以在PainterEngine_Startup.c找到这个函数的详细实现,但在入门阶段和之后开发应用的大部分情况,你都可以直接使用这个默认的初始化函数或对其进行少量的修改,这个部分将在之后的章节详细介绍。
PX_ApplicationUpdate
px_void PX_ApplicationUpdate(PX_Application *pApp,px_dword elpased)PainterEngine的更新函数,在大部分的情况下,PainterEngine的运行环境会循环调用这个函数。
其中:
pApp 是应用的描述结构
elapsed 是上次更新后经历的时间,单位是毫秒
对于其详细应用将在之后详细介绍
PX_ApplicationRender
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)PainterEngine的渲染函数,在大部分的情况下,PainterEngine的运行环境会循环调用这个函数(实时渲染),这个函数的主要作用是绘制图像,当然,为了让显示和动画看起来尽可能流畅,你应该保证这个函数在每秒钟能被执行60次以上。但如果你对渲染没有非常高的实时性要求,你可以降低其帧率以实现更低的渲染功耗。
在这个函数中,你可以看到两行已经写好的代码
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));其中,第一句中的pRenderSurface表示渲染表面
PX_RuntimeRenderClear表示用某种颜色清空当前的渲染表面(或者绘制背景色),在上面PX_COLOR是一个颜色生成函数,四个参数分别表示a,r,g,b颜色分量
简单来说,PainterEngine的绘制流程是,先将surface成背景色,然后在上面绘制图像,在下一帧,再将这个surface重新刷成背景色,再画下一帧的图像。
其中
pApp 是应用的描述结构
elapsed 是上次更新后经历的时间,单位是毫秒
对于其详细应用将在之后详细介绍
PX_ApplicationPostEvent
这个函数用户响应用户输入事件,最常见的是鼠标移动,键盘按键,触摸屏按键等事件
px_void PX_ApplicationPostEvent(PX_Application *pApp,PX_Object_Event e)其中:
pApp是应用的描述结构
e是事件类型,
e.event有以下几种常用事件类型
#define PX_OBJECT_EVENT_ANY 0 //任意类型
#define PX_OBJECT_EVENT_CURSORMOVE 1 //光标移动
#define PX_OBJECT_EVENT_CURSORUP 2 //光标抬起
#define PX_OBJECT_EVENT_CURSORRDOWN 3 //光有右键按下
#define PX_OBJECT_EVENT_CURSORDOWN 4 //光标按下(触摸屏按下)
#define PX_OBJECT_EVENT_CURSORRUP 5 //光标抬起(触摸屏抬起)
#define PX_OBJECT_EVENT_CURSOROVER 6 //光标移动到区域*
#define PX_OBJECT_EVENT_CURSOROUT 7 //光标移出区域*
#define PX_OBJECT_EVENT_CURSORWHEEL 8 //光标滚轮*
#define PX_OBJECT_EVENT_STRING 9 //输入法字符串*
#define PX_OBJECT_EVENT_EXECUTE 10 //按钮按下
#define PX_OBJECT_EVENT_CURSORCLICK 11 //光标单击*
#define PX_OBJECT_EVENT_CURSORDRAG 12 //光标拖拽(触摸屏手指滑动)
#define PX_OBJECT_EVENT_VALUECHANGED 13 //值改变*
#define PX_OBJECT_EVENT_DRAGFILE 14 //文件拖进
#define PX_OBJECT_EVENT_KEYDOWN 15 //键盘按键按下
#define PX_OBJECT_EVENT_IMPACT 16 //对象碰撞(PX_World事件)
#define PX_OBJECT_EVENT_ONFOCUSCHANGED 17 //焦点改变
#define PX_OBJECT_EVENT_SCALE 18 //缩放
#define PX_OBJECT_EVENT_WINDOWRESIZE 19 //窗体尺寸改变详细内容将在之后讨论
获取PainterEngine绘制表面基础信息
PainterEngine的所有绘制是基于px_surface(渲染表面)的
在PX_ApplicationRender中pApp->runtime.RenderSurface是默认的渲染表面,在这个渲染表面绘制的图像会被直接显示在渲染结果中
因为显示设备的不一样,或者用户调整显示窗口的大小,默认渲染表面的长度和宽度可能会发生变化
你可以使用
pApp->runtime.surface_width 来获取当前渲染表面的像素宽度
pApp->runtime.surface_height来获取当前渲染表面的像素高度
使用PainterEngine绘制几何图形
*PainterEngine中使用的二维坐标系布置如下(屏幕坐标系)
其中,左上角为原点(0,0)右下角为终点(surface宽度,surface高度)
*PainterEngine采用了反走样算法进行几何绘制
绘制圆形
线
函数原型
函数名 | px_void PX_GeoDrawLine(px_surface *psurface, px_int x0, px_int y0, px_int x1, px_int y1 ,pt_int lineWidth, px_color color); | 说明 | 绘制一个反走样线段 | 参数 | psurface 渲染表面x0 y0起始点坐标x1 y1 终点坐标lineWidth 线宽color 颜色 |
示范
在PX_ApplicationRender中添加画线代码(如下所示),分别绘制三根:
(100,100)---> (600,100) 的 宽度为2的 红线
(100,200)---> (600,200) 的 宽度为6的 绿线
(100,300)---> (600,300) 的 宽度为12的 蓝线
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawLine(pRenderSurface,100,100,600,100,2,PX_COLOR(255,255,0,0));
PX_GeoDrawLine(pRenderSurface,100,200,600,200,6,PX_COLOR(255,0,255,0));
PX_GeoDrawLine(pRenderSurface,100,300,600,300,12,PX_COLOR(255,0,0,255));
}
边框
函数原型
函数名 | px_void PX_GeoDrawBorder(px_surface *psurface, px_int left, px_int top, px_int rignt, px_int bottom ,px_int lineWidth,px_color color); | 说明 | 绘制一个边框 | 参数 | psurface 渲染表面left top right bottom 位置描述lineWidth 边框宽度像素color 颜色 |
示范1
在PX_ApplicationRender中添加代码(如下所示),分别绘制一个:
(100,100)---> (300,300) 的 宽度为3的 黑色 边框
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawBorder(pRenderSurface,100,100,300,300,3,PX_COLOR(255,0,0,0));
}
示范2
在PX_ApplicationRender中添加代码(如下所示),分别绘制一个:
(100,100)---> (300,300) 的 宽度为8的 红色 半透明 边框
(200,200)---> (500,500) 的 宽度为8的 蓝色 半透明 边框
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawBorder(pRenderSurface,100,100,300,300,8,PX_COLOR(128,255,0,0));
PX_GeoDrawBorder(pRenderSurface,200,200,500,500,8,PX_COLOR(128,0,0,255));
}
矩形
函数原型
函数名 | px_void PX_GeoDrawRect(px_surface *psurface, px_int left, px_int top, px_int right, px_int bottom,px_color color); | 说明 | 绘制一个实心矩形 | 参数 | psurface 渲染表面left top right bottom 位置描述color 颜色 |
示范
在PX_ApplicationRender中添加代码(如下所示),分别绘制一个:
(100,100)---> (300,300) 的 宽度为8的 红色 半透明 矩形
(200,200)---> (500,500) 的 宽度为8的 蓝色 半透明 矩形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawRect(pRenderSurface,100,100,300,300,PX_COLOR(128,255,0,0));
PX_GeoDrawRect(pRenderSurface,200,200,500,500,PX_COLOR(128,0,0,255));
}
实心圆
函数原型
函数名 | px_void PX_GeoDrawSolidCircle(px_surface *psurface, px_int x,px_int y,px_int Radius,px_color color ); | 说明 | 绘制一个反走样实心圆 | 参数 | psurface 渲染表面x,y 圆心radius 半径color 颜色 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
(300,300) 的 半径为200的 紫色 圆形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawSolidCircle(pRenderSurface,300,300,200,PX_COLOR(255,255,0,255));
}圆
函数原型
函数名 | px_void PX_GeoDrawCircle(px_surface *psurface,px_int x,px_int y,px_int Radius ,pt_int lineWidth,px_color color); | 说明 | 绘制一个反走样圆 | 参数 | psurface 渲染表面x,y 圆心radius 半径lineWidth 线宽color 颜色 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
(300,300) 的 半径为200 线宽为10的 紫色 圆形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawCircle(pRenderSurface,300,300,200,10,PX_COLOR(255,255,0,255));
}
环
函数原型
函数名 | px_void PX_GeoDrawRing(px_surface *psurface, px_int x,px_int y,px_int Radius,px_int lineWidth,px_color color,px_uint start_angle,px_uint end_angle) | 说明 | 绘制一个反走样环 | 参数 | psurface 渲染表面x,y 环心radius 半径lineWidth 线宽color 颜色start_angle 起始角度(大于0)end_angle 终止角度(大于0)这个环遵循顺时针方向 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
环心在(300,300) 的 半径为200 线宽为10 开始角度45度终止角度270度的 蓝色 环形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawRing(pRenderSurface,300,300,200,50,PX_COLOR(255,0,0,255),45,270);
}
扇形
函数原型
函数名 | px_void PX_GeoDrawSector(px_surface *psurface, px_int x,px_int y,px_int Radius_outside,px_int Radius_inside,px_color color,px_uint start_angle,px_uint end_angle); | 说明 | 绘制一个反走样扇形 | 参数 | psurface 渲染表面x,y 环心outside 外径inside 内径color 颜色start_angle 起始角度end_angle 终止角度这个扇形遵循顺时针方向 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
扇心在(300,300) 的 内径为0 外径为200 开始角度45度终止角度270度的 蓝色 扇形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawSector(pRenderSurface,300,300,200,0,PX_COLOR(255,0,0,255),45,270);
}
圆角矩形
函数原型
函数名 | px_void PX_GeoDrawRoundRect(px_surface *psurface, px_int left, px_int top, px_int right, px_int bottom,px_float roundRaduis,px_float linewidth,px_color color); | 说明 | 绘制一个反走样圆角矩形 | 参数 | psurface 渲染表面left top right bottom 位置描述roundRadius 圆角半径lineWidth 线宽color 颜色 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
(100,100)(600,200) 圆角半径为25,线宽为5的红色圆角矩形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawRoundRect(pRenderSurface,100,100,600,200,25,5,PX_COLOR(255,0,0,255));
}
实心圆角矩形
函数原型
函数名 | px_void PX_GeoDrawSolidRoundRect(px_surface *psurface, px_int left, px_int top, px_int right, px_int bottom,px_float roundRaduis,px_color color); | 说明 | 绘制一个反走样实心圆角矩形 | 参数 | psurface 渲染表面left top right bottom 位置描述roundRadius 圆角半径color 颜色 |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制一个:
(100,100)(600,200) 圆角半径为25的蓝色实心圆角矩形
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_GeoDrawSolidRoundRect(pRenderSurface,100,100,600,200,25,5,PX_COLOR(255,0,0,255));
}
使用PainterEngine绘制图片纹理
加载纹理
在绘制图片纹理前PainterEngine需要先将纹理加载到内存中
PainterEngine_startup.c中,默认提供了一系列从文件加载资源的函数实现,当然这需要对应平台提供文件系统的支持.
在加载纹理之前,先定义px_texture用于存储纹理信息,为此,打开PainterEngine_Application.h在PX_Application中定义一个px_texture的实例MyTexture
typedef struct
{
px_texture MyTexture;
PX_Runtime runtime;
}PX_Application;(当然,这个MyTexture你也可以声明在其它地方,比如把它定义为全局变量,这里仅仅是作为一个例子)
现在,我们需要加载纹理,PainterEngine默认支持bmp和traw两种格式的文件,其中,traw格式文件可以由png文件转换,转换工具你可以在support/tools中找到(PainterEngine_PngToTraw.exe)
然后你可以使用PX_LoadTextureFromFile完成纹理的加载
px_bool PX_LoadTextureFromFile(px_memorypool *mp,px_texture *tex,const px_char path[]);其中:
Mp:表示将纹理加载后存储到的内存池,一般情况下,静态资源可以存储在pApp->runtime.mp_resources中
Tex:px_texture实例
Path:纹理文件的路径(windows以D盘下的test.traw)为例
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(PX_LoadTextureFromFile(pApp->runtime.mp_resources,&pApp->MyTexture,"D:/test.traw"))
{
//加载成功
}
else
{
//加载失败
}
return PX_TRUE;
}如果的你的程序使用Android平台,你可以将图片资源放在assets目录下,然后通过assets/图片名访问这个资源例如:
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(PX_LoadTextureFromFile(&pApp->runtime.mp_resources,&pApp->MyTexture,"asssets/test.traw"))
{
//加载成功
}
else
{
//加载失败
}
return PX_TRUE;
}现在,纹理资源加载完成了
绘制纹理
PainterEngine提供多种纹理绘制函数
函数原型
函数名 | px_void PX_TextureRender(px_surface *psurface,px_texture *tex,px_int x,px_int y ,PX_TEXTURERENDER_REFPOINT refPoint,PX_TEXTURERENDER_BLEND *blend); | 说明 | 渲染一个纹理到表面 | 参数 | psurface 渲染到的表面 px_texture需要渲染的纹理 x,y偏移量(该坐标以纹理左上角为参照)refPoint 参考中心点,用于表示纹理绘制的相对位置blend blend类型结构体,用于调整绘制纹理的alpha,hdr值当它为PX_NULL时,表示采用默认blend值typedef struct{ float hdr_R; //HDR of Red float hdr_G; //HDR of Green float hdr_B; //HDR of Blue float alpha; //Blend of alpha}PX_TEXTURERENDER_BLEND; | 返回值 | - |
示范
在PX_ApplicationInitialize,PX_ApplicationRender中添加代码(如下所示),绘制一个纹理
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(PX_LoadTextureFromFile(&pApp->runtime.mp_resources,&pApp->MyTexture,"D:/test.traw"))
{
//加载成功
}
else
{
//加载失败
}
return PX_TRUE;
}
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_TextureRender(pRenderSurface,&pApp->MyTexture,pApp->runtime.surface_width/2,pApp->runtime.window_height/2,PX_TEXTURERENDER_REFPOINT_CENTER,PX_NULL);
}
使用PainterEngine绘制文本
绘制默认ANSI字模
PainterEngine默认集成了ANSI文本字模,使用默认字模绘制文本十分简单
函数原型
函数名 | px_int PX_FontDrawText(px_surface *psurface,int x,int y,PX_FONT_ALIGN align,const px_char *Text,px_color Color); | 说明 | 绘制ANSI文本 | 参数 | psurface 表面x,y偏移坐标align 对齐模式PX_FONT_ALIGN_LEFTTOP, 左上角对齐 PX_FONT_ALIGN_MIDTOP,居中顶部对齐 PX_FONT_ALIGN_RIGHTTOP,右上角对齐 PX_FONT_ALIGN_LEFTMID,靠左居中对齐 PX_FONT_ALIGN_CENTER,中心对齐 PX_FONT_ALIGN_RIGHTMID,靠右居中对齐 PX_FONT_ALIGN_LEFTBOTTOM,靠左底部对齐 PX_FONT_ALIGN_MIDBOTTOM,居中底部对齐 PX_FONT_ALIGN_RIGHTBOTTOM,靠右底部对齐Text ANSI字符集文本指针Color 颜色 | 返回值 | - |
示范
在PX_ApplicationRender中添加代码(如下所示),绘制深蓝色文本”Hello World 123”
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_FontDrawText(pRenderSurface,10,100,PX_FONT_ALIGN_LEFTTOP,"Hello World 123",PX_COLOR(255,0,0,128));
}
创建字模文件
PainterEngine运行您使用TTF文件创建自定义的字模文件,字模制作工具你可以在PainterEngine/supports/tools中找到(PainterEngine_Fontmodule.exe)
1.运行字模制作工具,选择你需要的ttf文件(以幼圆为例)
2.选择字典文件(TXT),字典文件里应该包含你程序需要用到的所有文字(如果没有,这个文字将不被显示),同时,字典文件必须按照特定的编码进行保存(强烈建议UTF8或GBK).在
PainterEngine/supports/tools/Font Module Dictionary中,你可以找到ANSI和汉字不同编码的所有字符字典,你可以直接使用这些字典,当然,在一些存储空间紧张的情况下,强烈建议使用裁剪后的字典以减小生成字模的文件大小(这里,笔者以UTF8的字典为例).
3.选择字模的生成路径(D:/test.pxf)
4.设定字体大小
5.设定编码(必须和字典文件的使用编码一致)
6.生成字模
现在,你可以在D盘中找到test.pxf的字模文件了
*注意,chs中仅包含汉字文件,并不包含ANSI中的英文字符及标点,因此,如果你希望支持所有的汉字及英文标点,你应该使用ANSI_utf8.txt和英文字体制作另一份字模文件,下面是例子:
绘制字模文本
相关函数原型
字模初始化
函数名 | px_bool PX_FontModuleInitialize(px_memorypool *mp,PX_FontModule *module,PX_FONTMODULE_CODEPAGE codepage) | 说明 | 初始化一个字模库 | 参数 | Mp 内存池Module 字模库codepage 字模代码页 | 返回值 | 如果成功返回PX_TRUE,否者返回PX_FALSE |
以字模库绘制文本
函数名 | px_int PX_FontModuleDrawText(px_surface *psurface,PX_FontModule *mod,int x,int y,PX_FONT_ALIGN align,const px_char *Text,px_color Color) | 说明 | 以该字模库绘制文本,注意,输入的字模必须是UTF-16 littleendia编码的 | 参数 | Psurface 目标表面X 原点x坐标Y 原点y坐标 Text 文本Color字颜色Mod 字模库Align 字体对齐模式PX_FONT_ALIGN_LEFTTOP, 左上角对齐 PX_FONT_ALIGN_MIDTOP,居中顶部对齐 PX_FONT_ALIGN_RIGHTTOP,右上角对齐 PX_FONT_ALIGN_LEFTMID,靠左居中对齐 PX_FONT_ALIGN_CENTER,中心对齐 PX_FONT_ALIGN_RIGHTMID,靠右居中对齐 PX_FONT_ALIGN_LEFTBOTTOM,靠左底部对齐 | 返回值 | -绘制文本的像素宽度 |
1.创建字模库
使用PainterEngine绘制字模文本,首先需要创建字模库,打开PainterEngine_Application.h,在PX_Application的结构体定义中,添加PX_FontModule
typedef struct
{
PX_FontModule fm;
PX_Runtime runtime;
}PX_Application;
2.初始化字模库
打开PainterEngine_Application.c,添加初始化字模库代码
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(!PX_FontModuleInitialize(&pApp->runtime.mp_resources,&pApp->fm,PX_FONTMODULE_CODEPAGE_UTF8)) return PX_FALSE;
return PX_TRUE;
}3.加载字模文件
打开PainterEngine_Application.c,添加初始化字模加载代码
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(!PX_FontModuleInitialize(&pApp->runtime.mp_resources,&pApp->fm,PX_FONTMODULE_CODEPAGE_UTF8)) return PX_FALSE;
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test.pxf")) return PX_FALSE;//加载中文字模
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test2.pxf")) return PX_FALSE;//加载ANSI字模
return PX_TRUE;
}
4.绘制字模文本
打开PainterEngine_Application.c, 在PX_ApplicationRender中绘制字模文本:
”你好,PainterEngine”
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(!PX_FontModuleInitialize(&pApp->runtime.mp_resources,&pApp->fm,PX_FONTMODULE_CODEPAGE_UTF8)) return PX_FALSE;
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test.pxf")) return PX_FALSE;//加载中文字模
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test2.pxf")) return PX_FALSE;//加载ANSI字模
return PX_TRUE;
}
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_FontModuleDrawText(pRenderSurface,&pApp->fm,10,100,PX_FONT_ALIGN_LEFTTOP,"你好,PainterEngine",PX_COLOR(255,0,0,128));
}
使用PainterEngine创建交互式组件(UI控件)
PainterEngine的应用的组建是以对象的形式存在的.PainterEngine内部集成了多种常用交互式组件(对象)供用户使用,PainterEngine强烈鼓励用户自己设计或拓展需要的功能组件(对象),下面是几个简单的交互式组件(对象)例子.
创建根对象
函数原型
函数名 | PX_Object *PX_ObjectCreate(px_memorypool *mp,PX_Object *Parent,px_float x,px_float y,px_float z,px_float Width,px_float Height,px_float Lenght); | 功能 | 创建一个对象 | mp | 对象使用的内存池 | parent | 父对象(如果为NULL表示这是一个根对象) | x,y,z | 坐标信息,注意z坐标信息,z的值越大,这个对象在渲染时将被最先绘制,这也就意味着z值小的对象将会覆盖在z值较大的对象中 | Width,Heigth,Lenght | 宽度,高度,长度 | 返回值 | 返回创建的对象指针 |
示范
在创建其它交互式组件(对象)之前,强烈建议创建一个根对象以便于对象树的管理,创建根对象很简单,打开PainterEngine_Application.h,定义一个PX_Object *ui_root;
typedef struct
{
PX_Object *ui_root;
PX_FontModule fm;
PX_Runtime runtime;
}PX_Application;打开PainterEngine_Application.c,在PX_ApplicationInitialize中添加代码
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
if(!PX_FontModuleInitialize(&pApp->runtime.mp_resources,&pApp->fm,PX_FONTMODULE_CODEPAGE_UTF8)) return PX_FALSE;
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test.pxf")) return PX_FALSE;//加载中文字模
if(!PX_LoadFontModuleFromFile(&pApp->fm,"D:/test2.pxf")) return PX_FALSE;//加载ANSI字模
pApp->ui_root=PX_ObjectCreate(&pApp->runtime.mp_ui,0,0,0,0,0,0,0);
return PX_TRUE;
}
创建按钮控件
函数原型
函数名 | PX_Object *PX_Object_PushButtonCreate(px_memorypool *mp,PX_Object *Parent,px_int x,px_int y,px_int Width,px_int Height,const px_char *Text,PX_FontModule *fontmodule,px_color Color); | 说明 | 创建一个按钮交互控件 | 参数 | mp内存池Parent 父对象x,y 控件左上角位置width 宽度height 高度Text 控件显示文本fontmodule 控件显示文本的字模(为PX_NULL表示使用ANSI默认字模)color 文本颜色 | 返回值 | 如果成功PX_Object指针,否者返回PX_NULL |
示范
打开PainterEngine_Application.h,定义一个PX_Object * button;
typedef struct
{
PX_Object *ui_root;
PX_Object *button;
PX_Runtime runtime;
}PX_Application;
打开PainterEngine_Application.c,在PX_ApplicationInitialize中添加代码
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
pApp->ui_root=PX_ObjectCreate(&pApp->runtime.mp_ui,0,0,0,0,0,0,0);
pApp->button=PX_Object_PushButtonCreate(&pApp->runtime.mp_ui,pApp->ui_root,100,100,84,32,"Button",PX_NULL,PX_COLOR(255,0,0,0));
return PX_TRUE;
}在PX_ApplicationUpdate中添加代码
px_void PX_ApplicationUpdate(PX_Application *pApp,px_dword elpased)
{
PX_ObjectUpdate(pApp->ui_root,elpased);
}在PX_ApplicationRender中添加代码
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_ObjectRender(pRenderSurface,pApp->ui_root,elpased);
}
在PX_ApplicationPostEvent中添加代码
px_void PX_ApplicationPostEvent(PX_Application *pApp,PX_Object_Event e)
{
PX_ApplicationEventDefault(&pApp->runtime, e);
PX_ObjectPostEvent(pApp->ui_root,e);
}
添加点击事件
函数原型
注册对象事件
函数名 | px_int PX_ObjectRegisterEvent(PX_Object *Object,px_uint Event,px_void (*ProcessFunc)(PX_Object *,PX_Object_Event e,px_void *user_ptr),px_void *ptr); | 功能 | 为一个对象注册响应事件 | 参数Object | 需要绘制的对象指针 | 参数Event | 响应的事件类型 | ProcessFunc | 响应处理函数 | ptr | 用户自定义指针 |
示范
首先编写按钮点击处理函数, 打开PainterEngine_Application.c添加下面的代码
#include "windows.h"
px_void OnButtonExecute(PX_Object *pObject,PX_Object_Event e,px_void *ptr)
{
MessageBox(0,"Button Clicked","",MB_OK);
}
然后将处理函数和对象事件进行绑定
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
pApp->ui_root=PX_ObjectCreate(&pApp->runtime.mp_ui,0,0,0,0,0,0,0);
pApp->button=PX_Object_PushButtonCreate(&pApp->runtime.mp_ui,pApp->ui_root,100,100,84,32,"Button",PX_NULL,PX_COLOR(255,0,0,0));
PX_ObjectRegisterEvent(pApp->button,PX_OBJECT_EVENT_EXECUTE,OnButtonExecute,pApp);//注册按钮事件
return PX_TRUE;
}
完整代码
#include "PainterEngine_Application.h"
PX_Application App;
#include "windows.h"
px_void OnButtonExecute(PX_Object *pObject,PX_Object_Event e,px_void *ptr)
{
MessageBox(0,"Button clicked","",MB_OK);
}
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
pApp->ui_root=PX_ObjectCreate(&pApp->runtime.mp_ui,0,0,0,0,0,0,0);//创建根对象
pApp->button=PX_Object_PushButtonCreate(&pApp->runtime.mp_ui,pApp->ui_root,100,100,84,32,"Button",PX_NULL,PX_COLOR(255,0,0,0));
PX_ObjectRegisterEvent(pApp->button,PX_OBJECT_EVENT_EXECUTE,OnButtonExecute,pApp);//注册按钮事件
return PX_TRUE;
}
px_void PX_ApplicationUpdate(PX_Application *pApp,px_dword elpased)
{
PX_ObjectUpdate(pApp->ui_root,elpased);
}
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_ObjectRender(pRenderSurface,pApp->ui_root,elpased);
}
px_void PX_ApplicationPostEvent(PX_Application *pApp,PX_Object_Event e)
{
PX_ApplicationEventDefault(&pApp->runtime, e);
PX_ObjectPostEvent(pApp->ui_root,e);
}
创建文本控件
函数原型
函数名 | PX_Object* PX_Object_EditCreate(px_memorypool *mp, PX_Object *Parent,px_int x,px_int y,px_int Width,px_int Height,PX_FontModule *fontModule,px_color TextColor ) | 说明 | 创建一个编辑框控件 | 参数 | mp内存池Parent 父对象x,y 控件左上角位置width 宽度height 高度fontmodule 控件显示文本的字模(为PX_NULL表示使用ANSI默认字模)color 文本颜色 | 返回值 | 如果成功PX_Object指针,否者返回PX_NULL |
示范
打开PainterEngine_Application.h,定义一个PX_Object * Edit;
typedef struct
{
PX_Object *ui_root;
PX_Object * Edit;
PX_Runtime runtime;
}PX_Application;打开PainterEngine_Application.c,在PX_ApplicationInitialize中添加代码
px_bool PX_ApplicationInitialize(PX_Application *pApp,px_int screen_width,px_int screen_height)
{
PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height);
pApp->ui_root=PX_ObjectCreate(&pApp->runtime.mp_ui,0,0,0,0,0,0,0);//创建根对象
pApp->edit=PX_Object_EditCreate(&pApp->runtime.mp_ui,pApp->ui_root,100,100,128,32,PX_NULL,PX_COLOR(255,0,0,0));
return PX_TRUE;
}在PX_ApplicationUpdate,PX_ApplicationRender,PX_ApplicationPostEvent中添加代码
px_void PX_ApplicationUpdate(PX_Application *pApp,px_dword elpased)
{
PX_ObjectUpdate(pApp->ui_root,elpased);
}
px_void PX_ApplicationRender(PX_Application *pApp,px_dword elpased)
{
px_surface *pRenderSurface=&pApp->runtime.RenderSurface;
PX_RuntimeRenderClear(&pApp->runtime,PX_COLOR(255,255,255,255));
PX_ObjectRender(pRenderSurface,pApp->ui_root,elpased);
}
px_void PX_ApplicationPostEvent(PX_Application *pApp,PX_Object_Event e)
{
PX_ApplicationEventDefault(&pApp->runtime, e);
PX_ObjectPostEvent(pApp->ui_root,e);
}
===============================================
基于PainterEngine的网络游戏
自己拥有一台服务器可以做哪些很酷的事情?
演示下基于PainterEngine的服务端Console程序,写个简单的JIT(脚本即时编译执行)功能
一个基于PainterEngine的小游戏
PainterEngine支持群
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|