SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)
来源:互联网 发布:网络教育本科能考研吗 编辑:程序博客网 时间:2024/05/17 20:26
转自 : http://www.cppblog.com/lf426/archive/2008/02/15/42773.html
这里,我们真正的开始使用SDL的硬件渲染。首先,我们需要设置驱动的环境(以windows为例,我们设置为directx,Linux的设置请参考官方网站,我们这里预留为dga)。另外,如果要启动硬件加速,必须使用全屏模式(SDL_FULLSCREEN),所以,在前面的软件渲染中,我们也使用全屏以作对比。第三,硬件渲染需要打开双缓冲(SDL_DOUBLEBUF),至于为什么我们在最后讨论,我们还是先看看完整的代码。
2.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[])
{
#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.
FeedBack:
用x11也不行!
请问怎么才能启用硬加速呢?谢谢 回复 更多评论
以为x11会去调用他
而且我加上这句话运行会崩掉的(其他directfb,svgalib,ggi也一样不行)
可是我检测到的pScreen->flags确是没有开启加速。
晕了
设置成
putenv("SDL_VIDEODRIVER=fbcon");
显示有点有变化,但pScreen->flags==0
同样,
putenv("SDL_VIDEODRIVER=aalib");
会有乱马,但仍然pScreen->flags==0
回复 更多评论
sdl源码我认真分析了
sdl的渲染模式是绕过了x11
直接建立在底层了
因此想怎么渲染都行
但又设计者把零碎的给屏幕描点给封装成了各式的渲染,并且为了方便他人开发,又用x11在外围加了一层不必要的框
因此在没有x11,文本的状态下仍然可以各种渲染
并且sdl是基于底层的原因,所以可以实现任意坐标点的颜色改变,但又因为封装的缘故,所以没那么随心所欲
按找sdl的渲染原理。
我也同样做出了可以任意改变屏幕某个点,或块,的函数
同时又找了x11的显图原理
发现应该是
x11→显卡
sdl→显卡
而且x11,sdl都是平等的用了2.4以上kernel的fb设备,实现显图,只不过是功能不同而以 回复 更多评论
sdl是用fb的接口做渲染的
所以要想双缓冲,那么就要fb的总内存大于 〔fb.xres *
fb.yres *
fb.bits_per_pixel /
8〕 的值 回复 更多评论
- SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)
- SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)
- SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)
- SDL入门教程(四):1、SDL动画的软件渲染(Software Render)
- SDL入门教程(四):1、SDL动画的软件渲染(Software Render)
- SDL入门教程(四):3、SDL的软、硬件渲染的深入试验和分析
- SDL入门教程(四):3、SDL的软、硬件渲染的深入试验和分析
- SDL入门教程(六):SDL读取其它格式的图片
- SDL入门教程(六):SDL读取其它格式的图片
- SDL入门教程(五):2、构建SDL surface类
- SDL入门教程(五):2、构建SDL surface类
- SDL入门教程(二):2、SDL的安全装载与安全退出
- SDL入门教程(二):2、SDL的安全装载与安全退出
- SDL入门教程(十三):2、初识多线程
- SDL入门教程(十三):2、初识多线程
- SDL入门教程(九):2、显示文本的完整代码
- SDL入门教程(九):2、显示文本的完整代码
- SDL入门教程(十三):1、多线程,从动画说起
- Rest服务实现返回List<Map>结果
- MySQL忘记密码怎么办?
- spring AOP 注解
- 树莓派源代码安装opencv
- JS通过get、post向jsp传递中文出现乱码的问题的解决
- SDL入门教程(四):2、SDL动画的硬件渲染(Hardware Render)
- 大数据视频学习目录
- Robot Framework自动化测试修炼宝典——互动出版网
- Android性能优化典范C2
- 集合_java集合框架
- 自己搭建ngrok服务
- IIS服务器配置出错
- 内存管理 ARC
- chrome不再支持dialog对话框,模仿对话框类似的效果