VC++ C++ C# Algorithm

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

#

SDL本身只支持加载BMP文件,如果你想显示其他类型的图像文件,就要用到扩展类库,扩展类库里面还有其他一些组件,你可以在这里下载到 http://www.libsdl.org/projects/SDL_image/
下载完以后,按照教程一配置,我们就可以显示一张PNG图片了。
以下是具体的代码,与教程二很相似,如有疑问请参考教程二。
#include 
" SDL.h "

#include 
< SDL_image.h >
#include 
< string >
SDL_Surface 
* screen;
SDL_Surface 
*
background;
SDL_Surface 
* load_image( std:: string
 filename ) 
{
    
// The image that's loaded

    SDL_Surface *  loadedImage  =  NULL;

    
// The optimized image that will be used

    SDL_Surface *  optimizedImage  =  NULL;

    
// Load the image using SDL_image

    loadedImage  =  IMG_Load( filename.c_str() );

    
// If the image loaded

     if ( loadedImage  !=  NULL )
    
{
        
// Create an optimized image

        optimizedImage  =  SDL_DisplayFormat( loadedImage );

        
// Free the old image

        SDL_FreeSurface( loadedImage );
    }


    
// Return the optimized image
     return  optimizedImage;
}

void  apply_surface( int  x, int  y,SDL_Surface  * source ,SDL_Surface  * destinaion)
{
    SDL_Rect rect;
    rect.x
=
x;
    rect.y
=
y;
    SDL_BlitSurface(source,NULL,destinaion,
&
rect);

}

int  main(  int  argc,  char *  args[] )
{
    
// Start SDL

    SDL_Init( SDL_INIT_EVERYTHING );

    
// Quit SDL

    screen = SDL_SetVideoMode( 640 , 480 , 32 ,SDL_SWSURFACE);
    background
= load_image( " Dockxrt5.jpg "
);

    apply_surface(
0 , 0
,background,screen);

    
if (SDL_Flip(screen) ==- 1
)
        
return   - 1
;
    SDL_FreeSurface(background);
    SDL_Delay(
2000
);
    SDL_FreeSurface(background);
    SDL_Quit();

    
return   0
;    
}

以下代码用SDL_TTF扩展类库加载一个TTF字体文件,并用该字体显示一段文字。
 1 #include  " SDL.h "
 2 #include  < SDL_ttf.h >
 3 #include  < string >
 4 SDL_Surface  * screen;
 5 SDL_Surface  *
background;
 6 void  apply_surface( int  x, int  y,SDL_Surface  * source ,SDL_Surface  *
destinaion)
 7
{
 8
    SDL_Rect rect;
 9     rect.x =
x;
10     rect.y =
y;
11     SDL_BlitSurface(source,NULL,destinaion, &
rect);
12

13 }

14 int  main(  int  argc,  char *  args[] )
15
{
16      // Start SDL

17
18     SDL_Init( SDL_INIT_EVERYTHING );
19      if (TTF_Init() ==- 1
)
20          return   - 1
;
21     TTF_Font  * font =
NULL;
22     font = TTF_OpenFont( " verdana.ttf " , 14
);
23      if (font  ==
 NULL)
24          return   - 1
;
25

26      // Quit SDL

27     SDL_Color textColor = { 255 , 255 , 255 } ;
28     SDL_Color textBgColor = { 0 , 0 , 0 ,}
;
29     screen = SDL_SetVideoMode( 640 , 480 , 32
,SDL_SWSURFACE);
30     background = TTF_RenderText_Blended( font,  " why it can not display chinese "
, textColor);
31

32     apply_surface( 0 , 0
,background,screen);
33

34      if (SDL_Flip(screen) ==- 1
)
35          return   - 1
;
36

37     SDL_Delay( 100000
);
38
    SDL_Quit();
39

40      return   0
;    
41 }

42
posted @ 2007-03-05 22:30 大熊猫 阅读(3428) | 评论 (4)编辑 收藏

 

我们可以把表面想象成一张画布, 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 @ 2007-03-05 19:00 大熊猫 阅读(838) | 评论 (0)编辑 收藏


 (1)把类库从 www.libsdl.org 上下载下来。
 (2)在VC2005中,添加一个库文件目录,和头文件目录。
