随笔 - 96  文章 - 255  trackbacks - 0
<2010年6月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 488853
  • 排名 - 37

最新评论

阅读排行榜

评论排行榜

作者:龙飞

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作为了一个黑盒子来研究,但是我得到的试验结果,却是不可能错的。

2.4:补充。

        目前用Debian试验的时候,发现NVidia的显卡驱动屏蔽掉了dga的。也就是说实际上用不了,或者会设置起来很麻烦。实际上,SDL通过x11来实现图像,我目前的认识应该是这样的:SDL->x11->NV驱动->显卡。所以,实际上我们虽然没有通过SDL接触到显卡,但实际上还是通过种种渠道调用了显卡,我们应该充分相信NV的工程师比我们牛得多。NV官方解释如下:
http://us.download.nvidia.com/XFree86/Linux-x86/169.04/README/chapter-07.html#id2546686

Why do applications that use DGA graphics fail?


The NVIDIA driver does not support the graphics component of the XFree86-DGA (Direct Graphics Access) extension. Applications can use the XDGASelectInput() function to acquire relative pointer motion, but graphics-related functions such as XDGASetMode() and XDGAOpenFramebuffer() will fail.

The graphics component of XFree86-DGA is not supported because it requires a CPU mapping of framebuffer memory. As graphics cards ship with increasing quantities of video memory, the NVIDIA X driver has had to switch to a more dynamic memory mapping scheme that is incompatible with DGA. Furthermore, DGA does not cooperate with other graphics rendering libraries such as Xlib and OpenGL because it accesses GPU resources directly.

NVIDIA recommends that applications use OpenGL or Xlib, rather than DGA, for graphics rendering. Using rendering libraries other than DGA will yield better performance and improve interoperability with other X applications.


posted on 2008-02-15 16:23 lf426 阅读(9425) 评论(6)  编辑 收藏 引用 所属分类: SDL入门教程

FeedBack:
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)  2008-08-03 19:28 xiangxiangxiangxiangxiangxiangxiang
我显卡是NVIDIA的,用dga果然不行
用x11也不行!
请问怎么才能启用硬加速呢?谢谢  回复  更多评论
  
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render) [未登录] 2008-08-03 20:07 lf426
我的认识是这样的,只要x11启动了nv的驱动,硬件加速实际上是打开的,只是被封装到了x11内部,我们通过SDL软件渲染调用了封装后的x11接口,实际作用的时候是启动了硬件加速。这样应该比我们直接调用硬件接口更加安装简单易用。如何绕过这个设定,估计只有问问SDL的作者了,我在fqa里是没找到。  回复  更多评论
  
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)  2008-08-04 18:25 xiangxiangxiangxiangxiangxiangxiang
按照你的意思那么在linux 下面就可以不用写putenv("SDL_VIDEODRIVER=dga");
以为x11会去调用他
而且我加上这句话运行会崩掉的(其他directfb,svgalib,ggi也一样不行)

可是我检测到的pScreen->flags确是没有开启加速。
晕了
设置成
putenv("SDL_VIDEODRIVER=fbcon");
显示有点有变化,但pScreen->flags==0
同样,
putenv("SDL_VIDEODRIVER=aalib");
会有乱马,但仍然pScreen->flags==0
  回复  更多评论
  
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render) [未登录] 2008-08-04 22:06 lf426
我的意思其实就是,一般情况下,不需要设置成硬件渲染。我认为SDL软件渲染实际是把任务交给了x11,至于x11最终是通过什么途径渲染不是很重要,而且我认为x11实际上是调用了nv的驱动,所以,虽然没有在SDL中设置成硬件渲染,但是并不意味着就没调用显卡。当然,都是我的猜测,具体情况,可能得问问SDL作者本人。  回复  更多评论
  
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)  2013-06-10 13:06 萧萧_gloxec
关于sdl的渲染楼主说错了
sdl源码我认真分析了
sdl的渲染模式是绕过了x11
直接建立在底层了
因此想怎么渲染都行
但又设计者把零碎的给屏幕描点给封装成了各式的渲染,并且为了方便他人开发,又用x11在外围加了一层不必要的框
因此在没有x11,文本的状态下仍然可以各种渲染
并且sdl是基于底层的原因,所以可以实现任意坐标点的颜色改变,但又因为封装的缘故,所以没那么随心所欲

按找sdl的渲染原理。
我也同样做出了可以任意改变屏幕某个点,或块,的函数

同时又找了x11的显图原理
发现应该是
x11→显卡
sdl→显卡
而且x11,sdl都是平等的用了2.4以上kernel的fb设备,实现显图,只不过是功能不同而以  回复  更多评论
  
# re: SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)  2013-06-10 13:14 萧萧_gloxec
并且双缓冲也是需要硬件支持的
sdl是用fb的接口做渲染的
所以要想双缓冲,那么就要fb的总内存大于 〔fb.xres *
fb.yres *
fb.bits_per_pixel /
8〕 的值  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理