SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)

作者:龙飞

2.1:需要修改的地方。

        这里,我们真正的开始使用SDL的硬件渲染。首先,我们需要设置驱动的环境(以windows为例,我们设置为directx,Linux的设置请参考官方网站,我们这里预留为dga)。另外,如果要启动硬件加速,必须使用全屏模式(SDL_FULLSCREEN),所以,在前面的软件渲染中,我们也使用全屏以作对比。第三,硬件渲染需要打开双缓冲(SDL_DOUBLEBUF),至于为什么我们在最后讨论,我们还是先看看完整的代码。

2.2:硬件渲染演示程序完整的源代码。
#define  __windows__     //  Linux using #define __linux__
#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[])
{
#ifdef __windows__
    SDL_putenv(
" SDL_VIDEODRIVER=directx " );
#endif

#ifdef __linux__
    putenv(
" SDL_VIDEODRIVER=dga " );
#endif

    
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  |  SDL_DOUBLEBUF  |  SDL_HWSURFACE;

    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 ;
}

2.3:问题。

        你可能发现除了鼠标指针不显示之外,没有其它问题——这其实不是好现象,因为应该和可能出现的问题,都被我们事先避免了,但是这样让我们离事情的本质越来越远。你可以尝试着关掉SDL_DOUBLEBUF位标看看是什么效果;或者,在前面渲染单帧的程序中使用硬件渲染同时打开双缓冲看看出现什么问题——这些正是我们下一节将要讨论的。
        如果你迫不及待的想知道原因,并且英语也过关的话,对于硬件渲染可能会引发的问题,我给你推荐一篇SDL官方也推荐的论文:
http://www.linuxdevcenter.com/pub/a/linux/2003/08/07/sdl_anim.html
        但是很不幸的是,我在试验的过程中发现这篇文章有很多问题,当然,也许是我错了。因为我仅仅把SDL作为了一个黑盒子来研究,但是我得到的试验结果,却是不可能错的。  
 
此篇文章来自【 http://blog.csdn.net/lf426/article/details/2097510】

你可能感兴趣的:(windows,linux,video)