简单的象素绘制
下文从使用SDL的编程 函数开始,介绍了如何使用SDL在屏幕上进行象素绘制的基本知识,并给出了一个简单的例子。
如果要在VC中用SDL库,必须在源文件头部包含以下头文件:
初始化SDL是通过SDL_Init()函数来实现的。如果初始化失败,函数返回值为0。函数只接受初始化对象作为参数。如果要 初始化视频屏幕,传入常数SDL_INIT_VIDEO作为参数;初始化音频,传入常数SDL_INIT_AUDIO;如果同时初始化视频和音频,传入 SDL_INIT_VIDEO|SDL_INIT_AUDIO。其它还有一些量可以传入作为参数的(如果同时传入多个量要使用|将它们隔开):
如果我们要初始化,可以使用如下语句:
如果初始化失败,则函数SDL_GetError()返回关于错误的一个字符串提示信息。
当从你的C++语句返回时,记住使用SDL_Quit()进行程序的清理工作,否则就会出现奇怪的现象。可以使用如下语句进行描述:
这样的话就不需要在main函数中每个return语句前加入SDL_Quit()了。
在SDL中你可以拥有多个surface,每件物体都是一个surface。你可以在一个surface上进行绘图或者在其他surface上绘制另外 一个surface。程序中一个surface的表示即为指向结构SDL_Surface的指针。如果要获得一个surface只要如下定义:
如果需要对screen所指向的surface上进行绘图,你可以使用函数SDL_SetVideoMode()来设置屏幕分辨率:
前三个参数分别为屏幕宽度,高度和屏幕上的每象素包含的位数(bits per pixel, BPP)。如果填入0则SDL自动选择最合适的BPP。第四个参数用来给出某些特殊标志位。如果要在屏幕上进行图形绘制就必须使用 SDL_HWSURFACE或者SDL_SWSURFACE。以下给出了一个你可以指定的标志位:
SDL_SWSURFACE:在系统内存中创建视频Surface
SDL_HWSURFACE:在视频内存中创建视频Surface
SDL_ASYNCBLIT:允许在显示surface上使用异步更新。在单CPU机器上会变慢,但在SMP系统上会有显著的性能提升。
SDL_ANYFORMAT:一般的,如果指定位数的bpp不可用,那么SDL就会模拟使用阴影surface。如果传入SDL_ANYFORMAT就会阻止这样做,并且不管色深强制使用视频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 rendering context。使用前必须已经使用SDL_GL_SetAttribute对OpenGL视频属性进行设置。
SDL_OPENGLBLIT: 和上一个选项一样创建一个 OPENGL rendering context, 但是允许使用正常的blitting操作。
SDL_RESIZABLE; 创建一个可伸缩大小的窗口。当用户调整窗口大小时,将会触发一个SDL_VIDEORESIZE事件,SDL_SetVideoMode将会使用新大小作为参数再次被调用。
SDL_NOFRAME: 如果可以的话,SDL_NOFRAME将会创建出一个没有标题栏和边界修饰的窗口,全屏方式自动设置此标志位。
建议使用SDL_HWSURFACE | SDL_DOUBLEBUF,如果出现错误可以尝试使用SDL_SWSURFACE。
SDL_SetVideoMode如果操作成功,则返回一个指向SDL_Surface的指针,否则的话返回NULL。可以使用如下语句检查发生的错误:
以上介绍了如何对SDL进行初始化,下面可以开始绘制了。但是还有一些需要注意的关键地方,首先是一些SDL使用的容易让人产生迷惑的数据类型:
还有,有的时候如果初始化出现错误,没必要完全退出。例如当初始化了SDL_INIT_VIDEO而没有初始化SDL_INIT_AUDIO,那么你可 以继续这个错误只是没有音频而已。要检查是否音频初始化是否成功,可以使用SDL_WasInit()函数来检查。下面是一个例子:
你可以在程序初始化的某些地方加入以上语句。
以下是SDL介绍中进行象素绘制的语句,可以暂时不需要完全了解其中的意思:
通过这个函数,可以传递给surface要绘制的点的(x,y)坐标和RGB值。 更多内容请看游戏开发、网络游戏攻略、Solaris基础知识入门专题,或进入讨论组讨论。
如果要在VC中用SDL库,必须在源文件头部包含以下头文件:
#include “SDL.h” |
初始化SDL是通过SDL_Init()函数来实现的。如果初始化失败,函数返回值为0。函数只接受初始化对象作为参数。如果要 初始化视频屏幕,传入常数SDL_INIT_VIDEO作为参数;初始化音频,传入常数SDL_INIT_AUDIO;如果同时初始化视频和音频,传入 SDL_INIT_VIDEO|SDL_INIT_AUDIO。其它还有一些量可以传入作为参数的(如果同时传入多个量要使用|将它们隔开):
SDL_INIT_TIMER SDL_INIT_AUDIO SDL_INIT_VIDEO SDL_INIT_CDROM SDL_INIT_JOYSTICK SDL_INIT_NOPARACHUATE SDL_INIT_EVENTTHREAD SDL_INIT_EVERYTHING |
如果我们要初始化,可以使用如下语句:
if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) { printf(“Unable to init SDL: %s"n”, SDL_GetError()); return 1; } |
如果初始化失败,则函数SDL_GetError()返回关于错误的一个字符串提示信息。
当从你的C++语句返回时,记住使用SDL_Quit()进行程序的清理工作,否则就会出现奇怪的现象。可以使用如下语句进行描述:
atexit(SDL_Quit); |
这样的话就不需要在main函数中每个return语句前加入SDL_Quit()了。
在SDL中你可以拥有多个surface,每件物体都是一个surface。你可以在一个surface上进行绘图或者在其他surface上绘制另外 一个surface。程序中一个surface的表示即为指向结构SDL_Surface的指针。如果要获得一个surface只要如下定义:
SDL_Surface *screen; |
如果需要对screen所指向的surface上进行绘图,你可以使用函数SDL_SetVideoMode()来设置屏幕分辨率:
screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); |
前三个参数分别为屏幕宽度,高度和屏幕上的每象素包含的位数(bits per pixel, BPP)。如果填入0则SDL自动选择最合适的BPP。第四个参数用来给出某些特殊标志位。如果要在屏幕上进行图形绘制就必须使用 SDL_HWSURFACE或者SDL_SWSURFACE。以下给出了一个你可以指定的标志位:
SDL_SWSURFACE:在系统内存中创建视频Surface
SDL_HWSURFACE:在视频内存中创建视频Surface
SDL_ASYNCBLIT:允许在显示surface上使用异步更新。在单CPU机器上会变慢,但在SMP系统上会有显著的性能提升。
SDL_ANYFORMAT:一般的,如果指定位数的bpp不可用,那么SDL就会模拟使用阴影surface。如果传入SDL_ANYFORMAT就会阻止这样做,并且不管色深强制使用视频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 rendering context。使用前必须已经使用SDL_GL_SetAttribute对OpenGL视频属性进行设置。
SDL_OPENGLBLIT: 和上一个选项一样创建一个 OPENGL rendering context, 但是允许使用正常的blitting操作。
SDL_RESIZABLE; 创建一个可伸缩大小的窗口。当用户调整窗口大小时,将会触发一个SDL_VIDEORESIZE事件,SDL_SetVideoMode将会使用新大小作为参数再次被调用。
SDL_NOFRAME: 如果可以的话,SDL_NOFRAME将会创建出一个没有标题栏和边界修饰的窗口,全屏方式自动设置此标志位。
建议使用SDL_HWSURFACE | SDL_DOUBLEBUF,如果出现错误可以尝试使用SDL_SWSURFACE。
SDL_SetVideoMode如果操作成功,则返回一个指向SDL_Surface的指针,否则的话返回NULL。可以使用如下语句检查发生的错误:
If ( screen == NULL ) { printf(“Unable to set 640x480 video: %s"n”, SDL_GetError()); return 1; } |
以上介绍了如何对SDL进行初始化,下面可以开始绘制了。但是还有一些需要注意的关键地方,首先是一些SDL使用的容易让人产生迷惑的数据类型:
Uint8 – 相当于unsigned char Uint16 – 16位(2字节) unsigned integer Uint32 – 32位(4字节) unsigned integer Uint64 - 64位(8字节) unsigned integer Sint8 – 相当于signed char Sint16 – 16位(2字节) signed integer Sint32 – 32位(4字节) signed integer Sint64 - 64位(8字节) signed integer |
还有,有的时候如果初始化出现错误,没必要完全退出。例如当初始化了SDL_INIT_VIDEO而没有初始化SDL_INIT_AUDIO,那么你可 以继续这个错误只是没有音频而已。要检查是否音频初始化是否成功,可以使用SDL_WasInit()函数来检查。下面是一个例子:
Uint32 init = SDL_WasInit(SDL_INIT_AUDIO); If (init & SDL_INIT_AUDIO) { sound = 1; } else { sound = 0; } |
你可以在程序初始化的某些地方加入以上语句。
以下是SDL介绍中进行象素绘制的语句,可以暂时不需要完全了解其中的意思:
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) { Uint32 color = SDL_MapRGB(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 or 16-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: // Probably 32-bpp { Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = color; } break; } } |
通过这个函数,可以传递给surface要绘制的点的(x,y)坐标和RGB值。 更多内容请看游戏开发、网络游戏攻略、Solaris基础知识入门专题,或进入讨论组讨论。