[PSP教程01]helloworld,第一个sdl+nge程序



掌叔
2008-06-05 16:54:32

摘自: topoc studio
作者:newcreat
设置好库之后,就可以开始写代码了.在这里我建议你将你的psp锁起来,因为在接下来的10个教程里,我们都不会用到psp调试程序,而你也不需要用他来看效果.当然,你如果觉得没事干可以编译一份放到psp上看看,你会发现一切都是一样的,和在windows上,包括错误.

  那么我们开始hello world吧.这个helloworld将显示一张图片,这张图片是任意大小的,这里用的480*272,你按不同的键可以使他放大,缩小,旋转或者平移.

#include "libnge.h"

SDL_Joystick* joystick;
SDL_Event event;
IVideoDriver* sys ;

首先是包含头文件libnge.h,接着是SDL_Joystick与SDL_Event,熟悉sdl的都知道SDL_Joystick是控制杆(手柄),SDL_Event是一个消息,用于消息队列.IVideoDriver*是显示接口的指针,这个对用户是透明的.由 NGE_GetVideoDriver()得到.(实际在windows是返回的ogldriver,在psp是返回gudriver.)

接下来是一些变量,主要是为了让旋转有所变化.

CTexture* bg[2]; //保存图片的指针,这里加载2张图片
int done = 0; //程序是否结束
int id = 0; // 图片id
float scale = 1.0; //放大缩小比率1.0就是原大小,2.0就是2倍 0.5 就是缩小一倍

float angel = 0.0; //旋转角度

接下来是2个输入处理函数,其中一个是处理键盘,一个处理手柄.

void ButtonPressedProc(SDL_JoyButtonEvent * jbutton)
{
switch(jbutton -> button)
{
case 8:
angel=90;
break;
case 6:
angel =180;
break;
case 7:
angel = 270;
break;
case 9:
angel = 360;
break;
case 0:
scale-=0.05;
if(scale<=0)
scale = 0.05;
break;
case 1:
scale+=0.05;
break;
case 2:
angel-=1.0;
break;
case 3:
angel+=1.0;
break;
case 11:
id++;
id=id%2;
break;

}

}

void KeyPressedProc(SDL_keysym * keysym)
{

switch(keysym -> sym)
{
case SDLK_UP:
angel=90;
break;
case SDLK_DOWN:
angel =180;
break;
case SDLK_LEFT:
angel =270;
break;
case SDLK_RIGHT:
angel =360;
break;
case SDLK_w:
scale-=0.05;
if(scale<=0)
scale = 0.05;
break;
case SDLK_d:
scale+=0.05;
break;
case SDLK_s:
angel-=1.0;
break;
case SDLK_a:
angel+=1.0;
break;
case SDLK_m:
id++;
id=id%2;
break;
}
}

然后是sdl处理消息的函数,来了键盘消息就调用键盘处理函数,来了手柄消息就调用手柄处理函数.

void InputProc()
{
while( SDL_PollEvent( &event ) )
{
switch(event.type)
{
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
KeyPressedProc(&event.key.keysym);
break;
case SDL_JOYBUTTONDOWN:
ButtonPressedProc(&event.jbutton);
break;
}
}
}

接着是画图的函数:

int DrawScene()
{
 sys->BeginScene();
 sys->RenderQuad(bg[id],0,0,0,0,0,0,scale,scale,angel,0xffffffff);
 sys->EndScene();
return( TRUE );
}

RenderQuad是处于BeginScene()和EndScene()之间的,其中BeginScene()作的清屏等工作, EndScene()作的交换缓冲的工作,gu是双缓冲模式工作的,所以效率有所保证.(ps:debug版的交换缓冲区在ShowFps()里作的,所以程序需要调用ShowFps().)

RenderQuad各个参数的意义如下:

/**
* a normal member function taking 11 arguments and non-returning.
* use for render picture.
* @param texture CTexture pointer, create by LoadTexture().
* @param sx float,x(left) coodinate of texture.
* @param sy float,y(top) coodinate of texture.
* @param sw float,w(right) of texture.
* @param sh float,h(bottom) of texture.
* @param dx float,x coodinate of screen.
* @param dy float,y coodinate of screen.
* @param xscale float,x scale of texture.
* @param yscale float,y scale of texture.
* @param angle float,roting texture,use (rcentrex,rcentrex) in CTexture as rote point.
* @param color int , blend color,the color will blend in texture,using for alpha blend.
* use macro RGBA(r,g,b,a) to make color,if a is 0,the picture is transparent.

*/

主程序:

extern "C"
int main(int argc, char* argv[])
{
NGE_InitSDL(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);//初始化sdl

if(SDL_NumJoysticks()) {
joystick = SDL_JoystickOpen(0);//初始化手柄
}
sys = NGE_GetVideoDriver();//得到显示接口
bg[0] = LoadTexture("gamebg1.png");//加载图片1到内存
bg[1] = LoadTexture("gamebg2.png");//加载图片2到内存
sys->FpsInit();//初始化fps计数器
while ( !done )
{
InputProc();
DrawScene();
sys->ShowFps();//显示fps,注意debug版都要加这个.
}
FreeTexture(bg[0]);//释放图片1
FreeTexture(bg[1]);//释放图片2
NGE_QuitSDL();//释放sdl分配的资源

return 0;
}

运行效果
[attach]10[/attach]
windows版的箭头对应psp的上下左右,w/d/s/a对应 △○×□,可以旋转缩放,可以看出由于是硬件加速所以旋转缩放不会有性能损耗,在psp上默认222mhz下能到250-270fps(windows下会因为pc的显卡不同而fps不同,这基本是pc贴图的极限植.瞧我的机器很好吧,hoho)

psp上效果是一致的,只是fps少点
[attach]11[/attach]
熟悉sdl的都知道这个程序与sdl基本没有差别,这是显示部分不同.所以如果会sdl基本就会用这个了.

本节代码下载地址:本节代码就在demo文件夹里.

下一节我们将讨论freetype汉字的显示,可以作出很多奇怪的效果来:)


lihuaning
2009-07-22 03:47:29

你的机器还不错呢,能跑到2000多帧,对了,有没有办法限制帧数,比如说我想让他60帧跑?


yl_ls
2009-07-22 10:08:20

NGE 已经升级到 NGE2 上,也就是说此贴的内容过期了
NGE2上使用
在显示循环中插入
LimitFps(60);
这样的写法就是每秒 60 帧的意思