SDL之三显示一张bmp图

转自: https://blog.csdn.net/lf426/article/details/2086646

1.1 再次使用函数

SDL_Surface *SDL_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags);

1) 在这里,我们使用的flag(s)仍然是SDL_SWSURFACE。它的作用是说明所建立的surface是储存在系统内存中的。实际上,SDL_SWSURFACE是一个“伪位标”,如果你读出它的值,会发现其实是0!

这意味着任何其他位标(以及|组合)与SDL_SWSURFACE的&结果都是0。这个事实的另外一层含义是,surface的数据“至少”会被储存在系统内存中——对立面的意思是,

这些数据有可能储存在显存中(指定使用显存储存数据的位标是SDL_HWSURFACE,它的值是1)。

2) SDL_Surface结构包含了一个surface的数据结构,包括宽,高和每个像素点的具体颜色等等。

3) width和height是你希望建立的窗口的宽与高。如果值为0,则建立与你当前桌面等宽高的窗口。

4) bitsperpixel是这个窗口的颜色位深。当前的硬件环境下,相信你的桌面也是32位色的。如果这个值为0,则所建立的窗口使用你当前桌面的位深。

const int SCREEN_WIDTH = 640;    // 0 means use current width.   

const int SCREEN_HEIGHT = 480;    // 0 means use current height.   

const int SCREEN_BPP = 32;        // 0 means use current bpp.   

const Uint32 SCREEN_FLAGS = SDL_SWSURFACE;    // SDL_SWSURFACE == 0,surface in system memory.   

SDL_Surface* pScreen = 0;   

pScreen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SCREEN_FLAGS);    // Creat a SDL window, and get the window's surface.   

try {       

  if ( pScreen == 0 )           

    throw SDL_GetError();   

}   

catch ( const char* s ) {       

  std::cerr << "SDL_SetVideoMode() failed!/n" << s << std::endl;          

  SDL_Quit();       

  return -1;   

}

 

1.2 装载BMP格式的位图

SDL_Surface *SDL_LoadBMP(const char *file);

如果我们使用std::string objName传值的时候,需要使用objName.c_str()(请注意objName.data()没有'/0'),把std::string类转化为C风格字符串。

这个函数把一个BMP位图转化成为SDL的surface数据结构方式(SDL_Surface结构),储存在系统内存中(我没找到任何信息可以说明能直接储存到显存中),并返回这个surface的指针。

如果返回的指针为空,说明函数调用失败了。

SDL_Surface* pShownBMP = 0;   

pShownBMP = SDL_LoadBMP("helloworld.bmp"); // Load a BMP file, and convert it as a surface.   

try {       

  if ( pShownBMP == 0 )           

    throw SDL_GetError();   

}   

catch ( const char* s ) {       

  std::cerr << "SDL_LoadBMP() failed!/n" << s << std::endl;       

  SDL_Quit();       

  return -1;   

}

 

1.3 块移图面blit surface

int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);

1) src指的是要进行blit的源surface,dst指的是blit这个surface要去的目的地——另外一个surface。

我们这里先忽略SDL_Rect结构的具体意思,仅仅需要了解的是,如果srcrect为空指针,意味着整个源surface将被blit;

如果dstrect为空指针,意味着源surface与目的surface的左上角重合(坐标(0,0))。       

2) blit是个有渊源的词语,我将来会在术语解释中具体提到。这个词的本意就是块(block)移动(transfer)的缩写blt,因为这个缩写缺少元音不好读,所以后来加上了i,就变成blit。       

如果blit成功,则返回0;否则返回-1。

SDL_Rect* pSrcRect = 0;    // If pSrcRect is NULL, the entire source surface is copied.     

SDL_Rect* pDstRect = 0;    // If pDstRect is NULL, then the destination position (upper left corner) is (0, 0).   

try {       

  if ( SDL_BlitSurface(pShownBMP, pSrcRect, pScreen, pDstRect) != 0 )    // Put the BMP's surface on the SDL window's surface.           

    throw SDL_GetError();   

}   

catch ( const char* s ) {       

  std::cerr << "SDL_BlitSurface() failed!/n" << s << std::endl;       

  SDL_Quit();       

  return -1;   

}

 

1.4 显示图片

之前对surface的种种操作,实际上都是在修改surface数据结构中的某些数据,当我们最后需要将这些surface显示到屏幕上(我们打开的SDL操作窗口上),我们需要使用函数SDL_Flip()。

int SDL_Flip(SDL_Surface *screen);

如果函数调用成功,则返回0;否则返回-1。

try {       

  if ( SDL_Flip(pScreen) != 0 )    // Show the SDL window's surface.           

    throw SDL_GetError();   

}   

catch ( const char* s ) {       

  std::cerr << "SDL_Flip() failed!/n" << s << std::endl;       

  SDL_Quit();       

  return -1;   

}

 

1.5 完整代码如下: 

#include <iostream>
#include "SDL2/SDL.h"
void pressESCtoQuit();
int main(int argc, char* argv[]){
  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;    // 0 means use current width.  
 const int SCREEN_HEIGHT = 480;    // 0 means use current height.   
 const int SCREEN_BPP = 32;        // 0 means use current bpp.   
 const Uint32 SCREEN_FLAGS = SDL_SWSURFACE;    // SDL_SWSURFACE == 0,surface in system memory.   
 SDL_Surface* pScreen = 0;   
 //Creat a SDL window, and get the window's surface.   
 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;   
  }   
  SDL_Surface* pShownBMP = 0;   
  pShownBMP = SDL_LoadBMP("helloworld.bmp"); // Load a BMP file, and convert it as a surface.   
  try {       
    if ( pShownBMP == 0 )           
    throw SDL_GetError();   
  }   
  catch ( const char* s ) {       
    std::cerr << "SDL_LoadBMP() failed!/n" << s << std::endl;       
    SDL_Quit();       
    return -1;   
  }   
  SDL_Rect* pSrcRect = 0;    // If pSrcRect is NULL, the entire source surface is copied.     
   // If pDstRect is NULL, then the destination position (upper left corner) is (0, 0).   
  SDL_Rect* pDstRect = 0;
  try {       
    // Put the BMP's surface on the SDL window's surface.           
    if ( SDL_BlitSurface(pShownBMP, pSrcRect, pScreen, pDstRect) != 0 )   
    throw SDL_GetError();   
  }   
  catch ( const char* s ) {       
    std::cerr << "SDL_BlitSurface() failed!/n" << s << std::endl;       
    SDL_Quit();       
    return -1;   
  }   
  try {       
    if ( SDL_Flip(pScreen) != 0 )    // Show the SDL window's surface.           
    throw SDL_GetError();   
  }   
  catch ( const char* s ) {       
    std::cerr << "SDL_Flip() failed!/n" << s << std::endl;       
    SDL_Quit();       
    return -1;   
  }   
  pressESCtoQuit();   
  SDL_Quit();   
  return 0;
}

void pressESCtoQuit(){   
  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;               
        }           
      }       
    }   
   }   
   return;
}

posted @ 2019-05-07 13:34  HenryLiuY  阅读(248)  评论(0)    收藏  举报