﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-我风-随笔分类-SDL</title><link>http://www.cppblog.com/kyelin/category/14536.html</link><description>收集,记录,整理,回收</description><language>zh-cn</language><lastBuildDate>Wed, 11 Aug 2010 12:45:06 GMT</lastBuildDate><pubDate>Wed, 11 Aug 2010 12:45:06 GMT</pubDate><ttl>60</ttl><item><title>SDL-5(打开和显示图片)</title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123062.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 05:59:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123062.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123062.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123062.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123062.html</trackback:ping><description><![CDATA[
		<strong>
				<br />
		</strong>　　在这个例子里我们将学习如何使用SDL程序中打开和显示图片。示例程序将绘制一个漂亮的背景，上面显示一个正方形图案，并可以使用键盘的方向键移动它。如果比较熟悉“推箱子”这个游戏，可以看出这个程序实际就是推箱子游戏的基础。<br /><br />　　在程序首部包含以下头文件(stdlib.h供调用atexit()时使用)：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include “SDL.h”</td></tr></tbody></table><br />　　声明3个SDL_Surface类型的全局变量，同时声明2个整型变量用于记录正方形的坐标：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>SDL_Surface *back;<br />SDL_Surface *image;<br />SDL_Surface *screen;<br /><br />int xpos = 0, ypos = 0;</td></tr></tbody></table><br />　　我们构造一个函数InitImage函数来打开bitmap文件(.bmp)中的图像信息，传递给SDL_Surface显示。InitImage将会被main()函数调用。在InitImage函数中我们使用到了SDL_LoadBMP函数，它把bmp文件的文件名作为参数传入，返回指向存储图像文件信息内存区域的指针。InitImage中我们将背景图片bg.bmp打开并使用back指针进行记录，将正方形图片image.bmp打开并使用image指针记录。<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>int InitImages() <br />{ <br />　back = SDL_LoadBMP("bg.bmp"); <br />　image = SDL_LoadBMP("image.bmp"); <br />　return 0; <br />} </td></tr></tbody></table><br />　　下面我们介绍将图像绘制到屏幕的两个函数，两个函数都被命名为DrawIMG。第一个DrawIMG函数使用SDL_BlitSurface函数来在屏幕上显示图像。在SDL中SDL_BliSurface的函数原型如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, <br />SDL_Surface *dst, SDL_Rect *dstrect); </td></tr></tbody></table><br />　　src是需要进行绘制的surface而dst是进行显示的surface。SDL_Rect是一个包含4个16位整型变量的结构：x, y, w(width)和h(height)。srcrect用来描述源surface中需要绘制部分，而dstrect用来描述在目的surface何处进行绘制。如果设置srcrect为NULL，那么源文件中包含的整个图像都会被显示。dstrect中的x和y变量指定了在何处blit SDL_Surface src。对于dstrect来说，w(width)和h(height)这两个变量是被忽略不计的。第一个DrawIMG函数非常简单：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawIMG(SDL_Surface *img, int x, int y) <br />{ <br />　SDL_Rect dest; <br />　dest.x = x; <br />　dest.y = y; <br />　SDL_BlitSurface(img, NULL, screen, &amp;dest); <br />} </td></tr></tbody></table><br />　　下面我们考虑一个复杂点的情况，如图：<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41641F7F17F.jpg" border="0" /></div></td></tr></tbody></table><br />　　如果我们需要将阴影区域传递给srcrect进行绘制，我们就需要使用到srcrect结构里的几个变量了:x,y指定了所要绘制的源区域的起点坐标，而w和h分别指定了源区域的宽度和高度。如果图中的阴影坐标起点坐标为(20,25)，宽61个象素高70个象素，那么我们可以得到：srcrect中x = 20, y = 25, w = 61, h = 70。<br /><br />　　第二个DrawIMG定义如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2) <br />{ <br />　SDL_Rect dest; <br />　dest.x = x; <br />　dest.y = y; <br />　SDL_Rect dest2; <br />　dest2.x = x2; <br />　dest2.y = y2; <br />　dest2.w = w; <br />　dest2.h = h; <br />　SDL_BlitSurface(img, &amp;dest2, screen, &amp;dest); <br />} </td></tr></tbody></table><br />　　绘制背景的函数DrawBG()比较简单:<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawBG()<br />{<br />　Slock(screen);<br />　DrawIMG(back, 0, 0);<br />　Sulock(screen);<br />}</td></tr></tbody></table><br />　　绘制正方形图像的函数将会比较复杂，首先我们用背景图案填充当前正方形图像所在区域，如果不这样做的话，正方形图像的移动就会造成背景上留下黑色的方形移动轨迹，如图所示：<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41642148DC3.jpg" border="0" /></div></td></tr></tbody></table><br />　　这里，我们只填充正方形图像移动后的轨迹区域，这样比填充整个区域速度快。由于正方形区域大小是128x128，由于每次正方形只能朝某个方向移动1个象素(pixel),为了彻底消除移动轨迹，我们背景的新填充区域扩大到132x132，这样就可以完全覆盖由于移动造成的轨迹残留。最后使用SDL_Flip对新的图像绘制区域进行更新。函数如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawScene()<br />{<br />　Slock(screen);<br />　DrawIMG(back, xpos-2, ypos-2, 132, 132, xpos-2, ypos-2);<br />　DrawIMG(image, xpos, ypos);<br /><br />　SDL_Flip(screen);<br />　Sulock(screen);<br />}</td></tr></tbody></table><br />　　由于要移动正方形图像，我们需要对键盘的方向键的按下事件进行响应，因此在main函数开始时定义：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>Uint8* keys；</td></tr></tbody></table><br />　　keys用来获得每一时间的键盘状态。获得键盘状态的函数为SDL_GetKeyState(),它返回一个指向Uin8类型的数组头部的指针。数组的每个元素都对应记录了某个按键是否被按下的标志。这里的实现，我们不在事件轮询SDL_PollEvent中检查按键，因为事件轮询中是只有触发事件也即SDL_PollEvent(&amp;event) == 1才能进入循环的，因而如果我们一直按下某键不放开是不会触发新的事件发生的，要使得正方形移动我们必须一下又一下的敲击某个方向键，显示这不是我们所要的。我们希望是按下某键不放开的话，正方形一直保持向此方向移动。因此我们将检查按键的程序段放到事件轮询之后处理。这里没有使用else if…结构，因此可以多个方向键同时按下进行移动，程序段如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>int done=0;<br /><br />while(done == 0)<br />{<br />　SDL_Event event;<br /><br />　while ( SDL_PollEvent(&amp;event) )<br />　{<br />　　if ( event.type == SDL_QUIT ) { done = 1; }<br /><br />　　if ( event.type == SDL_KEYDOWN )<br />　　{<br />　　　if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }<br />　　}<br />　}<br />　keys = SDL_GetKeyState(NULL);<br />　if ( keys[SDLK_UP] ) { ypos -= 1; }<br />　if ( keys[SDLK_DOWN] ) { ypos += 1; }<br />　if ( keys[SDLK_LEFT] ) { xpos -= 1; }<br />　if ( keys[SDLK_RIGHT] ) { xpos += 1; }<br /><br />　DrawScene();<br />}</td></tr></tbody></table><br />　　程序运行结果如下（我们已经将正方形图像区域移动到了窗口中央）：<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C416422EC7AC.jpg" border="0" /></div></td></tr></tbody></table><br />　　如果想学习本程序的完整代码，可以从以下地址下载：http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/download.pl?file=lesson2.zip&amp;blah=1<br /><br />　　以上我们简单介绍了VC6下SDL的安装和简单应用，并举了两个小例子，当然SDL的功能远远不止这些，包括音频、定时器和线程编程等等，这里就不一一鳌数了。如果有兴趣，SDL官方网站提供了非常详尽的函数说明、文档和使用指南，你可以在网站上获取非常多的信息。由于SDL是跨平台和开发工具的，方便游戏在各种平台下的移植，同时还支持常用的各种开发语言。因此，有足够的理由相信，在游戏产业蓬勃发展的今天，SDL一定会得到更多开发者的青睐，用它开发出各种有趣的游戏来。 <img src ="http://www.cppblog.com/kyelin/aggbug/123062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 13:59 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL-4(简单的象素绘制)</title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123061.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 05:54:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123061.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123061.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123061.html</trackback:ping><description><![CDATA[
		<strong>
				<br />
		</strong>　　下文从使用SDL的编程函数开始，介绍了如何使用SDL在屏幕上进行象素绘制的基本知识，并给出了一个简单的例子。<br /><br />　　如果要在VC中用SDL库，必须在源文件头部包含以下头文件：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>#include “SDL.h”</td></tr></tbody></table><br />　　初始化SDL是通过SDL_Init()函数来实现的。如果初始化失败，函数返回值为0。函数只接受初始化对象作为参数。如果要初始化视频屏幕，传入常数SDL_INIT_VIDEO作为参数；初始化音频，传入常数SDL_INIT_AUDIO；如果同时初始化视频和音频，传入SDL_INIT_VIDEO|SDL_INIT_AUDIO。其它还有一些量可以传入作为参数的（如果同时传入多个量要使用|将它们隔开）：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>SDL_INIT_TIMER<br />SDL_INIT_AUDIO<br />SDL_INIT_VIDEO<br />SDL_INIT_CDROM<br />SDL_INIT_JOYSTICK<br />SDL_INIT_NOPARACHUATE<br />SDL_INIT_EVENTTHREAD<br />SDL_INIT_EVERYTHING</td></tr></tbody></table><br />　　如果我们要初始化，可以使用如下语句：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) &lt; 0 )<br />{<br />　printf(“Unable to init SDL: %s\n”, SDL_GetError());<br />　return 1;<br />}</td></tr></tbody></table><br />　　如果初始化失败，则函数SDL_GetError()返回关于错误的一个字符串提示信息。<br /><br />　　当从你的C++语句返回时，记住使用SDL_Quit()进行程序的清理工作，否则就会出现奇怪的现象。可以使用如下语句进行描述：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>atexit(SDL_Quit); </td></tr></tbody></table><br />　　这样的话就不需要在main函数中每个return语句前加入SDL_Quit()了。<br /><br />　　在SDL中你可以拥有多个surface，每件物体都是一个surface。你可以在一个surface上进行绘图或者在其他surface上绘制另外一个surface。程序中一个surface的表示即为指向结构SDL_Surface的指针。如果要获得一个surface只要如下定义：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>SDL_Surface *screen;</td></tr></tbody></table><br />　　如果需要对screen所指向的surface上进行绘图，你可以使用函数SDL_SetVideoMode()来设置屏幕分辨率：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);</td></tr></tbody></table><br />　　前三个参数分别为屏幕宽度，高度和屏幕上的每象素包含的位数(bits per pixel, BPP)。如果填入0则SDL自动选择最合适的BPP。第四个参数用来给出某些特殊标志位。如果要在屏幕上进行图形绘制就必须使用SDL_HWSURFACE或者SDL_SWSURFACE。以下给出了一个你可以指定的标志位：<br /><br />　　SDL_SWSURFACE:在系统内存中创建视频Surface<br /><br />　　SDL_HWSURFACE:在视频内存中创建视频Surface<br /><br />　　SDL_ASYNCBLIT:允许在显示surface上使用异步更新。在单CPU机器上会变慢，但在SMP系统上会有显著的性能提升。<br /><br />　　SDL_ANYFORMAT:一般的，如果指定位数的bpp不可用，那么SDL就会模拟使用阴影surface。如果传入SDL_ANYFORMAT就会阻止这样做，并且不管色深强制使用视频surface。<br /><br />　　SDL_HWPALETTE:给予SDL特许的画盘的访问权，使用这个标志位就不需要总是使用SDL_SetColors或者SDL_SetPalette来获取所需的颜色。<br /><br />　　SDL_DOUBLEBUF:允许硬件双缓冲；只是和SDL_HWSURFACE一起使用时比较有用。调用SDL_Flip将会flip整个缓冲并且更新屏幕。所有的绘制将会在当前未显示的surface上发生。如果双缓冲被允许，那么SDL_Flip将会对整个屏幕进行SDL_UpdateRect操作。<br /><br />　　SDL_FULLSCREEN:SDL将会尝试使用全屏模式。如果硬件分辨率的调整由于某种情况无法完成，那么下一个稍高的分辨率将会被使用，并且显示窗口将会处于一个黑色背景的中央。<br /><br />　　SDL_OPENGL:创建一个OPENGL rendering context。使用前必须已经使用SDL_GL_SetAttribute对OpenGL视频属性进行设置。<br /><br />　　SDL_OPENGLBLIT: 和上一个选项一样创建一个 OPENGL rendering context, 但是允许使用正常的blitting操作。<br /><br />　　SDL_RESIZABLE; 创建一个可伸缩大小的窗口。当用户调整窗口大小时，将会触发一个SDL_VIDEORESIZE事件，SDL_SetVideoMode将会使用新大小作为参数再次被调用。<br /><br />　　SDL_NOFRAME: 如果可以的话，SDL_NOFRAME将会创建出一个没有标题栏和边界修饰的窗口，全屏方式自动设置此标志位。<br /><br />　　建议使用SDL_HWSURFACE | SDL_DOUBLEBUF，如果出现错误可以尝试使用SDL_SWSURFACE。<br /><br />　　SDL_SetVideoMode如果操作成功，则返回一个指向SDL_Surface的指针，否则的话返回NULL。可以使用如下语句检查发生的错误：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>If ( screen == NULL )<br />{<br />　printf(“Unable to set 640x480 video: %s\n”, SDL_GetError());<br />　return 1;<br />}</td></tr></tbody></table><br />　　以上介绍了如何对SDL进行初始化，下面可以开始绘制了。但是还有一些需要注意的关键地方，首先是一些SDL使用的容易让人产生迷惑的数据类型：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>Uint8 – 相当于unsigned char<br />Uint16 – 16位(2字节) unsigned integer<br />Uint32 – 32位(4字节) unsigned integer<br />Uint64 - 64位(8字节) unsigned integer<br />Sint8 – 相当于signed char<br />Sint16 – 16位(2字节) signed integer<br />Sint32 – 32位(4字节) signed integer<br />Sint64 - 64位(8字节) signed integer</td></tr></tbody></table><br />　　还有，有的时候如果初始化出现错误，没必要完全退出。例如当初始化了SDL_INIT_VIDEO而没有初始化SDL_INIT_AUDIO，那么你可以继续这个错误只是没有音频而已。要检查是否音频初始化是否成功，可以使用SDL_WasInit()函数来检查。下面是一个例子：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>Uint32 init = SDL_WasInit(SDL_INIT_AUDIO);<br />If (init &amp; SDL_INIT_AUDIO)<br />{<br />　sound = 1;<br />} else {<br />　sound = 0;<br />}</td></tr></tbody></table><br />　　你可以在程序初始化的某些地方加入以上语句。<br /><br />　　以下是SDL介绍中进行象素绘制的语句，可以暂时不需要完全了解其中的意思：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) <br />{ <br />　Uint32 color = SDL_MapRGB(screen-&gt;format, R, G, B); <br />　switch (screen-&gt;format-&gt;BytesPerPixel) <br />　{ <br />　　case 1: // Assuming 8-bpp <br />　　{ <br />　　　Uint8 *bufp; <br />　　　bufp = (Uint8 *)screen-&gt;pixels + y*screen-&gt;pitch + x; <br />　　　*bufp = color; <br />　　} <br />　　break; <br />　　case 2: // Probably 15-bpp or 16-bpp <br />　　{ <br />　　　Uint16 *bufp; <br />　　　bufp = (Uint16 *)screen-&gt;pixels + y*screen-&gt;pitch/2 + x; <br />　　　*bufp = color; <br />　　} <br />　　break; <br />　　case 3: // Slow 24-bpp mode, usually not used <br />　　{ <br />　　　Uint8 *bufp; <br />　　　bufp = (Uint8 *)screen-&gt;pixels + y*screen-&gt;pitch + x * 3; <br />　　　if(SDL_BYTEORDER == SDL_LIL_ENDIAN) <br />　　　{ <br />　　　　bufp[0] = color;<br />　　　　bufp[1] = color &gt;&gt; 8; <br />　　　　bufp[2] = color &gt;&gt; 16; <br />　　　} else{ <br />　　　　bufp[2] = color; <br />　　　　bufp[1] = color &gt;&gt; 8; <br />　　　　bufp[0] = color &gt;&gt; 16; <br />　　　} <br />　　} <br />　　break; <br />　　case 4: // Probably 32-bpp <br />　　{ <br />　　　Uint32 *bufp; <br />　　　bufp = (Uint32 *)screen-&gt;pixels + y*screen-&gt;pitch/4 + x; <br />　　　*bufp = color; <br />　　} <br />　　break; <br />　} <br />} </td></tr></tbody></table><br />　　通过这个函数，可以传递给surface要绘制的点的(x,y)坐标和RGB值。<br /> 　　同时，由于绘制的屏幕不能同时接受两个函数的同时操作，我们需要其他两个辅助函数，用于在绘制前对屏幕进行锁定，以及在绘制完成之后解除锁定。这两个工作一般由SDL_MUSTLOK(SDL_Surface *screen)和SDL_UnlockSurface(SDL_Surface *screen)完成。使用如下两个自定义的函数会更加简单：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void Slock(SDL_Surface *screen)<br />{<br />　if ( SDL_MUSTLOCK(screen) )<br />　{<br />　　if ( SDL_LockSurface(screen) &lt; 0 )<br />　　{<br />　　　return;<br />　　}<br />　}<br />}<br />void Sulock(SDL_Surface *screen)<br />{<br />　if ( SDL_MUSTLOCK(screen) )<br />　{<br />　　SDL_UnlockSurface(screen);<br />　}<br />}</td></tr></tbody></table><br />　　这样，我们可以得到一个简单的主程序框架如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include "SDL.h"<br /><br />// The functions are not shown to save space <br />void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B); <br />void Slock(SDL_Surface *screen); <br />void Sulock(SDL_Surface *screen); <br /><br />int main(int argc, char *argv[]) <br />{ <br />　if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) &lt; 0 ) <br />　{ <br />　　printf("Unable to init SDL: %s\n", SDL_GetError()); <br />　　exit(1); <br />　} <br />　atexit(SDL_Quit); <br />　SDL_Surface *screen; <br />　screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF); <br />　if ( screen == NULL ) <br />　{ <br />　　printf("Unable to set 640x480 video: %s\n", SDL_GetError()); <br />　　exit(1); <br />　} <br /><br />　// DRAWING GOES HERE <br />　return 0; <br />} </td></tr></tbody></table><br />　　如果对该程序进行编译运行，那么只能得到一闪而过的一个黑色的窗口。我们需要对窗口进行绘制，并且对基本的键盘鼠标事件进行处理。<br /><br />　　绘制的基本原理是，先在缓冲区绘制，再一次性将缓冲区绘制到屏幕上。这样比起一次一个象素点在屏幕上绘图的方式效率更高，速度更快，也不易出错。首先使用循环在screen所指向的surface(缓冲区)上绘制，然后调用SDL_Flip函数将screen surface绘制到真实电脑屏幕上。SDL_Flip函数的作用是：在支持双缓冲(double-buffering)的硬件上，建立flip并返回。硬件将等待vertical retrace,然后在下一个视频surface blit或者执行锁定返回前交换视频缓冲区。如果硬件不支持双缓冲，那么等同于调用SDL_UpdateRect(screen, 0, 0, 0, 0)，即对整个screen的绘制区域进行刷新。<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>void DrawScene(SDL_Surface *screen) <br />{ <br />　Slock(screen); <br />　for(int x=0;x&lt;640;x++) <br />　{ <br />　　for(int y=0;y&lt;480;y++) <br />　　{ <br />　　　DrawPixel(screen, x,y,y/2,y/2,x/3); <br />　　} <br />　} <br />　Sulock(screen); <br />　SDL_Flip(screen); <br />} </td></tr></tbody></table><br />　　在SDL中对采用结构SDL_Event来描述事件，并采用轮询的机制对事件进行处理，程序中使用一个SDL_Event的实例(Instance)来检查事件的发生：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>SDL_Event event;</td></tr></tbody></table><br />　　轮询采用while循环来检查：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>while ( SDL_PollEvent(&amp;event))<br />{<br />　if ( event.type == SDL_QUIT) <br />　{<br />　　//code here….<br />　}<br />　if ( event.type == SDL_KEYDOWN) <br />　{<br />　　//code here….<br />　}<br />　//…..<br />} </td></tr></tbody></table><br />　　事件轮询完毕之后，调用DrawScene(sreen)进行一次绘制。 <br /><br />         本例中的源代码如下：<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include "SDL.h"<br /><br />void Slock(SDL_Surface *screen)<br />{<br />　if ( SDL_MUSTLOCK(screen) )<br />　{<br />　　if ( SDL_LockSurface(screen) &lt; 0 )<br />　　{<br />　　　return;<br />　　}<br />　}<br />}<br />void Sulock(SDL_Surface *screen)<br />{<br />　if ( SDL_MUSTLOCK(screen) )<br />　{<br />　　SDL_UnlockSurface(screen);<br />　}<br />}<br />void DrawPixel(SDL_Surface *screen, int x, int y,<br />Uint8 R, Uint8 G, Uint8 B)<br />{<br />　Uint32 color = SDL_MapRGB(screen-&gt;format, R, G, B);<br />　switch (screen-&gt;format-&gt;BytesPerPixel)<br />　{<br />　　case 1: // Assuming 8-bpp<br />　　{<br />　　　Uint8 *bufp;<br />　　　bufp = (Uint8 *)screen-&gt;pixels + y*screen-&gt;pitch + x;<br />　　　*bufp = color;<br />　　}<br />　　break;<br />　　case 2: // Probably 15-bpp or 16-bpp<br />　　{<br />　　　Uint16 *bufp;<br />　　　bufp = (Uint16 *)screen-&gt;pixels + y*screen-&gt;pitch/2 + x;<br />　　　*bufp = color;<br />　　}<br />　　break;<br />　　case 3: // Slow 24-bpp mode, usually not used<br />　　{<br />　　　Uint8 *bufp;<br />　　　bufp = (Uint8 *)screen-&gt;pixels + y*screen-&gt;pitch + x * 3;<br />　　　if(SDL_BYTEORDER == SDL_LIL_ENDIAN)<br />　　　{<br />　　　　bufp[0] = color;<br />　　　　bufp[1] = color &gt;&gt; 8;<br />　　　　bufp[2] = color &gt;&gt; 16;<br />　　　} else {<br />　　　　bufp[2] = color;<br />　　　　bufp[1] = color &gt;&gt; 8;<br />　　　　bufp[0] = color &gt;&gt; 16;<br />　　　}<br />　　}<br />　　break;<br />　　case 4: // Probably 32-bpp<br />　　{<br />　　　Uint32 *bufp;<br />　　　bufp = (Uint32 *)screen-&gt;pixels + y*screen-&gt;pitch/4 + x;<br />　　　*bufp = color;<br />　　}<br />　　break;<br />　}<br />}<br />void DrawScene(SDL_Surface *screen)<br />{<br />　Slock(screen);<br />　for(int x=0;x&lt;640;x++)<br />　{<br />　　for(int y=0;y&lt;480;y++)<br />　　{<br />　　　DrawPixel(screen, x,y,y/2,y/2,x/3);<br />　　}<br />　}<br />　Sulock(screen);<br />　SDL_Flip(screen);<br />}<br /><br />int main(int argc, char *argv[])<br />{<br />　if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) &lt; 0 )<br />　{<br />　　printf("Unable to init SDL: %s\n", SDL_GetError());<br />　　exit(1);<br />　}<br />　atexit(SDL_Quit);<br />　SDL_Surface *screen;<br />　screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);<br />　if ( screen == NULL )<br />　{<br />　　printf("Unable to set 640x480 video: %s\n", SDL_GetError());<br />　　exit(1);<br />　}<br />　int done=0;<br />　while(done == 0)<br />　{<br />　　SDL_Event event;<br />　　while ( SDL_PollEvent(&amp;event) )<br />　　{<br />　　　if ( event.type == SDL_QUIT ) { done = 1; }<br />　　　if ( event.type == SDL_KEYDOWN )<br />　　　{<br />　　　　if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }<br />　　　}<br />　　}<br />　　DrawScene(screen);<br />　}<br />　return 0;<br />}</td></tr></tbody></table><br />　　程序运行结果如下：<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41642490195.jpg" border="0" /></div></td></tr></tbody></table><br /><img src ="http://www.cppblog.com/kyelin/aggbug/123061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 13:54 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL-3(安装和初步使用) </title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123038.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 02:35:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123038.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123038.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123038.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123038.html</trackback:ping><description><![CDATA[　　首先，我们为所有的工程创建一个文件夹tutorial,将下载的开发库SDL-devel-1.2.8-VC6.zip拷贝到tutorial下并解压，并保证如下的文件夹层次（图2）如下：<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41642BDD500.jpg" border="0" /><br />图2</div></td></tr></tbody></table><br />　　下面我们打开Visual Studio6.0，开发一个非常简单的小例子。选择File-&gt;New,新建一个工程，选择Win32 Application,将工程gp保存为tutorial目录下，如图3所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41642E65D0B.jpg" border="0" /><br />图3</div></td></tr></tbody></table><br />　　在图4中，保持默认设置，点击Finish。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C416430A2060.jpg" border="0" /><br />图4</div></td></tr></tbody></table><br />　　为了使用SDL，我们需要进行相关的设置，选择Project-&gt;Settings...，选择C/C++属性页，在Category中选择Code Generation，在Use run-time library中选择Debug Multithreaded DLL，如图5所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41643376D21.jpg" border="0" /><br />图5</div></td></tr></tbody></table><br />　　在Category中选择Preprocessor，在'Additional include directories'的文本框中填上..\SDL-1.2.8\include\，如图6所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41643625787.jpg" border="0" /><br />图6</div></td></tr></tbody></table><br />　　选择Link属性页，在'Object/library modules'文本框的首部增加SDLmain.lib和sdl.lib，如图7所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41643887D37.jpg" border="0" /><br />图7</div></td></tr></tbody></table><br />　　仍然是Link属性页，选择Category中的Input，在'Additional library path'文本框中填写..\SDL-1.2.8\lib\，如图8所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41643BF5364.jpg" border="0" /><br />图8</div></td></tr></tbody></table><br />　　这样我们就完成了编程前的设置工作，不过这是针对Debug版本的，如果要设置Release版本，需要选择Build-&gt;Set Active Configuration,选择Release，然后再次如上配置一次。<br /><br />下面我们正式开始编程，将E:\tutorial\SDL-1.2.8\lib\SDL.dll拷贝到gp文件夹下，然后给gp工程增加一个C++文件main.cpp。如图9所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C41642659DD9.jpg" border="0" /><br />图9</div></td></tr></tbody></table><br />　　将以下代码拷贝到main.cpp并保存。<br /><br /><table bordercolor="#cccccc" width="90%" align="center" bgcolor="#edeceb" border="1"><tbody><tr><td>#include &lt;stdlib.h&gt;<br />#if defined(_MSC_VER)<br />#include "SDL.h"<br />#else<br />#include "SDL/SDL.h"<br />#endif<br /><br />SDL_Surface *screen;<br /><br />void render()<br />{ <br />　// 独占资源，将surface 锁定<br />　if (SDL_MUSTLOCK(screen)) <br />　　if (SDL_LockSurface(screen) &lt; 0) <br />　　　return;<br /><br />　// 获取当前时间，以毫秒计时<br />　int tick = SDL_GetTicks();<br /><br />　// 声明变量<br />　int i, j, yofs, ofs;<br /><br />　// 对窗口进行绘制<br />　yofs = 0;<br />　for (i = 0; i &lt; 480; i++)<br />　{<br />　　for (j = 0, ofs = yofs; j &lt; 640; j++, ofs++)<br />　　{<br />　　　((unsigned int*)screen-&gt;pixels)[ofs] = i * i + j * j + tick;<br />　　}<br />　　yofs += screen-&gt;pitch / 4;<br />　}<br /><br />　// 解除锁定<br />　if (SDL_MUSTLOCK(screen)) <br />　　SDL_UnlockSurface(screen);<br /><br />　// 使用SDL对窗口进行更新<br />　SDL_UpdateRect(screen, 0, 0, 640, 480); <br />}<br /><br />// Entry point<br />int main(int argc, char *argv[])<br />{<br />　// 初始化SDL子系统，这里只对视频进行初始化<br />　if ( SDL_Init(SDL_INIT_VIDEO) &lt; 0 ) <br />　{<br />　　fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());<br />　　exit(1);<br />　}<br /><br />　// 注册SDL_Quit，当退出时调用，使得退出时程序自动清理<br />　atexit(SDL_Quit);<br /><br />　// 使用32位象素创建640x480的窗口<br />　screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);<br /><br />　// 若失败，则退出<br />　if ( screen == NULL ) <br />　{<br />　　fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());<br />　　exit(1);<br />　}<br /><br />　// 主循环<br />　while (1)<br />　{<br />　　// Render stuff<br />　　render();<br /><br />　　// SDL中的事件轮询机制<br />　　SDL_Event event;<br />　　while (SDL_PollEvent(&amp;event)) <br />　　{<br />　　　//对消息进行处理<br />　　　switch (event.type) <br />　　　{<br />　　　　// 如果按下某键的消息响应<br />　　　　case SDL_KEYDOWN: <br />　　　　　break;<br />　　　　　//如果某键按下后弹起的消息响应<br />　　　　case SDL_KEYUP:<br />　　　　　//若按下ESC键，则退出<br />　　　　　if (event.key.keysym.sym == SDLK_ESCAPE)<br />　　　　　　return 0;<br />　　　　　break;<br />　　　　　//退出消息响应<br />　　　　case SDL_QUIT:<br />　　　　　return(0);<br />　　　}<br />　　}<br />　}<br />　return 0;<br />}</td></tr></tbody></table><br />　　对工程gp进行编译，可以看看动态水波纹的效果了:) 如图10所示。<br /><br /><table width="90%" align="center"><tbody><tr><td><div align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C416429A11AB.jpg" border="0" /><br />图10</div></td></tr></tbody></table><br />　　如果你能够看到图10中的美丽动态窗口，那么恭喜你，你可以开始漫游SDL的精彩世界了。下面我们将正式开始我们的SDL之旅。<br /><img src ="http://www.cppblog.com/kyelin/aggbug/123038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 10:35 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL-1(简介)</title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123036.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 02:30:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123036.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123036.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123036.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123036.html</trackback:ping><description><![CDATA[说明:本文转载自<a href="http://tech.itdb.cn/n/200603/19/n20060319_12998.shtml">http://tech.itdb.cn/n/200603/19/n20060319_12998.shtml</a><br /><br />　　Simple DirectMedia Layer, 简称SDL，是一个自由的跨平台的多媒体开发包，主要通过OpenGL和2D视频帧缓冲(framebuffer)提供对音频、键盘、鼠标、游戏操纵杆(joystick)和3D硬件的底层访问。它被广泛的应用于MPEG回放软件、模拟器和多个著名游戏中，如获得大奖的《文明：权倾天下》(Civilization: Call To Power)的Linux移植版本。它的官方站点是：http://www.libsdl.org/ ，还有一个非常个性的LOGO(图1)。<br /><br /><p align="center"><img src="http://images.itdb.cn/News/2006/03/19/8C8C33BFAD35A40.gif" border="0" /></p><br /><br />　　在Win32编程中，如果要操纵2D图像，可以选择使用GDI或者DirectDraw，前者速度较慢，而后者是特定针对Microsoft平台的，在非Win32平台上移植会带来很大的麻烦。这时，你可以选择使用SDL。SDL支持多种平台：Linux、Windows, BeOS, MacOS Classic, MacOS X, FreeBSD, OpenBSD, BSD/OS, Solaris, IRIX和QNX，同时也部分支持部分其他平台：Windows CE, AmigaOS, Dreamcast, Atari, NetBSD, AIX, OSF/Tru64, RISC OS和SymbianOS。当然SDL本身是针对2D图像编程的，如果使用到3D编程，那么需要将SDL和OpenGL结合使用。<br /><br />　　SDL是用C编写的，但是也支持C++，同时其他多种语言，下面给出了其他语言的SDL的开发包的相关信息：<br /><br />　　·Ada <br />　　　AdaSDL - http://sourceforge.net/projects/adasdl/ <br />　　·C# <br />　　　SDL.Net - http://cs-sdl.sourceforge.net/ <br />　　·Eiffel <br />　　　ewg - http://ewg.sourceforge.net/ <br />　　·Erlang <br />　　　ESDL - http://www.ericsson.com/cslab/~dgud/esdl/ <br />　　·Euphoria <br />　　　SDL_Wrap - http://www.rapideuphoria.com/sdl_wrap.zip <br />　　·Guile <br />　　　guile-sdl - http://sourceforge.net/projects/guile-sdl/ <br />　　·Java <br />　　　JSDL - http://jsdl.sourceforge.net/ <br />　　　sdljava - http://sdljava.sourceforge.net <br />　　·Lisp <br />　　　CL-SDL - http://cl-sdl.sourceforge.net/ <br />　　　SDL for Corman Common Lisp - http://www.balooga.com/lisp_sdl.php3 <br />　　·Lua <br />　　　luaSDL - http://lua-users.org/wiki/LuaModuleLuaSdl <br />　　·ML <br />　　　SDLML - http://www.HardcoreProcessing.com/Freeware/SDLML.html <br />　　　OCamlSDL - http://ocamlsdl.sourceforge.net/ <br />　　·Objective C <br />　　　SDLOBJC - http://savannah.nongnu.org/projects/sdlobjc/ <br />　　·Pascal <br />　　　SDL4Freepascal - http://sdl4fp.sourceforge.net/ <br />　　　JEDI-SDL - http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME <br />　　·Perl <br />　　　SDLPerl - http://sdl.perl.org <br />　　·PHP <br />　　　PHP SDL module - http://phpsdl.sourceforge.net <br />　　·Pike <br />　　　Natively supported (module SDL) - http://pike.ida.liu.se/ <br />　　·Pliant <br />　　　Pligame - http://pligame.sourceforge.net/ <br />　　·Python <br />　　　PyGame - http://pygame.seul.org/ <br />　　·Ruby <br />　　　Ruby/SDL - http://www.kmc.kyoto-u.ac.jp/~ohai/index.en.html <br />　　　RUDL - http://rudl.sourceforge.net <br /><br /><br /><img src ="http://www.cppblog.com/kyelin/aggbug/123036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 10:30 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL-2(功能)</title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123037.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 02:30:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123037.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123037.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123037.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123037.html</trackback:ping><description><![CDATA[　　<strong>功能</strong><br /><br />　　视频 <br /><br />　　·设置8bpp或更高的任意色彩深度的视频模式。如果某个模式硬件不支持，可以选择转化为另一模式。 <br /><br />　　·直接写入线性的图像帧缓冲（framebuffer）。 <br /><br />　　·用颜色键值（colorkey）或者alpha混合属性创建用于绘图的表面(surface)。 <br /><br />　　·Surface的blit能自动的转化为目标格式。blit是优化过的，并能使用硬件加速。x86平台上有针对MMX优化过的blit。 <br /><br />　　·硬件加速的blit和fill（填充）操作，如果硬件支持的话。 <br /><br />　　事件 <br /><br />　　·提供以下事件： <br /><br />　　o 应用程序的visibility(可视性)发生改变 <br /><br />　　o 键盘输入 <br /><br />　　o 鼠标输入 <br /><br />　　o 用户要求的退出 <br /><br />　　·每种事件都能通过SDL_EventState()关闭或者打开。 <br /><br />　　·事件经由用户指定的过滤函数再被加入到内部的事件队列。 <br /><br />　　·线程安全的事件队列。<br /><br />　　音频 <br /><br />　　·设置8位和16位的音频，单声道或者立体声，如果格式硬件不支持，可以选择转换。 <br /><br />　　·由独立的线程执行音频部分，并提供用户回调（callback）机制。 <br /><br />　　·设计上考虑到了客户定制的软混音器，但实际上在例程中就包含了一个完整的音频/音乐输出库。<br /><br />　　CD音频 <br /><br />　　·完整的CD音频控制API <br /><br />　　线程 <br /><br />　　·简单的线程创建API <br /><br />　　·用于同步的简单的二进制信号量（semaphores） <br /><br />　　定时器 <br /><br />　　·读取已流逝的毫秒数。 <br /><br />　　·等待指定的毫秒数。 <br /><br />　　·设置一个10毫秒精度的周期性定时器。<br /><br />　　字节序无关 <br /><br />　　·侦测当前系统的字节序 <br /><br />　　·快速转换数据的函数 <br /><br />　　·读写指定字节序的数据 <br /><br />　　下载<br /><br />　　SDL的官方下载地址为http://www.libsdl.org/download-1.2.php, 最新版本为1.2.8，分为运行库Runtime Library和开发库Development Library，使用SDL开发需要下载的是后者。由于SDL支持多平台和多个开发工具如VC6、Visual Studio.NET 2003、Dev-C++等等，所以可以根据需要选择合适自己的平台版本。由于笔者采用VC6给朋友们讲解SDL的使用，因此文章中只介绍了VC6下的安装方式，并使用了一个小例子做说明。如果您使用其他的平台和工具，请在官方网站上查找相应的说明并按照要求去安装使用。 <br /><img src ="http://www.cppblog.com/kyelin/aggbug/123037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 10:30 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL简介(转)</title><link>http://www.cppblog.com/kyelin/archive/2010/08/11/123033.html</link><dc:creator>我风</dc:creator><author>我风</author><pubDate>Wed, 11 Aug 2010 02:22:00 GMT</pubDate><guid>http://www.cppblog.com/kyelin/archive/2010/08/11/123033.html</guid><wfw:comment>http://www.cppblog.com/kyelin/comments/123033.html</wfw:comment><comments>http://www.cppblog.com/kyelin/archive/2010/08/11/123033.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kyelin/comments/commentRss/123033.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kyelin/services/trackbacks/123033.html</trackback:ping><description><![CDATA[
		<table style="TABLE-LAYOUT: fixed">
				<tbody>
						<tr>
								<td>
										<div class="cnt">
												<p>什么是SDL？<br />即 Simple DirectMedia Layer，使用 LGPL 许可证。</p>
												<p>免费的跨平台多媒体应用编程接口 <br />用于游戏、游戏开发工具、模拟器、样本演示、多媒体应用等 <br />它能做什么？<br />视频、音频、事件、CDROM支持、线程、计时器、各种图象文件格式读取、快速绘图、混音、游戏杆支</p>
												<p>持、网络、MPEG解码等等，且CPU字节顺序无关。 </p>
												<p>大体上与DirectX比较对应关系如下：</p>
												<p>SDL_Video、SDL_Image、OpenGL —— DirectDraw、Direct3D <br />SDL_Audio、SDL_Mixer —— DirectSound <br />SDL_Joystick、SDL_Base —— DirectInput <br />SDL_Net —— DirectPlay <br />SMPEG、SDL_Video、SDL_Audio、SDL_Sound、SDL_Filter —— DirectShow <br />字体、窗口管理等其他实用工具和大量样例 <br />支持哪些平台？<br />Linux 随系统安装 <br />Win32 需一个到几个较小的DLL <br />BeOS <br />MacOS, MacOS X <br />其他非官方移植 <br />可以在哪些编程语言中使用？<br />几乎所有！SDL本身用 C 写成，有各种语言的接口。简单的函数调用，不需要COM。</p>
												<p>个人观点（不代表任何团体和他人）<br />总的来说，SDL并不怎么优秀，但它是少数的DX替代品之一。有人会问为什么非得不用DX，也没有非得</p>
												<p>不用，至少懒人总是希望用更少的功夫做更多的 事。对大多数人来说，无论DX、OpenGL还是SDL，都是</p>
												<p>低层API，尤其DX，如果您精通DX，那么恭喜，您的硬件知识一定也不错。留心的话就会发 现今天的游</p>
												<p>戏很多都提供选项：Direct3D、OpenGL、Glide还是Software，既是说很多游戏厂商都根据需要设计了</p>
												<p>自己的高层API， 底层是可以替换的。那么也许有人说水平高的厂商都是充分开发硬件功能才有高性能</p>
												<p>的表现，那么我举个例子，很多2D游戏的渲染虽然用了 DirectDraw，但却是纯软件在内存帧缓冲区渲</p>
												<p>染，最后调用DirectDraw将图象Swap到屏幕。对于2D游戏加今天的机器配置，GDI加直 接帧缓冲操作已</p>
												<p>经足够，需要更先进的渲染能力时就要使用3D技术，这也是在DX8中DirectDraw和Direct3D都被基于3D</p>
												<p>的 DirectGraphics替换掉的原因。但最主要的是，选择SDL意味着跨平台。</p>
												<p>回到正题。象DX一样，SDL的各个部分是可以单独使用的，但必须有SDL_Base。窗口消息管理方式很古</p>
												<p>董，写过Win32程序的一定还记得switch...case，没错SDL用就是这个，但完全可以不用它的。SDL的 C </p>
												<p>风格很浓，就像DirectX的COM风格很浓一样，用非 C 类语言的人会更愿意封装一下再用。</p>
												<p>与DX相比，SDL有更快的启动速度，方便的调试（调试过DX程序吗？:( ），简洁的接口，很小的运行时</p>
												<p>库，当然首要的是跨平台。SDL直接支持很多媒体文件格式，与DX比起来非常的方便。但SDL即简单直接</p>
												<p>访问媒体层，不象DX支持那么多功能，当然也因为不是每个平台都能提供那么多功能。</p>
												<p>样例代码上说，比起DX，SDL的样例非常短小精悍，程序流程是直线式，效果上一点也不差。非C语言的</p>
												<p>翻译版本保留了C的风格，没有利用先进的语言特性，是个遗憾。至于帮助文件，绝对不如DirectX，很</p>
												<p>多有用的信息是头文件里的注释。但毕竟 C 接口比COM简单得多，看看函数名和样例也就会用了。但没</p>
												<p>有中文资料，不爱看英文的可能会头痛。可能的话大家分工翻译一下，毕竟比DX文档少多了。</p>
												<p>详细信息在哪里？<br /><a href="http://www.libsdl.org/">http://www.libsdl.org/</a> SDL首页</p>
												<p>
														<a href="http://www.delphi-jedi.org/">http://www.delphi-jedi.org/</a> Delphi接口项目首页</p>
												<p>
														<a href="http://jsdl.sourceforge.net/">http://jsdl.sourceforge.net/</a> Java接口首页</p>
												<p>
														<a href="http://csgl.sourceforge.net/">http://csgl.sourceforge.net</a> C#接口首页</p>
												<p>
														<a href="http://phpsdl.sourceforge.net/">http://phpsdl.sourceforge.net</a> php接口首页</p>
												<p>使用SDL的游戏有哪些？<br /><a href="http://www.libsdl.org/games.php">http://www.libsdl.org/games.php</a></p>
												<p>
														<br />有个列表，总之非常多 </p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cppblog.com/kyelin/aggbug/123033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kyelin/" target="_blank">我风</a> 2010-08-11 10:22 <a href="http://www.cppblog.com/kyelin/archive/2010/08/11/123033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>