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