1. 程式人生 > >SDL 簡單入門學習

SDL 簡單入門學習

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及檔案

概要

實際學習使用SDL建立視窗,並繪製圖形。

前言   

    今天想要做一個簡單的demo,因為一部分需要使用objective C,所以還需要跨平臺,我才發現,我瞭解的東西還真沒有一個適合做這樣事情的,Cocos2D For IPhone僅僅能在IPhone下跑,HGE僅僅能在Windows下跑,Orx雖然能夠跨平臺,但是很顯然,用於做簡單的demo太麻煩了,因為我需要的僅僅是一個簡單的DrawBmp函式而已,Orx那種一使用就使用一套的做法不太適合,還能想到的就是OpenGL了,但是用OpenGL做跨平臺應用全靠自己那就挺麻煩了,還是找個框架吧。
    其實我有3個選擇,glut/free glut, SDL, GLFW。其中glut雖然在學習OpenGL的時候用過一些,但是因為該專案已經死了,我不想再為其投入更多的學習時間,瞭解到可以看懂其程式碼的水平(其實使用也很簡單),已經夠了。SDL是很多人推薦的選擇,我以前找工作的時候,國內的一家公司竟然直接提到過,說明其在國內也算是有人用了。我在那以後也看過SDL的API,感覺還算簡單,與HGE一樣,圖形顯示上,都是用了類似DirectDraw的抽象。(應該也是最通吃的抽象方式了)我對GLFW的感興趣是因為最近Orx的作者iarwain提到過,並且給予了很高的評價,他說對GLFW的輕量級印象非常深刻,在最新的Orx版本中,GLFW是Orx的預設外掛,並且就iarwain的測試,比SDL快5%左右(雖然不算太多),最重要的是,GLFW的封裝都很簡單,以直接使用OpenGL為主,借這個契機,我也順面複習一下OpenGL,最近老是用庫,我都快忘了該怎麼用了。
    兩相比較,我發現我不知道該用SDL還是GLFW,按我的習慣,兩個一起用先,嘗試一下再下結論。本文先看看SDL。

實際使用   

    其實我的需求很簡單,建立視窗,在制定的地方繪圖。簡單的說也就是類似於CreateWindows和DrawBmp的兩個函式而已。

    SDL其實真的算挺出名的了,也有人提到過,即使不真的準備使用SDL,但是想想一個庫,能夠被移植到這麼多平臺,抽象封裝的方式和原始碼起碼都值得研究研究。因為這個,我也稍微看一下,雖然真的不打算長期SDL。SDL的協議是LGPL的(也有商業協議),還算可以接受。
    環境的搭建還算簡單,Windows版本的SDL需要D3D SDK支援。
    簡單的參考了一下教程,顯示BMP圖片的過程還算簡單:
 1


 2 #include
 3 #include
 4 #include
 5 #include "SDL.h"
 6
 7 int _tmain(int argc, _TCHAR* argv[])
 8 {
 9   if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
10   {
11     printf("Unable to initialize SDL: %sn", SDL_GetError());
12
13     exit(1);
14   }
15   atexit(SDL_Quit);
16
17   //Load image
18   SDL_Surface* picture = SDL_LoadBMP( "dragon.bmp" );
19
20   SDL_Surface *screen = SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF);
21   if ( screen == NULL )
22   {
23     printf("Unable to set video mode: %sn", SDL_GetError());
24
25     exit(1);
26   }
27
28   //Apply image to screen
29   SDL_BlitSurface( picture, NULL, screen, NULL );
30
31   //Update Screen
32   SDL_Flip( screen );
33
34   //Pause
35   SDL_Delay( 2000 );
36
37   //Free the loaded image
38   SDL_FreeSurface( picture );
39
40     return 1;
41 }


這裡,可以看到,SDL沒有管理主迴圈,同時我沒有使用自己的主迴圈,那得牽涉到SDL的事件系統,所以,這個演示裡,用了SDL_Delay,才能看到圖片的顯示。這裡的顯示沒有指定大小,沒有指定alpha值,所以圖片原大顯示。SDL_BlitSurface函式的使用很像Windows API的對應函式。其他也沒有什麼好說的,看註釋及函式名就知道在幹什麼了。

然後,通過下述方式來設定想要的透明色(在沒有alpha通道的bmp中,也只能使用這樣蹩腳的color key方式了)
1
2   Uint32 colorKey = SDL_MapRGB(picture->format, 0xFF, 0xFF, 0xFF);
3   SDL_SetColorKey(picture, SDL_SRCCOLORKEY, colorKey);

其中0xFF,0xFF,0xFF分別是想要設定的顏色的R,G,B,這裡都是0xFF,那就是白色了。
於是,原圖:




在黑色背景下,周圍的白色都透明瞭,顯示出下列的效果:


