作者:龙飞
1.1:准备工作。
准备一张640*480的bmp位图(back.bmp)作为背景,另外一张小一点的(比如100*100的front.bmp)作为前景。
渲染(render)是CG术语,是将以数据结构储存在计算机中的图片以人眼可观察的图片实现出来的过程。前面例子中显示一张bmp图片实际上也是渲染。对于那张bmp图片,我们经历了3过过程的处理:1、将bmp图片转化为SDL_Surface的结构格式;2、将转化后的SDL_Surface块移(blit)到SDL创建的窗口surface上;3、将这个surface显示出来,实际上就是渲染出来。
当然,前面仅仅是渲染了单帧的图片,我们这里对程序做些修改,从而实际上是连续的渲染多帧动画(虽然表面上我们并没有让画面动起来)。
1.2:演示程序的完整源代码。
#include
<
iostream
>
#include " SDL/SDL.h "
SDL_Surface * pScreen = 0 ;
SDL_Surface * pBack = 0 ;
SDL_Surface * pFront = 0 ;
void pressESCtoQuitPlus();
void loopRender();
int main( int argc, char * argv[])
{
try {
if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_Init() failed!/n " << s << std::endl;
return - 1 ;
}
const int SCREEN_WIDTH = 640 ;
const int SCREEN_HEIGHT = 480 ;
const int SCREEN_BPP = 32 ;
const Uint32 SCREEN_FLAGS = SDL_FULLSCREEN;
pScreen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SCREEN_FLAGS);
try {
if ( pScreen == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_SetVideoMode() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
pBack = SDL_LoadBMP( " back.bmp " );
try {
if ( pBack == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_LoadBMP() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
pFront = SDL_LoadBMP( " front.bmp " );
try {
if ( pFront == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_LoadBMP() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
try {
pressESCtoQuitPlus();
}
catch ( const char * s ) {
std::cerr << " pressESCtoQuitPlus() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
SDL_Quit();
return 0 ;
}
void pressESCtoQuitPlus()
{
bool gameOver = false ;
while ( gameOver == false ){
SDL_Event gameEvent;
while ( SDL_PollEvent( & gameEvent) != 0 ){
if ( gameEvent.type == SDL_QUIT ){
gameOver = true ;
}
if ( gameEvent.type == SDL_KEYUP ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true ;
}
}
}
loopRender();
}
return ;
}
void loopRender()
{
SDL_Rect * pSrcRect = 0 ;
SDL_Rect * pDstRect = 0 ;
if ( SDL_BlitSurface(pBack, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();
if ( SDL_BlitSurface(pFront, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();
if ( SDL_Flip(pScreen) != 0 )
throw SDL_GetError();
return ;
}
#include " SDL/SDL.h "
SDL_Surface * pScreen = 0 ;
SDL_Surface * pBack = 0 ;
SDL_Surface * pFront = 0 ;
void pressESCtoQuitPlus();
void loopRender();
int main( int argc, char * argv[])
{
try {
if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_Init() failed!/n " << s << std::endl;
return - 1 ;
}
const int SCREEN_WIDTH = 640 ;
const int SCREEN_HEIGHT = 480 ;
const int SCREEN_BPP = 32 ;
const Uint32 SCREEN_FLAGS = SDL_FULLSCREEN;
pScreen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SCREEN_FLAGS);
try {
if ( pScreen == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_SetVideoMode() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
pBack = SDL_LoadBMP( " back.bmp " );
try {
if ( pBack == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_LoadBMP() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
pFront = SDL_LoadBMP( " front.bmp " );
try {
if ( pFront == 0 )
throw SDL_GetError();
}
catch ( const char * s ) {
std::cerr << " SDL_LoadBMP() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
try {
pressESCtoQuitPlus();
}
catch ( const char * s ) {
std::cerr << " pressESCtoQuitPlus() failed!/n " << s << std::endl;
SDL_Quit();
return - 1 ;
}
SDL_Quit();
return 0 ;
}
void pressESCtoQuitPlus()
{
bool gameOver = false ;
while ( gameOver == false ){
SDL_Event gameEvent;
while ( SDL_PollEvent( & gameEvent) != 0 ){
if ( gameEvent.type == SDL_QUIT ){
gameOver = true ;
}
if ( gameEvent.type == SDL_KEYUP ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true ;
}
}
}
loopRender();
}
return ;
}
void loopRender()
{
SDL_Rect * pSrcRect = 0 ;
SDL_Rect * pDstRect = 0 ;
if ( SDL_BlitSurface(pBack, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();
if ( SDL_BlitSurface(pFront, pSrcRect, pScreen, pDstRect) != 0 )
throw SDL_GetError();
if ( SDL_Flip(pScreen) != 0 )
throw SDL_GetError();
return ;
}
1.3:程序改动说明。
1) 使用了全屏幕显示;
2) 使用了改动后的pressESCtoQuit()函数,用于在全屏模式下方便退出。
3) 将一些变量修改为全局变量,以提供main()所调用的函数使用。