VC++ C++ C# Algorithm

C++博客 首页 新随笔 联系 聚合 管理
  21 Posts :: 3 Stories :: 31 Comments :: 0 Trackbacks

 

我们可以把表面想象成一张画布, blit 表面就是把一个表面的某个区域 COPY 到另外一个表面上去。

//The headers

#include " SDL.h"

#include <string>

以上就是我们需要的头文件了。

//The attributes of the screen

const int SCREEN_WIDTH = 640;

const int SCREEN_HEIGHT = 480;

const int SCREEN_BPP = 32;

3 个描述屏幕属性的变量

SCREEN_BPP 是颜色深度,就是每个象素用多少为来表示,我们这里用 4 个字节。

//The surfaces that will be used

SDL_Surface *message = NULL;

SDL_Surface *background = NULL;

SDL_Surface *screen = NULL;

接着我们又定义了 3 个表面,一个用于显示背景,一个用于显示 Hello World ,还有一个当然是代表屏幕了。

SDL_Surface *load_image( std::string filename )

{

    //Temporary storage for the image that's loaded

    SDL_Surface* loadedImage = NULL;

   

    //The optimized image that will be used

SDL_Surface* optimizedImage = NULL;

好了,我们可以写一个自己的图像装载函数,该函数负责 Load 图片,并返回一个经过优化的表面,当然图片已经在表面上了。

//Load the image

    loadedImage = SDL_LoadBMP( filename.c_str() );

首先我们使用 SDL_LoadBMP() 函数 Load 一张 BMP 格式的图片。应为位图是 24 位,所以我们不应该立即使用该表面,因为屏幕是 32 位的。如果在二各具有不同 format 表面进行 Blit ,那么 SDL 将会不停地进行格式之间的转换,程序就会变得很慢。 .

 

    if( loadedImage != NULL )

    {

        //Create an optimized image

        optimizedImage = SDL_DisplayFormat( loadedImage );

       

        //Free the old image

        SDL_FreeSurface( loadedImage );

}

以上几行代码检查了图片是否被正确加载了,如果有错误的话,那么 loadedImage 将是 NULL

SDL_DisplayFormat() 用于创建一个和屏幕表面相同格式的 Surface 。之所以这样做就是为了加快程序速度,避免 SDL 类库在对二个不同格式表面进行 Blit 时进行格式转换。

 

好了,现在我们拥有二个表面了,一个上面有图片,还有一个是前一个经过格式转换得到的。

 

displayformat.jpg
freesurface.jpg

 

因为第一表面我们不需要了,所以我们就要释放掉, SDL_FreeSurface() 函数就是干这件事情的。

    //Return the optimized image

    return optimizedImage;

}

好了,我们返回经过优化的表面。

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )

{

    //Make a temporary rectangle to hold the offsets

    SDL_Rect offset;

   

    //Give the offsets to the rectangle

    offset.x = x;

offset.y = y;

接下来,我们再写一个 Blit 函数。 X,Y 是目标表面的偏移量,另外二个自然是要进行 Blit 的二个表面了。

首先我们把偏移量塞入到一个 SDL_Rect 变量里面,这样做的原因很简单,就是 SDL_BlitSurface 只接受 SDL_Rect 结构中的偏移。

SDL_Rect 结构代表一个长方形 . 它有四个成员,左上角的坐标,长和宽。

    //Blit the surface

    SDL_BlitSurface( source, NULL, destination, &offset );

}

好了,调用 SDL_BlitSurface 实现 Blit 。第二个参数是源表面的要被 Blit 的区域,我们用 NULL 表示要对整个源表面进行 Blit

int main( int argc, char* args[] )

{

    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )

    {

        return 1;   

    }

SDL_Init() 函数中,我们使用 SDL_INIT_EVERYTHING 参数,表示我们希望启动所有 SDL 子系统,其中包括,视频,声音,时间,以及其他一些制作游戏所用到的组建。

   screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

现在我们用 SDL_SetVideoMode 函数新建一个窗口,它返回一个指向窗口表面的指针,这样我们就可以把图像往屏幕上 Blit 了。

 

    if( screen == NULL )

    {

        return 1;   

    }

如果函数有问题的话,就返回 NULL 。下面我们也可以改变一下窗口的标题。     SDL_WM_SetCaption( "Hello World", NULL );

   message = load_image( "hello_world.bmp" );

   background = load_image( "background.bmp" );

   apply_surface( 0, 0, background, screen );

现在我们把背景 Blit 到屏幕上,在 Blit 背景之前,窗口是黑色,如下图。

 blank.jpg

 

再这之后,窗口的背景就改变了。
background.jpg

用同样的方法,我们把 message Blit 到屏幕上去。

apply_surface( 180, 140, message, screen );

 

    if( SDL_Flip( screen ) == -1 )

    {

        return 1;   

    }

虽然我们把背景表面和消息表面都 Blit 到屏幕表面上去了,窗口还是一片漆黑,因为我们没有调用 SDL_Flip 函数来更新窗口,记住,屏幕表面是建立在系统内存当中的。

  SDL_Delay( 2000 );

好了,让窗口停顿二秒,以免我们什么也不到。

    //Free the surfaces

    SDL_FreeSurface( message );

    SDL_FreeSurface( background );

   

    //Quit SDL

    SDL_Quit();

   

    //Return

    return 0;

}

好了,我们的主函数也写完了,最后我释放了二个表面,并调用了 SDL_Quit 函数,清理我们所使用到其他资源。

 

好了,运行一下程序,你不意外你就能看到如下的效果了。如果有什么错误的话,看看第一个教程。
coorddemo.jpg

posted on 2007-03-05 19:00 大熊猫 阅读(838) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理