說實話,用SDL的API還算比較簡單,使用的時候有點感覺時空穿越,有點回到當年學習使用Win32 API來做類似事情的時候。介面的概念都差不多,也許SDL的優勢比起當年的Win32 API僅在於速度和跨平臺了。
顯示兩個圖只需要再blit一次即可:
  //Apply image to screen
   SDL_BlitSurface( picture, NULL, screen, NULL );

   SDL_Rect dest;
   dest.x = picture->w;
   dest.y = 0;

   //Apply image to screen again and move it to right
   SDL_BlitSurface( picture, NULL, screen, &dest );

然後,加入SDL對主迴圈的控制。

   // main loop
   bool running = true;
   while (running) {
     //Update Screen
     SDL_Flip( screen );

     // delay, 50 for simple
     SDL_Delay( 50 );

     //While there's an event to handle
     SDL_Event event;
     while( SDL_PollEvent( &event ) ) {
       if (event.type == SDL_QUIT) {
         running = false;
       }
     }
   }

SDL_PollEvent用於輪詢SDL的事件。
於是,現在SDL建立的視窗可以被拖動,也可以點選關閉了。
想說的是,SDL真的很簡單,我看教程的時候基本上只需要看原始碼即可,就能瞭解大部分的意思。

    下面到關鍵的部分了,PNG的顯示,我看到,雖然SDL本身僅僅支援BMP,但是已經有人做了一個名叫SDL_Image的庫,可以支援其他格式。(考驗一個開源庫好不好,有沒有良好的第3方支援是很重要的方面,SDL這方面明顯很不錯)於是,我們就不用直接使用libpng了,個人不是很喜歡libpng的介面。。。。。
    不知道是不是秉承了SDL簡單的優良傳統,SDL_Image的使用也非常簡單,編譯好後,將裡面的動態庫(因為需要支援PNG,所以有libpng和zlib的動態庫)都拷貝到執行目錄裡面,然後包含"SDL_image.h"就可以了。從bmp到png的距離只有幾行程式碼。。。。。從我發現SDL_Image到真的載入顯示PNG圖片,也就過了不到10分鐘。。。。
全部原始碼:

#include
#include
#include
#include "SDL.h"
#include "SDL_image.h"
int _tmain(int argc, _TCHAR* argv[])
 {
   if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
   {
     printf("Unable to initialize SDL: %sn", SDL_GetError());

     exit(1);
   }
   if (IMG_Init(IMG_INIT_PNG) == 0 ) {
     printf("Unable to initialize SDL_image");

     exit(1);
   }
   atexit(SDL_Quit);

   //Load image
   //SDL_Surface* picture = SDL_LoadBMP( "dragon.bmp" );
   SDL_Surface* picture = IMG_Load("dragon.png");

   SDL_Surface *screen = SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF);
   if ( screen == NULL )
   {
     printf("Unable to set video mode: %sn", SDL_GetError());

     exit(1);
   }

   // because we use png with alpha now
   //Uint32 colorKey = SDL_MapRGB(picture->format, 0xFF, 0xFF, 0xFF);
   //SDL_SetColorKey(picture, SDL_SRCCOLORKEY, colorKey);

   //Apply image to screen
   SDL_BlitSurface( picture, NULL, screen, NULL );

   SDL_Rect dest;
   dest.x = picture->w;
   dest.y = 0;

   //Apply image to screen again and move it to right
   SDL_BlitSurface( picture, NULL, screen, &dest );

   // main loop
   bool running = true;
   while (running) {
     //Update Screen
     SDL_Flip( screen );

     // delay, 50 for simple
     SDL_Delay( 50 );

     //While there's an event to handle
     SDL_Event event;
     while( SDL_PollEvent( &event ) ) {
       if (event.type == SDL_QUIT) {
         running = false;
       }
     }
   }

   //Free the loaded image
   SDL_FreeSurface( picture );

     return 1;
 }

僅僅只有幾行修改,在程式碼中看的很清楚。

 

小結

    簡單,還是簡單,這是我學習SDL的最大感受,API設計的簡單,相關概念也簡單,SDL無愧於Simple DirectMedia Layer中的Simple一次。要想真的從OpenGL學習起,然後呼叫libpng來載入PNG影象並顯示,你得看到紅寶書的第十幾章,直到紋理貼圖的學習後你才能做到,但是,在SDL中做這些事情實在是太簡單了。即使與當年的Win32 API相比,也少了很多Windows特定的訊息迴圈原理等東西的學習,建立視窗的API比較起來,就會感覺MS那一幫人都是廢物,設計的視窗建立API,竟然需要用幾十行的程式碼去建立一個視窗,還需要註冊視窗類。。。。。。。。。。。事實上,只需要一行程式碼。。。。。。

    一般來說,一個比較流行的開源庫都是比較好的,因為好,才流行,因為流行而變的更好,其中,最最重要的關鍵在於,使用要簡單,太複雜難用的庫,無論設計的多麼精巧,都很難吸引到使用者,也就難以進入這個良性的迴圈,不得不說,SDL在這方面,做的是非常好了。

 

 

原創文章作者保留版權 轉載請註明原作者 並給出連結

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie





           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述