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

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-12-19 09:47:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
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作为了一个黑盒子来研究,但是我得到的试验结果,却是不可能错的。                     
分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表