作者:龍飛
2.1:需要修改的地方。
這里,我們真正的開(kāi)始使用SDL的硬件渲染。首先,我們需要設(shè)置驅(qū)動(dòng)的環(huán)境(以windows為例,我們?cè)O(shè)置為directx,Linux的設(shè)置請(qǐng)參考官方網(wǎng)站,我們這里預(yù)留為dga)。另外,如果要啟動(dòng)硬件加速,必須使用全屏模式(SDL_FULLSCREEN),所以,在前面的軟件渲染中,我們也使用全屏以作對(duì)比。第三,硬件渲染需要打開(kāi)雙緩沖(SDL_DOUBLEBUF),至于為什么我們?cè)谧詈笥懻摚覀冞€是先看看完整的代碼。
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:?jiǎn)栴}。
你可能發(fā)現(xiàn)除了鼠標(biāo)指針不顯示之外,沒(méi)有其它問(wèn)題——這其實(shí)不是好現(xiàn)象,因?yàn)閼?yīng)該和可能出現(xiàn)的問(wèn)題,都被我們事先避免了,但是這樣讓我們離事情的本質(zhì)越來(lái)越遠(yuǎn)。你可以嘗試著關(guān)掉SDL_DOUBLEBUF位標(biāo)看看是什么效果;或者,在前面渲染單幀的程序中使用硬件渲染同時(shí)打開(kāi)雙緩沖看看出現(xiàn)什么問(wèn)題——這些正是我們下一節(jié)將要討論的。
如果你迫不及待的想知道原因,并且英語(yǔ)也過(guò)關(guān)的話,對(duì)于硬件渲染可能會(huì)引發(fā)的問(wèn)題,我給你推薦一篇SDL官方也推薦的論文:
http://www.linuxdevcenter.com/pub/a/linux/2003/08/07/sdl_anim.html 但是很不幸的是,我在試驗(yàn)的過(guò)程中發(fā)現(xiàn)這篇文章有很多問(wèn)題,當(dāng)然,也許是我錯(cuò)了。因?yàn)槲覂H僅把SDL作為了一個(gè)黑盒子來(lái)研究,但是我得到的試驗(yàn)結(jié)果,卻是不可能錯(cuò)的。
2.4:補(bǔ)充。
目前用Debian試驗(yàn)的時(shí)候,發(fā)現(xiàn)NVidia的顯卡驅(qū)動(dòng)屏蔽掉了dga的。也就是說(shuō)實(shí)際上用不了,或者會(huì)設(shè)置起來(lái)很麻煩。實(shí)際上,SDL通過(guò)x11來(lái)實(shí)現(xiàn)圖像,我目前的認(rèn)識(shí)應(yīng)該是這樣的:SDL->x11->NV驅(qū)動(dòng)->顯卡。所以,實(shí)際上我們雖然沒(méi)有通過(guò)SDL接觸到顯卡,但實(shí)際上還是通過(guò)種種渠道調(diào)用了顯卡,我們應(yīng)該充分相信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 閱讀(9508)
評(píng)論(6) 編輯 收藏 引用 所屬分類:
SDL入門教程