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;
}
浙公网安备 33010602011771号