zoukankan      html  css  js  c++  java
  • SDL 简单入门学习

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

    讨论新闻组及文件

    概要

    实际学习使用SDL创建窗体,并绘制图形。

    前言   

        今天想要做一个简单的demo,由于一部分须要使用objective C,所以还须要跨平台,我才发现,我了解的东西还真没有一个适合做这样事情的,Cocos2D For IPhone只能在IPhone下跑,HGE只能在Windows下跑,Orx尽管可以跨平台,可是非常显然,用于做简单的demo太麻烦了,由于我须要的不过一个简单的DrawBmp函数而已,Orx那种一使用就使用一套的做法不太适合,还能想到的就是OpenGL了,可是用OpenGL做跨平台应用全靠自己那就挺麻烦了,还是找个框架吧。
        事实上我有3个选择,glut/free glut, SDL, GLFW。当中glut尽管在学习OpenGL的时候用过一些,可是由于该项目已经死了,我不想再为其投入很多其它的学习时间,了解到能够看懂其代码的水平(事实上使用也非常easy),已经够了。SDL是非常多人推荐的选择,我曾经找工作的时候,国内的一家公司居然直接提到过,说明其在国内也算是有人用了。我在那以后也看过SDL的API,感觉还算简单,与HGE一样,图形显示上,都是用了相似DirectDraw的抽象。(应该也是最通吃的抽象方式了)我对GLFW的感兴趣是由于近期Orx的作者iarwain提到过,而且给予了非常高的评价,他说对GLFW的轻量级印象非常深刻,在最新的Orx版本号中,GLFW是Orx的默认插件,而且就iarwain的測试,比SDL快5%左右(尽管不算太多),最重要的是,GLFW的封装都非常easy,以直接使用OpenGL为主,借这个契机,我也顺面复习一下OpenGL,近期老是用库,我都快忘了该怎么用了。
        两相比較,我发现我不知道该用SDL还是GLFW,按我的习惯,两个一起用先,尝试一下再下结论。本文先看看SDL。

    实际使用   

        事实上我的需求非常easy,创建窗体,在制定的地方画图。简单的说也就是相似于CreateWindows和DrawBmp的两个函数而已。

        SDL事实上真的算挺出名的了,也有人提到过,即使不真的准备使用SDL,可是想想一个库,可以被移植到这么多平台,抽象封装的方式和源码起码都值得研究研究。由于这个,我也略微看一下,尽管真的不打算长期SDL。SDL的协议是LGPL的(也有商业协议),还算可以接受。
        环境的搭建还算简单,Windows版本号的SDL须要D3D SDK支持。
        简单的參考了一下教程,显示BMP图片的过程还算简单:
     1
     2 #include
     3 #include
     4 #include
     5 #include "SDL.h"
     6
     7 int  _tmain(int  argc, _TCHAR* argv[])
     8 {
     9   if  ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0  )
    10   {
    11     printf("Unable to initialize SDL: %s n " , SDL_GetError());
    12
    13     exit(1 );
    14   }
    15   atexit(SDL_Quit);
    16
    17   //Load image
    18   SDL_Surface* picture = SDL_LoadBMP( "dragon.bmp"  );
    19
    20   SDL_Surface *screen = SDL_SetVideoMode(640 , 480 , 16 , SDL_DOUBLEBUF);
    21   if  ( screen == NULL  )
    22   {
    23     printf("Unable to set video mode: %s n " , SDL_GetError());
    24
    25     exit(1 );
    26   }
    27
    28   //Apply image to screen
    29   SDL_BlitSurface( picture, NULL , screen, NULL  );
    30
    31   //Update Screen
    32   SDL_Flip( screen );
    33
    34   //Pause
    35   SDL_Delay( 2000  );
    36
    37   //Free the loaded image
    38   SDL_FreeSurface( picture );
    39
    40     return  1 ;
    41 }


    这里,能够看到,SDL没有管理主循环,同一时候我没有使用自己的主循环,那得牵涉到SDL的事件系统,所以,这个演示里,用了SDL_Delay,才干看到图片的显示。这里的显示没有指定大小,没有指定alpha值,所以图片原大显示。SDL_BlitSurface 函数的使用非常像Windows API的相应函数。其它也没有什么好说的,看凝视及函数名就知道在干什么了。

    然后,通过下述方式来设置想要的透明色(在没有alpha通道的bmp中,也仅仅能使用这样蹩脚的color key方式了)
    1
    2   Uint32 colorKey = SDL_MapRGB(picture->format, 0xFF , 0xFF , 0xFF );
    3   SDL_SetColorKey(picture, SDL_SRCCOLORKEY, colorKey);

    当中0xFF,0xFF,0xFF各自是想要设定的颜色的R,G,B,这里都是0xFF,那就是白色了。
    于是,原图:




    在黑色背景下,周围的白色都透明了,显示出下列的效果:


    说实话,用SDL的API还算比較简单,使用的时候有点感觉时空穿越,有点回到当年学习使用Win32 API来做相似事情的时候。接口的概念都差点儿相同,或许SDL的优势比起当年的Win32 API仅在于速度和跨平台了。
    显示两个图仅仅须要再blit一次就可以:
      //Apply image to screen
      SDL_BlitSurface( picture, NULL , screen, NULL  );

      SDL_Rect dest;
      dest.x = picture->w;
      dest.y = 0 ;

      //Apply image to screen again and move it to right
      SDL_BlitSurface( picture, NULL , screen, &dest );

    然后,增加SDL对主循环的控制。

      // main loop
      bool  running = true ;
      while  (running) {
        //Update Screen
        SDL_Flip( screen );

        // delay, 50 for simple
        SDL_Delay( 50  );

        //While there's an event to handle
        SDL_Event event;
        while ( SDL_PollEvent( &event ) ) {
          if  (event.type == SDL_QUIT) {
            running = false ;
          }
        }
      }

    SDL_PollEvent用于轮询SDL的事件。
    于是,如今SDL创建的窗体能够被拖动,也能够点击关闭了。
    想说的是,SDL真的非常easy,我看教程的时候基本上仅仅须要看源码就可以,就能了解大部分的意思。

        以下到关键的部分了,PNG的显示,我看到,尽管SDL本身只支持BMP,可是已经有人做了一个名叫SDL_Image的库,能够支持其它格式。(考验一个开源库好不好,有没有良好的第3方支持是非常重要的方面,SDL这方面明显非常不错)于是,我们就不用直接使用libpng了,个人不是非常喜欢libpng的接口。。。。。
        不知道是不是秉承了SDL简单的优良传统,SDL_Image的使用也很easy,编译好后,将里面的动态库(由于须要支持PNG,所以有libpng和zlib的动态库)都复制到执行文件夹里面,然后包括"SDL_image.h"就能够了。从bmp到png的距离仅仅有几行代码。。。。。从我发现SDL_Image到真的载入显示PNG图片,也就过了不到10分钟。。。。
    所有源码:

    #include
    #include
    #include
    #include "SDL.h"
    #include "SDL_image.h"
    int  _tmain(int  argc, _TCHAR* argv[])
    {
      if  ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0  )
      {
        printf("Unable to initialize SDL: %s n " , SDL_GetError());

        exit(1 );
      }
      if  (IMG_Init(IMG_INIT_PNG) == 0  ) {
        printf("Unable to initialize SDL_image" );

        exit(1 );
      }
      atexit(SDL_Quit);

      //Load image
      //SDL_Surface* picture = SDL_LoadBMP( "dragon.bmp" );
      SDL_Surface* picture = IMG_Load("dragon.png" );

      SDL_Surface *screen = SDL_SetVideoMode(640 , 480 , 16 , SDL_DOUBLEBUF);
      if  ( screen == NULL  )
      {
        printf("Unable to set video mode: %s n " , SDL_GetError());

        exit(1 );
      }

      // because we use png with alpha now
      //Uint32 colorKey = SDL_MapRGB(picture->format, 0xFF, 0xFF, 0xFF);
      //SDL_SetColorKey(picture, SDL_SRCCOLORKEY, colorKey);

      //Apply image to screen
      SDL_BlitSurface( picture, NULL , screen, NULL  );

      SDL_Rect dest;
      dest.x = picture->w;
      dest.y = 0 ;

      //Apply image to screen again and move it to right
      SDL_BlitSurface( picture, NULL , screen, &dest );

      // main loop
      bool  running = true ;
      while  (running) {
        //Update Screen
        SDL_Flip( screen );

        // delay, 50 for simple
        SDL_Delay( 50  );

        //While there's an event to handle
        SDL_Event event;
        while ( SDL_PollEvent( &event ) ) {
          if  (event.type == SDL_QUIT) {
            running = false ;
          }
        }
      }

      //Free the loaded image
      SDL_FreeSurface( picture );

        return  1 ;
    }

    只唯独几行改动,在代码中看的非常清楚。

     

    小结

        简单,还是简单,这是我学习SDL的最大感受,API设计的简单,相关概念也简单,SDL无愧于Simple DirectMedia Layer中的Simple一次。要想真的从OpenGL学习起,然后调用libpng来载入PNG图像并显示,你得看到红宝书的第十几章,直到纹理贴图的学习后你才干做到,可是,在SDL中做这些事情实在是太简单了。即使与当年的Win32 API相比,也少了非常多Windows特定的消息循环原理等东西的学习,创建窗体的API比較起来,就会感觉MS那一帮人都是废物,设计的窗体创建API,居然须要用几十行的代码去创建一个窗体,还须要注冊窗体类。。。。。。。。。。。其实,仅仅须要一行代码。。。。。。

        一般来说,一个比較流行的开源库都是比較好的,由于好,才流行,由于流行而变的更好,当中,最最重要的关键在于,使用要简单,太复杂难用的库,不管设计的多么静止,都非常难吸引到使用者,也就难以进入这个良性的循环,不得不说,SDL在这方面,做的是非常好了。

     

     

    原创文章作者保留版权 转载请注明原作者 并给出链接

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie





  • 相关阅读:
    Angularjs中添加ckEditor插件
    Angularjs中添加HighCharts
    ngTbale真分页实现排序、搜索等功能
    移动端小功能杂记(三)
    Html5 history Api简介
    移动端流程页处理
    Html5离线缓存简介
    多Tabs的横向滚动插件(支持Zepto和jQuery)
    flutter从零开始第一篇-环境搭建(Windows)
    vue 父子组件与全局数据传递共享
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4517939.html
Copyright © 2011-2022 走看看