- 浏览: 18734 次
最新评论
SDL video子系统学习 (1)
2011年05月16日
上次了解了SDL的框架,这次我们来看看SDL的video子系统。
Video是SDL中使用很普遍的一类元素,有一个完整的体系结构,下面就是一些示例:
首先是初始化视频显示,这部分是基本上所有的SDL程序都要做的。
--------------------------------------------------------------
#include "libnge.h"
#include "stdio.h"
extern"C"
int main(int argc, char* argv[])
{
SDL_Surface*screen;
/*Initialize the SDL library */
if(SDL_Init(SDL_INIT_VIDEO) format->BitsPerPixel);
exit(0);
}
---------------------------------------------------------------
首先,还是利用SDL_Init来初始化SDL,成功返回0否则返回-1。以初始化对象作为参数,多个参数之间用“|”隔开,SDL初始化对象有以下这些:
SDL_INIT_TIMER 用来初始化TIMER子系统
SDL_INIT_AUDIO 用来初始化AUDIO子系统
SDL_INIT_VIDEO 用来初始化VIDEO子系统
SDL_INIT_CDROM 用来初始化CDROM子系统
SDL_INIT_JOYSTICK 用来初始化JOYSTICK子系统
SDL_INIT_NOPARACHUATE 用来防止SDL接收错误数据
SDL_INIT_EVENTTHREAD 用来初始化EVENT子系统
SDL_INIT_EVERYTHING 用来初始化以上所有
然后,利用atexit函数来设置程序正常结束前调用的函数,这里我们需要调用SDL_Quit,这样的话就我们就不需要在main函数中每个return语句前都加入SDL_Quit()了。
下面,我们就定义了一个指向SDL_Surface结构的指针screen,在SDL中,每件物体都是一个surface,你可以拥有多个surface。可以在一个surface上进行绘图或者在其他surface上绘制另外一个surface。这里,我们需要对screen所指向的surface进行绘图,就可以使用函数SDL_SetVideoMode()来设置绘图模式。
SDL_SetVideoMode函数原型,如果操作成功,则返回一个指向SDL_Surface的指针,否则的话返回NULL。
SDL_Surface *SDL_SetVideoMode(int width, int height, intbpp, Uint32 flags);
前三个参数分别为屏幕宽度,高度和屏幕上的每象素包含的位数(bits perpixel,BPP)。如果填入0则SDL会自动选择最合适的BPP。第四个参数是一些特殊标志位的集合。有以下这些:
SDL_SWSURFACE 在系统内存中创建Surface。
SDL_HWSURFACE 在视频内存中创建Surface。
SDL_ASYNCBLIT 允许在显示surface上使用异步更新。在单CPU机器上会变慢,但在SMP系统上会有显著的性能提升。
SDL_ANYFORMAT 如果指定位数的bpp不可用,那么SDL就会模拟使用阴影surface,使用SDL_ANYFORMAT则会避免,不管色深强制SDL使用视频surface。
SDL_HWPALETTE 给予SDL特许的调色板访问权,如果设定这个标志位,就不需要总是使用SDL_SetColors或者SDL_SetPalette来获取所需的颜色。
SDL_DOUBLEBUF 允许硬件双缓冲,但必须同时设置SDL_HWSURFACE,调用SDL_Flip将会flip整个缓冲并且更新屏幕,所有的绘制将会在当前未显示的surface上发生。如果双缓冲被允许,那么SDL_Flip将会对整个屏幕进行SDL_UpdateRect操作。
SDL_FULLSCREEN SDL将会尝试使用全屏模式,如果硬件分辨率的调整由于某种情况无法完成,那么下一个稍高的分辨率将会被使用,并且显示窗口将会处于一个黑色背景的中央。
SDL_OPENGL 创建一个OPENGL渲染设备上下文,但使用前必须调用函数SDL_GL_SetAttribute对OpenGL进行视频属性设置。
SDL_OPENGLBLIT 和上一个选项一样创建一个OPENGL渲染设备上下文,但是允许使用正常的blitting操作。2D屏幕surface将会拥有一个alpha通道,而且必须调用函数SDL_UpdateRects来更新屏幕变化。
SDL_RESIZABLE 创建一个可伸缩大小的窗口,当用户调整窗口大小时,将会触发一个SDL_VIDEORESIZE事件,SDL_SetVideoMode将会使用新大小作为参数再次被调用。
SDL_NOFRAME SDL_NOFRAME将会创建出一个没有标题栏和边界修饰的窗口,SDL_FULLSCREEN方式将自动设置此标志位。
同样,我们可以调用SDL_GetError来获取发生错误的详细信息。
下面是程序的运行截图:
如果对上面的程序进行编译运行,那么只能得到一闪而过的一个黑色的窗口。若要绘制真正的图形,我们则需要对窗口进行绘制,并且对基本的键盘鼠标事件进行处理。
下面就是一个完整的屏幕绘图的程序:
----------------------------------------------------------------------
#include"libnge.h"
#include"stdio.h"
void Slock(SDL_Surface *screen)
{
if( SDL_MUSTLOCK(screen) )
{
if( SDL_LockSurface(screen)format, R,G, B);
switch(screen->format->BytesPerPixel)
{
case 1: // Assuming 8-bpp
{
Uint8*bufp;
bufp = (Uint8*)screen->pixels + y*screen->pitch + x;
*bufp =color;
}
break;
case 2: // Probably 15-bpp or16-bpp
{
Uint16*bufp;
bufp =(Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp =color;
}
break;
case 3: // Slow 24-bpp mode,usually not used
{
Uint8*bufp;
bufp = (Uint8*)screen->pixels + y*screen->pitch + x * 3;
if(SDL_BYTEORDER== SDL_LIL_ENDIAN)
{
bufp[0]= color;
bufp[1]= color >> 8;
bufp[2]= color >> 16;
}
else
{
bufp[2]= color;
bufp[1]= color >> 8;
bufp[0]= color >> 16;
}
}
break;
case 4: // Probably32-bpp
{
Uint32*bufp;
bufp =(Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp =color;
}
break;
}
}
voidDrawScene(SDL_Surface *screen)
{
Slock(screen);
for(int x=0;xformat->BitsPerPixel);
int done=0;
while(done == 0)
{
SDL_Event event;
while (SDL_PollEvent(&event) )
{
if (event.type == SDL_QUIT )
{
done = 1;
}
if (event.type == SDL_KEYDOWN )
{
if( event.key.keysym.sym == SDLK_ESCAPE )
{
done = 1;
}
}
}
DrawScene(screen);
}
exit(0);
}
---------------------------------------------------------------
蓝色代码是在前一份代码上添加的部分,主要是完成了绘图锁定,绘图,及消息处理。
由于绘制的屏幕不能同时接受两个函数的同时操作,我们需要其他两个辅助函数,用于在绘制前对屏幕进行锁定,以及在绘制完成之后解除锁定。这两个工作一般由SDL_MUSTLOK(SDL_Surface*screen)和SDL_UnlockSurface(SDL_Surface*screen)完成。上面使用了两个自定义的函数,简单一些。
然后就是绘制了,绘制的基本原理是,先在缓冲区绘制,再一次性将缓冲区绘制到屏幕上。这样比起一次一个象素点在屏幕上绘图的方式效率更高,速度更快,也不易出错。首先使用循环在screen所指向的surface(缓冲区)上绘制,然后调用SDL_Flip函数将screensurface绘制到真实电脑屏幕上。SDL_Flip函数的作用是:在支持双缓冲(double-buffering)的硬件上,建立flip并返回。硬件将等待verticalretrace,然后在下一个视频surfaceblit或者执行锁定返回前交换视频缓冲区。如果硬件不支持双缓冲,那么等同于调用SDL_UpdateRect(screen,0, 0, 0, 0),即对整个screen的绘制区域进行刷新。
接下来是消息处理,在SDL中,采用了结构SDL_Event来描述事件,并采用循环的机制对事件进行处理,程序中使用一个SDL_Event的对象event来检查事件的发生,这里用一个while循环,不断的调用函数SDL_PollEvent来获取事件,得到的消息将会自动填充event对象,在循环内部,通过判断不同的消息类型,从而做出不同的处理。
下面是程序运行的截图:
发表评论
-
用Wscript的Arguments属性实现vbs的命令行参数形式启动
2012-01-20 09:56 1181用Wscript的Arguments属性实现vbs的命令行参数 ... -
VBS--自动定时截图工具
2012-01-20 09:56 872VBS--自动定时截图工具 2010年09月01日 一、 ... -
使用 Iisftp.vbs 创建 FTP 站点
2012-01-20 09:56 626使用 Iisftp.vbs 创建 FTP ... -
CuteFTP上传脚本(VBS)
2012-01-20 09:56 674CuteFTP上传脚本(VBS) 2010年08月13日 ... -
VBS脚本常用经典代码收集
2012-01-20 09:56 937VBS脚本常用经典代码收集 2010年06月21日 1. ... -
vb读取txt文件到textbox (一)
2012-01-19 15:00 891vb读取txt文件到textbox (一) 2011年05月 ... -
2011-12-30
2012-01-19 15:00 5702011-12-30 2011年12月30日 用vbs来 ... -
VBScript+Asp(15)
2012-01-19 15:00 600VBScript+Asp(15) 2011年07月18日 ... -
read.asp
2012-01-19 15:00 641read.asp 2011年04月20日 ... -
FSO 读写文本文件
2012-01-19 15:00 564FSO 读写文本文件 2010年06月06日 Optio ... -
显卡3D管理程序设置与游戏画质的关系
2012-01-17 04:45 3454显卡3D管理程序设置与 ... -
opengl........
2012-01-17 04:43 669opengl........ 2010年06月30 ... -
狂飙GMA900/950 OpenGL性能.(CS玩家必看)
2012-01-17 04:43 1569狂飙GMA900/950 OpenGL性能.(CS玩家必看) ... -
一个Vislau Studio 2010 C++环境下基于OpenGL API 三维编程的实例(原创)
2012-01-17 04:43 678一个Vislau Studio 2010 C++环境下基于Op ... -
Nutch源代码学习-解读Nutch-运行,爬行过程
2012-01-16 03:38 557Nutch源代码学习-解读Nutch-运行,爬行过程 201 ... -
ASP.NET考试资料
2012-01-16 03:37 670ASP.NET考试资料 2009年06 ... -
.net开发工程师应该知道些什么
2012-01-16 03:37 1092.net开发工程师应该知道些什么 2010年05月29日 ... -
c# 面试题目
2012-01-16 03:37 731c# 面试题目 2009年11月13日 问答题沿用 ...
相关推荐
SDL资源子系统头文件
SDL电子档学习,基于c语言,附有代码,可以很快的学习
SDL电子资料
对SDL研究的兄得 可以下载此资源 详细的讲解sdl 库资源 助大家学习使用
--enable-timers 启用计时器子系统 --enable-endian 大小端设置 --enable-file 启用文件系统 --enable-esd 支持Enlightened(文明)声音后台程序 --enable-nas 支持NAS(网络连接存储)声卡API --enable-diskaudio 支持...
SDL入门学习资料pdf
学习SDL的一份很好的资料,讲的很详细,SDL 入门教程
对SDL1.2的源码进行编译,生成SDL.dll和SDLMain.lib文件,便于不想要进行搭建编译环境,而想要学习SDL1.2的朋友,因为SDL1和SDL2之间的差别还是很大的,对于Focus On SDL而言,就是利用的SDL1.*,而网上下载很少有...
SDL学习资料。
SDL_Image SDL SDLProgram SDL_Image SDL SDLProgram SDL_Image SDL SDLProgram SDL_Image SDL SDLProgram
VC 用的SDL库 1.3的,里面包含SDL.lid SDL.dll SDL.h
SDL强大不用解释,全面学习了解是必须的。
个人介绍 滴滴SDL建设历程概览 滴滴SDL建设历程详解 滴滴SDL现在与未来
SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽SDL2 拖拽
sdl源码,用于绘制视频,图片,解析和播放音频文件,已经编译成功,可以直接使用,也可以自己修改重新编译
SDL是一套开放源代码的跨平台多媒体开发库,使用C语言写成
sdl.rar SDL2-2.0.14 SDL源码
SDL官方中文资料,介绍SDL基本用法,并附有一些实例。
android-project sdl ffmpeg play mpg video