?? sdl很好的教程.txt
字號(hào):
GFX with SDL Lesson 1: Getting started with SDL(翻譯)
GFX with SDL
Lesson 1: Getting started with SDL
作者:Marius Andra
翻譯:heroboy
歡迎來(lái)到“GFX with SDL”的第一篇教程。
在Dev-C++中使用SDL
首先需要下載sdlDevCPP-1.2.4.zip(點(diǎn)擊名稱下載)。把zip文件解壓到Dev C++的目錄中,請(qǐng)確定include和lib文件夾(zip文件中)中的文件解壓到Dev C++中的include和lib文件夾中。我計(jì)算機(jī)上的Dev-C++文件夾是c:\Dev-C++。所以解壓以后,在c:\Dev-C++\lib會(huì)有l(wèi)ibSDL.a,libSDL.la,libSDLmain.a和SDL.dll,在c:\Dev-C++\include\SDL中會(huì)有一些 .h文件。
現(xiàn)在,在Dev-C++中新建一個(gè)控制臺(tái)工程。打開(kāi)“工程屬性”對(duì)話框(在“工程”菜單中)。在參數(shù)中,點(diǎn)擊“加入庫(kù)或者對(duì)象”按鈕,選擇libSDL.a,SDLmain.a和ligmingw32.a 三個(gè)文件。點(diǎn)擊“確定”。
最后,在SDL項(xiàng)目中使用printf(…)或輸出到stdout.txt中,而非屏幕。
在 Microsoft Visual C++ 6.0中使用SDL
要在MSVC6中使用SDL要下載SDL-devel-1.2.4-VC6.zip(請(qǐng)?jiān)L問(wèn)www.libsdl.org下載更新版本的SDL)。在這個(gè)壓縮文件中有兩個(gè)重要的文件夾-include和lib,把lib文件夾中的文件復(fù)制到MSVC6的lib文件夾中(在我的機(jī)器上是C:\Program Files\Microsoft Visual Studio\VC98\Lib),在MSVC6的include文件夾中新建一個(gè)SDL文件夾(在我的機(jī)器上是C:\Program Files\Microsoft Visual Studio\VC98\Include\SDL),把壓縮文件中include文件夾中的.h文件復(fù)制到新建的文件夾中。
現(xiàn)在,在VC++中新建一個(gè)工程。選擇“WIN32 Application”和“'an empty project”。現(xiàn)在要為工程創(chuàng)建一個(gè)cpp文件,單擊File-〉new并選擇 “c++ source file”,名字輸入“main.cpp”。現(xiàn)在打開(kāi)工程選項(xiàng)對(duì)話框(菜單project->settings)。點(diǎn)擊“LINK”欄,添加 “sdl.lib sdlmain.lib”到連接文件中(Object/library modules)。最后,點(diǎn)擊“C/C++”欄,在下拉菜單中選擇“Code Generation”。然后在“Use run-time library”下拉框中選擇“Multithreaded DLL”。
SDL.dll
SDL.dll是SDL中一個(gè)重要的文件(它在Dev-C++或MSVC6的SDL zip文件里)。如果你要運(yùn)行SDL程序,你必須把SDL.dll復(fù)制到c:\windows\system (win 95, 98, ME) 或 c:\windows\system32 (on windows NT, 2000 and XP)。或者SDL.dll和你的程序在同一個(gè)文件夾。
Getting started with SDL
你已經(jīng)設(shè)置好了一切。你要象下面一樣在你的程序中包含 SDL/SDL.h 文件:
#include <SDL/SDL.h>
通過(guò)SDL_Init()函數(shù)初始化SDL。SDL_Init的返回值下于0表示出錯(cuò)。它接受一個(gè)參數(shù),初始化的內(nèi)容。SDL_INIT_VIDEO初始化視頻,SDL_INIT_AUDIO初始化音頻。要初始化音頻和視頻,使用SDL_INIT_VIDEO|SDL_INIT_AUDIO。可以初始化更多如下的項(xiàng)目(要同時(shí)初始化,請(qǐng)使用 | 分割他們):
SDL_INIT_TIMER
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_JOYSTICK
SDL_INIT_NOPARACHUTE
SDL_INIT_EVENTTHREAD
SDL_INIT_EVERYTHING
因此,初始化視頻和音頻的代碼是:
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) <0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
return 1;
}
如果出錯(cuò)了,SDL_GetError()函數(shù)返回一個(gè)字符串來(lái)描述這個(gè)錯(cuò)誤。
但退出程序時(shí),你必須調(diào)用SDL_Quit()。如果沒(méi)有調(diào)用的話,可能會(huì)出現(xiàn)一些異常的現(xiàn)象。告訴編譯器你要在退出時(shí)調(diào)用SDL_Quit,代碼如下:
atexit(SDL_Quit);
那樣就不需要在main函數(shù)中的每個(gè)return前加上SDL_Quit()了。
在SDL中需要很多的surface。一切都是surface。你可以在surface上繪圖,也可以把一個(gè)surface畫(huà)到另一個(gè)surface上。在SDL中,屏幕也是一個(gè)surface。在我們的程序中surface是一個(gè)指向SDL_Surface結(jié)構(gòu)的指針。如下得到屏幕surface:
SDL_Surface *screen;
相信你在玩有些游戲的時(shí)候會(huì)要你選擇屏幕分辨率。如果沒(méi)有的話,請(qǐng)玩更多的游戲。如果你要使用surface屏幕(surface screen)(記住,screen只是一個(gè)指向SDL_Surface結(jié)構(gòu)的指針),在上面繪圖(你在監(jiān)視器上可以看到畫(huà)了什么),那么使用SDL_SetVideoMode()函數(shù)。
screen = SDL_SetVideoMode(640, 480, 32,
SDL_HWSURFACE|SDL_DOUBLEBUF);
前三個(gè)參數(shù)分別是屏幕的 寬度,高度和像素位數(shù)bits per pixel)。如果像素位數(shù)為0,SDL會(huì)為你自動(dòng)選擇最合適的位數(shù)。第四個(gè)參數(shù)是一些特殊的標(biāo)記。如果要在屏幕上繪圖的話,必須有SDL_HWSURFACE(或SDL_SWSURFACE)。下列是可用的選項(xiàng):
SDL_SWSURFACE – 在系統(tǒng)內(nèi)存中創(chuàng)建surface
SDL_HWSURFACE – 在顯示內(nèi)存中創(chuàng)建surface
SDL_ASYNCBLIT – 允許異步刷新的surface。這會(huì)降低在單CPU上的位拷貝(blitting)的速度,但在SMP系統(tǒng)上速度會(huì)有提升。
SDL_ANYFORMAT - 一般地,如果給與的像素位數(shù)(bits-per-pixel,bpp)不可用的話,SDL回使用影子surface(shadow surface)模擬。SDL_ANYFORMAT會(huì)阻止這么做,而忽略參數(shù)中的像素位數(shù)。
SDL_HWPALETTE –給予SDL 獨(dú)立的調(diào)色板訪問(wèn)(exclusive palette access)。沒(méi)有這個(gè)選項(xiàng),你不能通過(guò)SDL_SetColors或SDL_SetPalette來(lái)獲取顏色。
SDL_DOUBLEBUF –允許硬件雙緩沖。只有和SDL_HWSURFACE一起使用才有效。調(diào)用SDL_Flip來(lái)翻轉(zhuǎn)(flip)緩沖并刷新屏幕。所有的繪圖不會(huì)立即顯示在屏幕上。如果不允許雙緩沖的話,SDL_Flip函數(shù)相當(dāng)于對(duì)整個(gè)屏幕調(diào)用SDL_UpdateRect。
SDL_FULLSCREEN – SDL會(huì)嘗試使用全屏模式。如果硬件不支持當(dāng)前的分辨率的話,會(huì)使用一個(gè)更高的分辨率和黑色的背景。
SDL_OPENGL –創(chuàng)建OpenGL渲染上下文(rendering context)。你應(yīng)該預(yù)先使用SDL_GL_SetAttribute設(shè)置OpenGL視頻屬性。
SDL_OPENGLBLIT -創(chuàng)建OpenGL渲染上下文(rendering context),但使用普通的位拷貝(blitting)操作。屏幕surface(2D)會(huì)有一個(gè)alpha通道,并且必須使用SDL_UpdateRects來(lái)更新屏幕surface。
SDL_RESIZABLE –創(chuàng)建可縮放的窗口。當(dāng)縮放的時(shí)候,會(huì)產(chǎn)生SDL_VIDEORESIZE事件,此時(shí)可通過(guò)SDL_SetVideoMode再次改變屏幕surface大小。
SDL_NOFRAME - 如果可行的話,SDL會(huì)創(chuàng)建無(wú)框架無(wú)標(biāo)題欄的窗口。全屏模式自動(dòng)包含此選項(xiàng)。
我的建議是:使用 SDL_HWSURFACE|SDL_DOUBLEBUF。如果出錯(cuò)的話,使用SDL_SWSURFACE.
SDL_SetVideoMode 返回指向SDL_Surface的指針,出錯(cuò)的話返回NULL。使用如下代碼檢測(cè)出錯(cuò):
if ( screen == NULL )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
return 1;
}
至此已經(jīng)初始化了SDL,可以開(kāi)始繪圖了。在開(kāi)始繪圖前,我要告訴你一些SDL的數(shù)據(jù)類型。他們是:
Uint8 – 相當(dāng)于unsigned char
Uint16 – 16位(2字節(jié))無(wú)符號(hào)整形
Uint32 - 32位(4字節(jié)) 無(wú)符號(hào)整形
Uint64 - 64位(8字節(jié)) 無(wú)符號(hào)整形
Sint8 - 相當(dāng)于 signed char
Sint16 - 16位(2字節(jié)) 有符號(hào)整形
Sint32 - 32位(4字節(jié)) 有符號(hào)整形
Sint64 - 64位(8字節(jié)) 有符號(hào)整形
另外,無(wú)論何時(shí)初始化出錯(cuò)的時(shí)候,你不必完全退出。例如,SDL_INIT_VIDEO初始化成功,而SDL_INIT_AUDIO失敗的話,你仍然可以繼續(xù)運(yùn)行程序,只是沒(méi)有聲音。為了檢測(cè)音頻是否初始化成功,使用SDL_WasInit()函數(shù)。代碼如下:
Uint32 init = SDL_WasInit(SDL_INIT_AUDIO);
if(init & SDL_INIT_AUDIO)
{
sound = 1; // Audio init sucessful, use sound
} else {
sound = 0; // Audio init unsucessful, don't use sound
}
你可以在如下代碼中插入上述代碼
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) <0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
return 1;
}
為簡(jiǎn)單起見(jiàn),我不在教程中插入此代碼。
繪制像素乍看是很簡(jiǎn)單的,但如果你看了此函數(shù)的話其實(shí)并不簡(jiǎn)單。我使用的這個(gè)像素繪制函數(shù),取自SDL intro(www.libsdl.org上的)。如下:
注意:你不必完全理解它,只要使用就可以了
void DrawPixel(SDL_Surface *screen, int x, int y,
Uint8 R, Uint8 G, Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
switch (screen->format->BytesPerPixel)
{
case 1: // Assuming 8-bpp
{
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2: // Probably 15-bpp or 16-bpp
{
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
}
break;
case 3: // Slow 24-bpp mode, usually not used
{
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
bufp[0] = color;
bufp[1] = color >> 8;
bufp[2] = color >> 16;
} else {
bufp[2] = color;
bufp[1] = color >> 8;
bufp[0] = color >> 16;
}
}
break;
case 4: // Probably 32-bpp
{
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp = color;
}
break;
}
}
傳遞一個(gè)你想繪圖的surface,x軸,y軸坐標(biāo)和RGB顏色就可以了。
另外需要兩個(gè)重要的函數(shù)。一些顯卡,需要在繪圖前鎖定它。SDL_MUSTLOCK(SDL_Surface *screen)用來(lái)確定是否需要鎖定屏幕。SDL_LockSurface(SDL_Surface *screen)和SDL_UnlockSurface(SDL_Surface *screen)用來(lái)鎖定和解鎖。函數(shù)代碼如下:
void Slock(SDL_Surface *screen)
{
if ( SDL_MUSTLOCK(screen) )
{
if ( SDL_LockSurface(screen) < 0 )
{
return;
}
}
}
void Sulock(SDL_Surface *screen)
{
if ( SDL_MUSTLOCK(screen) )
{
SDL_UnlockSurface(screen);
}
}
調(diào)用 Slock(screen)鎖定屏幕, Sulock(screen)解鎖。
現(xiàn)在,代碼應(yīng)該如下:
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
// The functions are not shown to save space
void DrawPixel(SDL_Surface *screen, int x, int y,
Uint8 R, Uint8 G, Uint8 B);
void Slock(SDL_Surface *screen);
void Sulock(SDL_Surface *screen);
int main(int argc, char *argv[])
{
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
SDL_Surface *screen;
screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
if ( screen == NULL )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
exit(1);
}
// DRAWING GOES HERE
return 0;
}
運(yùn)行一下。你會(huì)發(fā)現(xiàn),一個(gè)空窗口閃了一下。加入SDL_FULLSCREEN標(biāo)記,會(huì)看見(jiàn)一個(gè)黑屏。現(xiàn)在,讓我們繪圖。
我們來(lái)做一個(gè)簡(jiǎn)單的繪圖:我們把所有的東西都繪制在一個(gè)緩沖上,再把緩沖畫(huà)到屏幕上。這比直接在屏幕上繪制像素簡(jiǎn)單,速度快,而且沒(méi)有閃爍。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -