青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 126,  comments - 73,  trackbacks - 0

  下文從使用SDL的編程函數開始,介紹了如何使用SDL在屏幕上進行象素繪制的基本知識,并給出了一個簡單的例子。

  如果要在VC中用SDL庫,必須在源文件頭部包含以下頭文件:

#include “SDL.h”

  初始化SDL是通過SDL_Init()函數來實現的。如果初始化失敗,函數返回值為0。函數只接受初始化對象作為參數。如果要初始化視頻屏幕,傳入常數SDL_INIT_VIDEO作為參數;初始化音頻,傳入常數SDL_INIT_AUDIO;如果同時初始化視頻和音頻,傳入SDL_INIT_VIDEO|SDL_INIT_AUDIO。其它還有一些量可以傳入作為參數的(如果同時傳入多個量要使用|將它們隔開):

SDL_INIT_TIMER
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_JOYSTICK
SDL_INIT_NOPARACHUATE
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;
}

  如果初始化失敗,則函數SDL_GetError()返回關于錯誤的一個字符串提示信息。

  當從你的C++語句返回時,記住使用SDL_Quit()進行程序的清理工作,否則就會出現奇怪的現象。可以使用如下語句進行描述:

atexit(SDL_Quit);

  這樣的話就不需要在main函數中每個return語句前加入SDL_Quit()了。

  在SDL中你可以擁有多個surface,每件物體都是一個surface。你可以在一個surface上進行繪圖或者在其他surface上繪制另外一個surface。程序中一個surface的表示即為指向結構SDL_Surface的指針。如果要獲得一個surface只要如下定義:

SDL_Surface *screen;

  如果需要對screen所指向的surface上進行繪圖,你可以使用函數SDL_SetVideoMode()來設置屏幕分辨率:

screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

  前三個參數分別為屏幕寬度,高度和屏幕上的每象素包含的位數(bits per pixel, BPP)。如果填入0則SDL自動選擇最合適的BPP。第四個參數用來給出某些特殊標志位。如果要在屏幕上進行圖形繪制就必須使用SDL_HWSURFACE或者SDL_SWSURFACE。以下給出了一個你可以指定的標志位:

  SDL_SWSURFACE:在系統內存中創建視頻Surface

  SDL_HWSURFACE:在視頻內存中創建視頻Surface

  SDL_ASYNCBLIT:允許在顯示surface上使用異步更新。在單CPU機器上會變慢,但在SMP系統上會有顯著的性能提升。

  SDL_ANYFORMAT:一般的,如果指定位數的bpp不可用,那么SDL就會模擬使用陰影surface。如果傳入SDL_ANYFORMAT就會阻止這樣做,并且不管色深強制使用視頻surface。

  SDL_HWPALETTE:給予SDL特許的畫盤的訪問權,使用這個標志位就不需要總是使用SDL_SetColors或者SDL_SetPalette來獲取所需的顏色。

  SDL_DOUBLEBUF:允許硬件雙緩沖;只是和SDL_HWSURFACE一起使用時比較有用。調用SDL_Flip將會flip整個緩沖并且更新屏幕。所有的繪制將會在當前未顯示的surface上發生。如果雙緩沖被允許,那么SDL_Flip將會對整個屏幕進行SDL_UpdateRect操作。

  SDL_FULLSCREEN:SDL將會嘗試使用全屏模式。如果硬件分辨率的調整由于某種情況無法完成,那么下一個稍高的分辨率將會被使用,并且顯示窗口將會處于一個黑色背景的中央。

  SDL_OPENGL:創建一個OPENGL rendering context。使用前必須已經使用SDL_GL_SetAttribute對OpenGL視頻屬性進行設置。

  SDL_OPENGLBLIT: 和上一個選項一樣創建一個 OPENGL rendering context, 但是允許使用正常的blitting操作。

  SDL_RESIZABLE; 創建一個可伸縮大小的窗口。當用戶調整窗口大小時,將會觸發一個SDL_VIDEORESIZE事件,SDL_SetVideoMode將會使用新大小作為參數再次被調用。

  SDL_NOFRAME: 如果可以的話,SDL_NOFRAME將會創建出一個沒有標題欄和邊界修飾的窗口,全屏方式自動設置此標志位。

  建議使用SDL_HWSURFACE | SDL_DOUBLEBUF,如果出現錯誤可以嘗試使用SDL_SWSURFACE。

  SDL_SetVideoMode如果操作成功,則返回一個指向SDL_Surface的指針,否則的話返回NULL。可以使用如下語句檢查發生的錯誤:

If ( screen == NULL )
{
 printf(“Unable to set 640x480 video: %s\n”, SDL_GetError());
 return 1;
}

  以上介紹了如何對SDL進行初始化,下面可以開始繪制了。但是還有一些需要注意的關鍵地方,首先是一些SDL使用的容易讓人產生迷惑的數據類型:

Uint8 – 相當于unsigned char
Uint16 – 16位(2字節) unsigned integer
Uint32 – 32位(4字節) unsigned integer
Uint64 - 64位(8字節) unsigned integer
Sint8 – 相當于signed char
Sint16 – 16位(2字節) signed integer
Sint32 – 32位(4字節) signed integer
Sint64 - 64位(8字節) signed integer

  還有,有的時候如果初始化出現錯誤,沒必要完全退出。例如當初始化了SDL_INIT_VIDEO而沒有初始化SDL_INIT_AUDIO,那么你可以繼續這個錯誤只是沒有音頻而已。要檢查是否音頻初始化是否成功,可以使用SDL_WasInit()函數來檢查。下面是一個例子:

Uint32 init = SDL_WasInit(SDL_INIT_AUDIO);
If (init & SDL_INIT_AUDIO)
{
 sound = 1;
} else {
 sound = 0;
}

  你可以在程序初始化的某些地方加入以上語句。

  以下是SDL介紹中進行象素繪制的語句,可以暫時不需要完全了解其中的意思:

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;
 }
}

  通過這個函數,可以傳遞給surface要繪制的點的(x,y)坐標和RGB值。
?  同時,由于繪制的屏幕不能同時接受兩個函數的同時操作,我們需要其他兩個輔助函數,用于在繪制前對屏幕進行鎖定,以及在繪制完成之后解除鎖定。這兩個工作一般由SDL_MUSTLOK(SDL_Surface *screen)和SDL_UnlockSurface(SDL_Surface *screen)完成。使用如下兩個自定義的函數會更加簡單:

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);
 }
}

  這樣,我們可以得到一個簡單的主程序框架如下:

#include <stdio.h>
#include <stdlib.h>
#include "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;
}

  如果對該程序進行編譯運行,那么只能得到一閃而過的一個黑色的窗口。我們需要對窗口進行繪制,并且對基本的鍵盤鼠標事件進行處理。

  繪制的基本原理是,先在緩沖區繪制,再一次性將緩沖區繪制到屏幕上。這樣比起一次一個象素點在屏幕上繪圖的方式效率更高,速度更快,也不易出錯。首先使用循環在screen所指向的surface(緩沖區)上繪制,然后調用SDL_Flip函數將screen surface繪制到真實電腦屏幕上。SDL_Flip函數的作用是:在支持雙緩沖(double-buffering)的硬件上,建立flip并返回。硬件將等待vertical retrace,然后在下一個視頻surface blit或者執行鎖定返回前交換視頻緩沖區。如果硬件不支持雙緩沖,那么等同于調用SDL_UpdateRect(screen, 0, 0, 0, 0),即對整個screen的繪制區域進行刷新。

void DrawScene(SDL_Surface *screen)
{
 Slock(screen);
 for(int x=0;x<640;x++)
 {
  for(int y=0;y<480;y++)
  {
   DrawPixel(screen, x,y,y/2,y/2,x/3);
  }
 }
 Sulock(screen);
 SDL_Flip(screen);
}

  在SDL中對采用結構SDL_Event來描述事件,并采用輪詢的機制對事件進行處理,程序中使用一個SDL_Event的實例(Instance)來檢查事件的發生:

SDL_Event event;

  輪詢采用while循環來檢查:

while ( SDL_PollEvent(&event))
{
 if ( event.type == SDL_QUIT)
 {
  //code here….
 }
 if ( event.type == SDL_KEYDOWN)
 {
  //code here….
 }
 //…..
}

  事件輪詢完畢之后,調用DrawScene(sreen)進行一次繪制。?

?????????本例中的源代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"

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);
 }
}
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;
 }
}
void DrawScene(SDL_Surface *screen)
{
 Slock(screen);
 for(int x=0;x<640;x++)
 {
  for(int y=0;y<480;y++)
  {
   DrawPixel(screen, x,y,y/2,y/2,x/3);
  }
 }
 Sulock(screen);
 SDL_Flip(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);
 }
 int done=0;
 while(done == 0)
 {
  SDL_Event event;
  while ( SDL_PollEvent(&event) )
  {
   if ( event.type == SDL_QUIT ) { done = 1; }
   if ( event.type == SDL_KEYDOWN )
   {
    if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
   }
  }
  DrawScene(screen);
 }
 return 0;
}

  程序運行結果如下:


posted on 2010-08-11 13:54 我風 閱讀(1248) 評論(0)  編輯 收藏 引用 所屬分類: SDL
<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

C++

MyFavorite

搜索

  •  

積分與排名

  • 積分 - 329147
  • 排名 - 76

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产午夜亚洲精品羞羞网站| 国产精品久久久久一区二区三区| 国产日韩欧美成人| 欧美中文字幕精品| 亚洲欧美国产精品桃花| 国产亚洲欧美日韩一区二区| 久久精品二区| 久久综合一区| 亚洲一区二区av电影| 亚洲欧美在线免费观看| 国产一区二区三区四区三区四| 欧美在线视频不卡| 久久久久久久网站| 日韩写真在线| 亚洲无线一线二线三线区别av| 国产欧美一区二区三区久久| 久久免费视频观看| 老牛嫩草一区二区三区日本| 亚洲视频在线播放| 久久精品国产第一区二区三区最新章节| 伊人久久大香线蕉综合热线| 最近中文字幕日韩精品 | 欧美日韩调教| 欧美伊人久久久久久久久影院| 久久久国产视频91| 在线一区二区日韩| 欧美一区二粉嫩精品国产一线天| 亚洲国产成人精品女人久久久 | 中文在线资源观看网站视频免费不卡 | 性久久久久久久久| 久久综合久久综合这里只有精品 | 亚洲激情av在线| 一区二区欧美视频| 精久久久久久| 在线一区亚洲| 亚洲日本va午夜在线电影| 亚洲影院高清在线| 亚洲精品在线视频| 欧美在线观看视频| 亚洲伊人色欲综合网| 鲁鲁狠狠狠7777一区二区| 午夜视频在线观看一区二区| 欧美精品v国产精品v日韩精品| 欧美一区亚洲二区| 欧美视频专区一二在线观看| 欧美国产日韩亚洲一区| 国产日韩亚洲| 亚洲亚洲精品三区日韩精品在线视频| 亚洲国产一区在线| 久久久久国产一区二区| 亚洲欧美一区二区三区久久| 欧美日韩国产成人高清视频| 欧美大片在线看| 红桃视频国产精品| 性感少妇一区| 午夜老司机精品| 国产精品草草| 99视频一区| 亚洲一二三级电影| 欧美日韩国产不卡| 亚洲精品日韩激情在线电影 | 韩国一区二区三区在线观看| 一区二区三区波多野结衣在线观看| 亚洲国产1区| 久久久综合免费视频| 久久精品最新地址| 国产一区二区看久久| 亚洲欧美日韩国产成人| 欧美一区二区日韩一区二区| 国产精品久久久久77777| 在线视频一区二区| 亚洲自拍都市欧美小说| 国产精品第三页| 亚洲一区二区免费视频| 香蕉成人久久| 国产主播在线一区| 久久久www| 欧美成人午夜| 一区二区三区 在线观看视频| 欧美人与禽性xxxxx杂性| 日韩视频精品在线观看| 亚洲一区制服诱惑| 国产亚洲欧洲997久久综合| 久久精品综合网| 欧美激情精品久久久六区热门 | 在线日韩中文字幕| 欧美不卡视频一区发布| 99视频在线精品国自产拍免费观看| 亚洲在线免费视频| 国产一区亚洲| 欧美福利电影网| 在线一区二区三区做爰视频网站| 欧美一区二区三区四区在线观看地址 | 亚洲精品在线电影| 欧美日韩综合| 欧美一区二区三区视频| 欧美韩日一区| 午夜精品久久| 亚洲黄页视频免费观看| 欧美了一区在线观看| 亚洲嫩草精品久久| 欧美黄色一区| 欧美一区二区三区视频免费| 一区在线观看视频| 欧美日韩综合精品| 久久精品国产免费看久久精品| 亚洲韩国精品一区| 欧美在线视频一区二区| 最新成人av在线| 国产日韩亚洲欧美精品| 欧美精品18videos性欧美| 香蕉乱码成人久久天堂爱免费 | 亚洲一区二区在线看| 国户精品久久久久久久久久久不卡| 久久亚洲国产精品日日av夜夜| 日韩视频永久免费| 免费在线亚洲| 久久国产高清| 国产精品99久久久久久www| 国产综合香蕉五月婷在线| 欧美精品日韩综合在线| 久久久久久高潮国产精品视| 一区二区欧美激情| 亚洲国产精品成人综合色在线婷婷 | 国产欧美综合一区二区三区| 欧美日韩国产bt| 农村妇女精品| 久久久久久久综合日本| 亚洲综合色噜噜狠狠| 亚洲精品一线二线三线无人区| 免费国产一区二区| 久久精品欧美| 欧美专区亚洲专区| 亚洲欧美国产日韩天堂区| 99视频精品全国免费| 亚洲激情偷拍| 亚洲国产一二三| 亚洲国产91精品在线观看| 国产在线拍偷自揄拍精品| 国产精品一区二区你懂的| 欧美午夜理伦三级在线观看| 欧美精品自拍| 欧美乱妇高清无乱码| 欧美国产精品v| 欧美不卡视频一区发布| 免费欧美网站| 欧美xx69| 欧美日韩日日夜夜| 欧美日韩精品| 欧美日韩一区二区在线视频| 欧美金8天国| 欧美日韩国产成人在线免费| 欧美日韩亚洲一区三区| 欧美三区在线视频| 国产精品久久久久久久久久直播| 欧美日韩国产色站一区二区三区| 欧美日韩高清在线| 国产精品v片在线观看不卡| 国产精品日韩欧美综合| 国产日韩欧美中文在线播放| 国产一区二区三区免费在线观看| 国产亚洲精品自拍| 亚洲电影av| 99精品热视频只有精品10| 亚洲视频图片小说| 性欧美暴力猛交69hd| 久久久久欧美| 欧美激情精品| 国产精品99久久久久久白浆小说| 亚洲欧美激情一区二区| 久久精品国产99精品国产亚洲性色 | 欧美 日韩 国产精品免费观看| 亚洲成色777777在线观看影院| 欧美国产三级| 日韩视频在线你懂得| 亚洲欧美日韩中文播放| 久久一区二区三区四区| 欧美激情视频在线播放| 国产精品影音先锋| 亚洲国产一区在线观看| 亚洲综合精品一区二区| 久久久久成人精品| 亚洲国产精品专区久久| 亚洲制服av| 久久中文精品| 国产精品久久久一区二区三区| 国内在线观看一区二区三区| 日韩视频久久| 久久综合九色欧美综合狠狠| 亚洲精品久久久久久久久| 亚洲免费人成在线视频观看| 久久夜精品va视频免费观看| 欧美午夜一区二区| 亚洲激情中文1区| 欧美一区国产在线| 亚洲精品视频在线播放| 久久久精品性| 国产精自产拍久久久久久| 亚洲欧洲一区二区天堂久久 | 在线观看视频一区二区|