directory.jpg
(3)把动态链接库COPY到C:\\Windows\System下面。
(4)建立一个Win32空项目。
new_project.jpgempty_project.jpg

(5)新建一个C++源文件。
new_cpp.jpg
敲下如下代码
#include <sdl.h>
int main( int argc, char*
 args[] )
{
    
// Start SDL

    SDL_Init( SDL_INIT_EVERYTHING );
    
    
// Quit SDL

    SDL_Quit();
    
    
return   0
;    
}

(6)设置一下工程的属性
project_properties.jpg
multithreadeddll.jpg
(7)加入二各引入库
linker.jpg
(8)编译运行一下,没有错误的话就成功了,有错误的话,检查前面的几个步骤是否出错了。
posted @ 2007-03-04 19:45 大熊猫 阅读(703) | 评论 (0)编辑 收藏

拉登说:中国是全世界唯一绝对不能惹的国家。原因是这样的,基地组织曾向中国派出五名恐怖分子,结果一人炸立交桥,转晕于立交桥上;一人炸公交车,没挤上车;一人炸超市,炸弹遥控器被盗;一人炸政府大楼,被保安狂揍,叫你讨薪,叫你上访;一人成功炸矿,死伤数百人,半年没有任何新闻报道,潜回基地后被以撒谎罪处决了。最后一次曾经尝试去炸广州,结果一出火车站就被飞车党把炸药包抢了
posted @ 2007-01-03 22:59 大熊猫 阅读(611) | 评论 (0)编辑 收藏

起因,昨天写的一段小程序
#include  < iostream >
#include 
< map >
#include 
< iterator >
#include 
< vector >
#include 
< algorithm >
using   namespace  std;
ostream 
& operator << (ostream  & os, const  pair < int , int >   &
mp)
{
   os
<<
mp.first;
   os
<<
mp.second;
   
return
 os;
}

int  _tmain( int  argc, _TCHAR *  argv[])
{
   pair
< int , int >  mmp( 100 , 200
);
   cout
<<
mmp;
   map
< int , int >
 imap;
   map.insert(make_pair(
100 , 100
));
   imap.insert(make_pair(
22 , 123
));
   copy(imap.begin(),imap.end(),ostream_iterator
< pair < int , int >   > (cout, " \n "
));
   
return   0
;
}

未能通过编译,报的错误是:没有找到接受“<未知>”类型的右操作数的运算符(或没有可接受的转换),百思不得其解,应为我觉得 我明明重载了<<运算符。再没有办法的情况下请教了CSDN论坛上的一些朋友,终于弄明白了其中的原因(可能这个知识点很菜,高手 不要见笑)。
ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
{
  *_Myostr << _Val;///~~~~~~~~~~~~~~~~~~~~~~~这是在ostream_iterator类源代码当中,就是这里报错了
  if (_Mydelim != 0)
  *_Myostr << _Mydelim;
  return
}
在上面那到程序当中_Val类型是pair<int,int> *_Myostr类型是ostream,显然这里出错,代表编译器就好像没有看到我的重载。出现以上现象的原因就是当编译器看到*_Myostr<<_Val时候,它会先在自己的名字空间查找<<,这个估计发生在模板编译的第一个阶
段(不知道是不是该这么说),它看到了一个范型的<<重载(估计),于是就不在去别的地方查找。可是到了实例化的时候,编译器发现 没有匹配的<<运算,于是就报错了。如果我们把重载写在std空间里,也就是和ostream_iterator一个空间里,编译器在实例化的时 候也会把它纳入考虑对象之一,这个时候它就会选择我们的重载,一切就OK了。注意,如果编译器在*_Myostr<<_Val所在名字空间没有找到 <<重载,则它会进行类型相关查找。就是去定义*_Myostr类型或_Va类型的空间查找,再找不到那它就会去全局空间去查找。
个人理解,不是很肯定,诚请高手纠正,感谢CSDN上周星星和晨星。

posted @ 2006-12-29 19:42 大熊猫 阅读(1858) | 评论 (13)编辑 收藏

仅列出标题
共5页: 1 2 3 4 5