`
izuoyan
  • 浏览: 9231731 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

SDL源码阅读笔记(2) video dirver的初始化及选择

阅读更多

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

讨论新闻组及文件

前一篇文章 讲了SDL的除video以外的大部分模块。本文主要关注SDL的video模块部分。

SDL中的video模块包含了大部分与平台相关的代码,并且SDL处理的很有技巧性,这里利用C语言的函数指针来模拟了一种类似于面向对象的效果。
主要的关键点在
SDL_VideoDevice *current_video = NULL;
这一句定义的全局变量current_video上,我们先来看看这个变量类型SDL_VideoDevice。
主要在SDL_sysvideo.h这个文件中

struct SDL_VideoDevice {
/* * * */
/* The name of this video driver */
const char *name;

/* * * */
/* Initialization/Query functions */

/* Initialize the native video subsystem, filling 'vformat' with the
"best" display pixel format, returning 0 or -1 if there's an error.
*/
int (*VideoInit)(_THIS, SDL_PixelFormat *vformat);

/* List the available video modes for the given pixel format, sorted
from largest to smallest.
*/
SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags);

/* Set the requested video mode, returning a surface which will be
set to the SDL_VideoSurface. The width and height will already
be verified by ListModes(), and the video subsystem is free to
set the mode to a supported bit depth different from the one
specified -- the desired bpp will be emulated with a shadow
surface if necessary. If a new mode is returned, this function
should take care of cleaning up the current mode.
*/
SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags);

/* Toggle the fullscreen mode */
int (*ToggleFullScreen)(_THIS, int on);

/* This is called after the video mode has been set, to get the
initial mouse state. It should queue events as necessary to
properly represent the current mouse focus and position.
*/
void (*UpdateMouse)(_THIS);

/* Create a YUV video surface (possibly overlay) of the given
format. The hardware should be able to perform at least 2x
scaling on display.
*/
SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height,
Uint32 format, SDL_Surface *display);

/* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) }
of the physical palette to those in 'colors'. If the device is
using a software palette (SDL_HWPALETTE not set), then the
changes are reflected in the logical palette of the screen
as well.
The return value is 1 if all entries could be set properly
or 0 otherwise.
*/
int (*SetColors)(_THIS, int firstcolor, int ncolors,
SDL_Color *colors);

/* This pointer should exist in the native video subsystem and should
point to an appropriate update function for the current video mode
*/
void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects);

/* Reverse the effects VideoInit() -- called if VideoInit() fails
or if the application is shutting down the video subsystem.
*/
void (*VideoQuit)(_THIS);

/* * * */
/* Hardware acceleration functions */

/* Information about the video hardware */
SDL_VideoInfo info;

/* The pixel format used when SDL_CreateRGBSurface creates SDL_HWSURFACEs with alpha */
SDL_PixelFormat* displayformatalphapixel;

/* Allocates a surface in video memory */
int (*AllocHWSurface)(_THIS, SDL_Surface *surface);

/* Sets the hardware accelerated blit function, if any, based
on the current flags of the surface (colorkey, alpha, etc.)
*/
int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst);

/* Fills a surface rectangle with the given color */
int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);

/* Sets video mem colorkey and accelerated blit function */
int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key);

/* Sets per surface hardware alpha value */
int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value);

/* Returns a readable/writable surface */
int (*LockHWSurface)(_THIS, SDL_Surface *surface);
void (*UnlockHWSurface)(_THIS, SDL_Surface *surface);

/* Performs hardware flipping */
int (*FlipHWSurface)(_THIS, SDL_Surface *surface);

/* Frees a previously allocated video surface */
void (*FreeHWSurface)(_THIS, SDL_Surface *surface);

/* * * */
/* Gamma support */

Uint16 *gamma;

/* Set the gamma correction directly (emulated with gamma ramps) */
int (*SetGamma)(_THIS, float red, float green, float blue);

/* Get the gamma correction directly (emulated with gamma ramps) */
int (*GetGamma)(_THIS, float *red, float *green, float *blue);

/* Set the gamma ramp */
int (*SetGammaRamp)(_THIS, Uint16 *ramp);

/* Get the gamma ramp */
int (*GetGammaRamp)(_THIS, Uint16 *ramp);

/* * * */
/* OpenGL support */

/* Sets the dll to use for OpenGL and loads it */
int (*GL_LoadLibrary)(_THIS, const char *path);

/* Retrieves the address of a function in the gl library */
void * (*GL_GetProcAddress)(_THIS, const char *proc);

/* Get attribute information from the windowing system. */
int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int * value);

/* Make the context associated with this driver current */
int (*GL_MakeCurrent)(_THIS);

/* Swap the current buffers in double buffer mode. */
void (*GL_SwapBuffers)(_THIS);

/* OpenGL functions for SDL_OPENGLBLIT */
#if SDL_VIDEO_OPENGL
#if !defined(__WIN32__)
#define WINAPI
#endif
#define SDL_PROC(ret,func,params) ret (WINAPI *func) params;
#include "SDL_glfuncs.h"
#undef SDL_PROC

/* Texture id */
GLuint texture;
#endif
int is_32bit;

/* * * */
/* Window manager functions */

/* Set the title and icon text */
void (*SetCaption)(_THIS, const char *title, const char *icon);

/* Set the window icon image */
void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask);

/* Iconify the window.
This function returns 1 if there is a window manager and the
window was actually iconified, it returns 0 otherwise.
*/
int (*IconifyWindow)(_THIS);

/* Grab or ungrab keyboard and mouse input */
SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode);

/* Get some platform dependent window information */
int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info);

/* * * */
/* Cursor manager functions */

/* Free a window manager cursor
This function can be NULL if CreateWMCursor is also NULL.
*/
void (*FreeWMCursor)(_THIS, WMcursor *cursor);

/* If not NULL, create a black/white window manager cursor */
WMcursor *(*CreateWMCursor)(_THIS,
Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);

/* Show the specified cursor, or hide if cursor is NULL */
int (*ShowWMCursor)(_THIS, WMcursor *cursor);

/* Warp the window manager cursor to (x,y)
If NULL, a mouse motion event is posted internally.
*/
void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y);

/* If not NULL, this is called when a mouse motion event occurs */
void (*MoveWMCursor)(_THIS, int x, int y);

/* Determine whether the mouse should be in relative mode or not.
This function is called when the input grab state or cursor
visibility state changes.
If the cursor is not visible, and the input is grabbed, the
driver can place the mouse in relative mode, which may result
in higher accuracy sampling of the pointer motion.
*/
void (*CheckMouseMode)(_THIS);

/* * * */
/* Event manager functions */

/* Initialize keyboard mapping for this driver */
void (*InitOSKeymap)(_THIS);

/* Handle any queued OS events */
void (*PumpEvents)(_THIS);

/* * * */
/* Data common to all drivers */
SDL_Surface *screen;
SDL_Surface *shadow;
SDL_Surface *visible;
SDL_Palette *physpal; /* physical palette, if != logical palette */
SDL_Color *gammacols; /* gamma-corrected colours, or NULL */
char *wm_title;
char *wm_icon;
int offset_x;
int offset_y;
SDL_GrabMode input_grab;

/* Driver information flags */
int handles_any_size;/* Driver handles any size video mode */

/* * * */
/* Data used by the GL drivers */
struct {
int red_size;
int green_size;
int blue_size;
int alpha_size;
int depth_size;
int buffer_size;
int stencil_size;
int double_buffer;
int accum_red_size;
int accum_green_size;
int accum_blue_size;
int accum_alpha_size;
int stereo;
int multisamplebuffers;
int multisamplesamples;
int accelerated;
int swap_control;
int driver_loaded;
char driver_path[256 ];
void * dll_handle;
} gl_config;

/* * * */
/* Data private to this driver */
struct SDL_PrivateVideoData *hidden;
struct SDL_PrivateGLData *gl_data;

/* * * */
/* The function used to dispose of this structure */
void (*free)(_THIS);
};

这个结构主要包含的是函数指针,每个函数指针表示了一个与平台相关的函数。在运行时,给这些函数指针赋值,指定成对应平台的函数实现,以此实现了使用此结构指针current_video的上层的代码的稳定与一致。

这里首先关心两个流程,其一,初始化给这些函数指针赋值的过程。

这个过程在SDL_VideoInit函数中实现:
SDL初始化基本流程:
SDL_Init(SDL_INIT_VIDEO)->SDL_InitSubSystem(SDL_INIT_VIDEO)->SDL_VideoInit()
中途会调用以"SDL_VIDEODRIVER"为参数调用SDL_getenv函数来获取全局配置中指定的对应的video driver。
代码如下:

if ( SDL_VideoInit(SDL_getenv("SDL_VIDEODRIVER" ),
(flags&SDL_INIT_EVENTTHREAD)) < 0 ) {
return (-1 );
}

我没有设定,所以会以name = NULL为第一参数来调用SDL_VideoInit,也就是让SDL自己选择一个video driver。
SDL会从一个

typedef struct VideoBootStrap {
const char *name;
const char *desc;
int (*available)(void );
SDL_VideoDevice *(*create)(int devindex);
} VideoBootStrap;

结构的全局变量bootstrap数组中选取一个可以使用的video driver。
一共有这么多可能的video driver:

/* Available video drivers */
static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_QUARTZ
&QZ_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_X11
&X11_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DGA
&DGA_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_NANOX
&NX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_IPOD
&iPod_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_QTOPIA
&Qtopia_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WSCONS
&WSCONS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_FBCON
&FBCON_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DIRECTFB
&DirectFB_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_PS2GS
&PS2GS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_PS3
&PS3_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_GGI
&GGI_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_VGL
&VGL_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_SVGALIB
&SVGALIB_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_GAPI
&GAPI_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WINDIB
&WINDIB_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DDRAW
&DIRECTX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_BWINDOW
&BWINDOW_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_TOOLBOX
&TOOLBOX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DRAWSPROCKET
&DSp_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_PHOTON
&ph_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_EPOC
&EPOC_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_XBIOS
&XBIOS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_GEM
&GEM_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_PICOGUI
&PG_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DC
&DC_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_NDS
&NDS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_RISCOS
&RISCOS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_OS2FS
&OS2FSLib_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_AALIB
&AALIB_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_CACA
&CACA_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
#endif
NULL
};

都是通过宏来筛选的。
- bootstrap 0x100a2b1c bootstrap VideoBootStrap * [4]
+ [0x0] 0x100a1160 _WINDIB_bootstrap {name=0x10099428 "windib" desc=0x1009940c "Win95/98/NT/2000/CE GDI" available=0x1005eaf0 ...} VideoBootStrap *
+ [0x1] 0x100a25e8 _DIRECTX_bootstrap {name=0x10099ab4 "directx" desc=0x10099a98 "Win95/98/2000 DirectX" available=0x100651d0 ...} VideoBootStrap *
+ [0x2] 0x100a2aec _DUMMY_bootstrap {name=0x100995a4 "dummy" desc=0x1009b3e4 "SDL dummy video driver" available=0x10072090 ...} VideoBootStrap *
+ [0x3] 0x00000000 {name=??? desc=??? available=??? ...} VideoBootStrap *

在我的电脑上(Win32),一共有上面3种可能,windib(即GDI),directX,dummy。事实上OpenGL在Win32的环境中都没有列出来,当然,但是在以前的例子中,我还是使用了SDL+OpenGL来渲染,原因在于video毕竟不是如同其名字所示,仅仅包含渲染或者视频方面的东西,它其实代表了大部分SDL与平台相关的东西,渲染在SDL中也仅仅是占比较小的一部分。

选取video driver的时候,先调用VideoBootStrap 结构中的available 函数来判断此video driver有效则通过此结构的create函数来创建一个video driver.
如下:

for ( i=0 ; bootstrap[i]; ++i ) {
if ( bootstrap[i]->available() ) {
video = bootstrap[i]->create(index);
if ( video != NULL ) {
break ;
}
}
}

创建的时候附带index,并且一旦创建成功,就停止了创建过程,在我的例子中,由于GDI方式排在第一,所以事实上,SDL在Win32环境下默认是选择了使用GDI的video driver。
此GDI video driver的create函数如下:

static SDL_VideoDevice *DIB_CreateDevice(int devindex)
{
SDL_VideoDevice *device;

/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *)SDL_malloc(sizeof (SDL_VideoDevice));
if ( device ) {
SDL_memset(device, 0 , (sizeof *device));
device->hidden = (struct SDL_PrivateVideoData *)
SDL_malloc((sizeof *device->hidden));
if (device->hidden){
SDL_memset(device->hidden, 0 , (sizeof *device->hidden));
device->hidden->dibInfo = (DibInfo *)SDL_malloc((sizeof (DibInfo)));
if (device->hidden->dibInfo == NULL )
{
SDL_free(device->hidden);
device->hidden = NULL ;
}
}

device->gl_data = (struct SDL_PrivateGLData *)
SDL_malloc((sizeof *device->gl_data));
}
if ( (device == NULL ) || (device->hidden == NULL ) ||
(device->gl_data == NULL ) ) {
SDL_OutOfMemory();
DIB_DeleteDevice(device);
return (NULL );
}
SDL_memset(device->hidden->dibInfo, 0 , (sizeof *device->hidden->dibInfo));
SDL_memset(device->gl_data, 0 , (sizeof *device->gl_data));

/* Set the function pointers */
device->VideoInit = DIB_VideoInit;
device->ListModes = DIB_ListModes;
device->SetVideoMode = DIB_SetVideoMode;
device->UpdateMouse = WIN_UpdateMouse;
device->SetColors = DIB_SetColors;
device->UpdateRects = NULL ;
device->VideoQuit = DIB_VideoQuit;
device->AllocHWSurface = DIB_AllocHWSurface;
device->CheckHWBlit = NULL ;
device->FillHWRect = NULL ;
device->SetHWColorKey = NULL ;
device->SetHWAlpha = NULL ;
device->LockHWSurface = DIB_LockHWSurface;
device->UnlockHWSurface = DIB_UnlockHWSurface;
device->FlipHWSurface = NULL ;
device->FreeHWSurface = DIB_FreeHWSurface;
device->SetGammaRamp = DIB_SetGammaRamp;
device->GetGammaRamp = DIB_GetGammaRamp;
#if SDL_VIDEO_OPENGL
device->GL_LoadLibrary = WIN_GL_LoadLibrary;
device->GL_GetProcAddress = WIN_GL_GetProcAddress;
device->GL_GetAttribute = WIN_GL_GetAttribute;
device->GL_MakeCurrent = WIN_GL_MakeCurrent;
device->GL_SwapBuffers = WIN_GL_SwapBuffers;
#endif
device->SetCaption = WIN_SetWMCaption;
device->SetIcon = WIN_SetWMIcon;
device->IconifyWindow = WIN_IconifyWindow;
device->GrabInput = WIN_GrabInput;
device->GetWMInfo = WIN_GetWMInfo;
device->FreeWMCursor = WIN_FreeWMCursor;
device->CreateWMCursor = WIN_CreateWMCursor;
device->ShowWMCursor = WIN_ShowWMCursor;
device->WarpWMCursor = WIN_WarpWMCursor;
device->CheckMouseMode = WIN_CheckMouseMode;
device->InitOSKeymap = DIB_InitOSKeymap;
device->PumpEvents = DIB_PumpEvents;

/* Set up the windows message handling functions */
WIN_Activate = DIB_Activate;
WIN_RealizePalette = DIB_RealizePalette;
WIN_PaletteChanged = DIB_PaletteChanged;
WIN_WinPAINT = DIB_WinPAINT;
HandleMessage = DIB_HandleMessage;

device->free = DIB_DeleteDevice;

/* We're finally ready */
return device;
}

开始时为video driver分配内存,然后为相应的参数赋值,最最重要的就是为video driver的函数指针赋值,赋值成当前video driver的函数,以此实现我开始说的,以C语言实现类似面向对象的效果。
video driver的那一堆函数指针就像是抽象的接口,这里的函数就像是子类的实现。上层逻辑只需要使用video driver的指针并调用其中的函数即可,完全统一,并且不用关心指针具体是调用了哪个"子类“的函数。因为习惯了C++,我很少使用C语言来编写大规模的代码,所以对这些特性并不是非常熟悉,但是在C语言实现面向对象特性方面,我见过几派,我感觉这种方式算是比较好的,比完全使用宏来模拟C++的效果看上去要更加容易理解和自然。当然,因为C语言的确没有"标准"的面向对象实现方式,所以到底那个更好,也只能是见仁见智的问题了,估计也会像"大括号战争”一样没有休止。

此处还值得一提的是,SDL_VIDEO_OPENGL宏是默认开启的,也就是说,在Win32下使用GDI这个默认的video driver时,
SDL进行了
device->GL_LoadLibrary = WIN_GL_LoadLibrary;
device->GL_GetProcAddress = WIN_GL_GetProcAddress;
device->GL_GetAttribute = WIN_GL_GetAttribute;
device->GL_MakeCurrent = WIN_GL_MakeCurrent;
device->GL_SwapBuffers = WIN_GL_SwapBuffers;

这些函数的赋值。形成了对OpenGL的支持。这里与我以前了解的有些差异,因为我以前以为SDL在Win32下是默认使用DirectX加速的,现在看来并不是,就如侯捷所言,"源码面前了无秘密",这些点点滴滴的东西,也算是看源码的一种收获。

然后,我查看了文档:
SDL支持哪些系统平台?
有如下描述:

  • 有两个版本,一个是适合所有基于Win32的系统的安全版本,另一个是基于DirectX的高性能版本。
  • 安全版本的视频显示采用GDI。高性能版本采用DirectDraw,并支持硬件加速。
  • 安全版本的音频回放采用waveOut API。高性能版本采用DirectSound。

这里可以看出,默认的时候SDL使用了Win32系统的安全版本。



此步初始化后,再利用video driver自己的VideoInit函数再次进行针对特殊的video driver的初始化。然后再开始SDL的事件线程(详细内容见上节)
然后,此时已经回到SDL_InitSubSystem函数了,此函数还需要进行一些其他模块的初始化,比如时间模块,摇杆等,这里就不多讲了。

看到这里,对于初始化部分的流程应该就比较清楚了,现在有个问题:
怎么改变SDL使用的video driver的默认值?比如,改成DirectX版本的。
从上面来看,有两种办法,
其一,改变bootstrap 数组中各driver的顺序,将directX的driver提到第一,那样默认就初始化directX版本了。
其二,让SDL_getenv("SDL_VIDEODRIVER" ) 返回directX版本driver的名字。

个人感觉方法二明显更加自然一些,感觉也是SDL作者提供的选择方案。那么,尝试一下,这里我通过SDL提供的接口SDL_putenv来设置环境变量,看看效果。
根据SDL_getenv的调用及前面查看的bootstrap的值,知道SDL查看的环境变量名为SDL_VIDEODRIVER,directX表示的driver名字为directx,所以在初始化前添加如下代码:
SDL_putenv("SDL_VIDEODRIVER=directx");

可以看到效果是以"directx"为第一参数调用SDL_VideoInit,并且进入了一下代码:

for ( i=0 ; bootstrap[i]; ++i ) {
if ( SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0 ) {
if ( bootstrap[i]->available() ) {
video = bootstrap[i]->create(index);
break ;
}
}
}
此时,通过SDL_strcasecmp的调用,略过了GDI的video driver,然后使用了directX的driver。首先进入的available函数是:DX5_Available,晕了,DX5。。。。。什么年代的东西啊。。。。。。无语中。
在DX5_Available的调用中,仅仅通过以下语句判断了DINPUT.DLL和DDRAW.DLL动态库及DirectDrawCreate函数的存在,来判断DX5 driver是否可用。
DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));

同时,上述语句也说明,SDL使用的DirectX加速使用的是DX5.....并且使用的是DirectDraw,在那古老的年代,我不知道有没有D3D,不过对DDraw的使用倒是印证了我初看SDL渲染接口时的印象,抽象的接口与DDraw太像了。。。。。。。下面函数赋值的时候应该还能看到。

DX5_CreateDevice为SDL DirectX driver的创建函数,如同GDI版本一样对函数进行赋值。

/* Set the function pointers */
device->VideoInit = DX5_VideoInit;
device->ListModes = DX5_ListModes;
device->SetVideoMode = DX5_SetVideoMode;
device->UpdateMouse = WIN_UpdateMouse;
device->CreateYUVOverlay = DX5_CreateYUVOverlay;
device->SetColors = DX5_SetColors;
device->UpdateRects = NULL ;
device->VideoQuit = DX5_VideoQuit;
device->AllocHWSurface = DX5_AllocHWSurface;
device->CheckHWBlit = DX5_CheckHWBlit;
device->FillHWRect = DX5_FillHWRect;
device->SetHWColorKey = DX5_SetHWColorKey;
device->SetHWAlpha = DX5_SetHWAlpha;
device->LockHWSurface = DX5_LockHWSurface;
device->UnlockHWSurface = DX5_UnlockHWSurface;
device->FlipHWSurface = DX5_FlipHWSurface;
device->FreeHWSurface = DX5_FreeHWSurface;
device->SetGammaRamp = DX5_SetGammaRamp;
device->GetGammaRamp = DX5_GetGammaRamp;
#if SDL_VIDEO_OPENGL
device->GL_LoadLibrary = WIN_GL_LoadLibrary;
device->GL_GetProcAddress = WIN_GL_GetProcAddress;
device->GL_GetAttribute = WIN_GL_GetAttribute;
device->GL_MakeCurrent = WIN_GL_MakeCurrent;
device->GL_SwapBuffers = WIN_GL_SwapBuffers;
#endif
device->SetCaption = WIN_SetWMCaption;
device->SetIcon = WIN_SetWMIcon;
device->IconifyWindow = WIN_IconifyWindow;
device->GrabInput = WIN_GrabInput;
device->GetWMInfo = WIN_GetWMInfo;
device->FreeWMCursor = WIN_FreeWMCursor;
device->CreateWMCursor = WIN_CreateWMCursor;
device->ShowWMCursor = WIN_ShowWMCursor;
device->WarpWMCursor = WIN_WarpWMCursor;
device->CheckMouseMode = WIN_CheckMouseMode;
device->InitOSKeymap = DX5_InitOSKeymap;
device->PumpEvents = DX5_PumpEvents;

/* Set up the windows message handling functions */
WIN_Activate = DX5_Activate;
WIN_RealizePalette = DX5_RealizePalette;
WIN_PaletteChanged = DX5_PaletteChanged;
WIN_WinPAINT = DX5_WinPAINT;
HandleMessage = DX5_HandleMessage;

这里我们可以看到,相对GDI版本而言,除了速度之外,DirectX版本明显支持的特性更多,上面的函数指针赋值就没有GDI版本那么多NULL了,全部都有对应的函数。
最让人惊讶的时候,还是有OpenGL的函数。最后经过我测试,的确也是能够使用OpenGL。。。。。。
很显然,关键在于
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 16, SDL_OPENGL);

一句的调用。

因为本文太长,在Google Document上输入都已经很卡了,所以留待下篇文章再看。


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

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

分享到:
评论

相关推荐

    SDL2源码包

    **SDL2源码包详解** **一、SDL2简介** SDL (Simple DirectMedia Layer) 是一个跨平台的开发库,用于处理图形、音频和输入设备。它的全称是"Simple DirectMedia Layer 2",是SDL的最新版本,提供了一个低级别的接口...

    sdl的linux源码包SDL2-2.0.2

    描述中的“sdl的linux源码包SDL2-2.0.2”进一步确认了这是针对Linux操作系统的SDL2库的特定版本。SDL2是SDL的第二个主要版本,它提供了一些新特性和改进,以适应现代开发需求。 **Linux运维与服务器关联** 在Linux...

    SDL2.0.3源码安装包

    例如,`SDL_Init()`函数初始化SDL系统,`SDL_CreateWindow()`创建窗口,`SDL_Renderer`和`SDL_Texture`处理渲染,`SDL_Event`结构体用于处理用户输入事件。 6. **示例代码**:在SDL2-2.0.3源代码包中,通常会包含...

    SDL2_SDL2_SDL2_

    【标题】"SDL2_SDL2_SDL2_" 指的是 Simple DirectMedia Layer 的第二版,这是一个跨平台的开发库,主要用于处理图形、音频、输入设备等方面,广泛应用于游戏开发和其他多媒体应用。SDL2 提供了底层访问硬件的能力,...

    sdl.rar SDL2-2.0.14 SDL源码

    标题"SDL.rar SDL2-2.0.14 SDL源码"表明这个压缩包包含了SDL库的源代码,具体版本为2.0.14。SDL是"Simple DirectMedia Layer"的缩写,它是一个跨平台的开发库,主要用于处理图形、音频、输入设备等多媒体功能,常...

    SDL2-2.0.2.tar.gz源码

    标题"SDL2-2.0.2.tar.gz源码"表明这是一个开源软件库的源代码包,使用的是版本控制格式`.tar.gz`,具体来说是SDL2库的2.0.2版本。SDL2是Simple DirectMedia Layer的第二版,是一个跨平台的开发库,主要用于处理...

    SDL 2.0 源码下载

    1. **头文件引用**:在你的C/C++项目中,引入`#include &lt;SDL2/SDL.h&gt;`来使用SDL的API。 2. **初始化**:调用`SDL_Init`函数启动SDL库,并设置所需的子系统,如视频和音频。 3. **创建窗口**:使用`SDL_CreateWindow`...

    SDL2源码.tar.gz

    SDL2,全称为Simple DirectMedia ...通过深入研究SDL2-2.0.9的源码,开发者不仅可以掌握SDL2库的使用,还能学习到底层系统交互、图形和音频处理、跨平台开发等多方面的知识,从而提升自己的编程技能和解决问题的能力。

    SDL库及源码.rar

    SDL库的源码通常分为多个子模块,如audio、video、render、joystick、timer等,每个模块对应库的一个功能领域。源码中包含头文件(.h)和实现文件(.c),以及构建脚本和配置文件,使得在不同平台上编译和链接变得...

    freetype2+SDL+SDL_ttf源码包及字符串转bmp图片demo

    2. **加载freetype2和SDL_ttf**:接着,你需要加载freetype2库,并通过SDL_ttf初始化字体库。这通常涉及设置字体文件路径,然后加载特定的字体和大小。 3. **创建文本表面**:使用SDL_ttf提供的函数,将字符串转换...

    SDL-1.2.15-lib包含源码

    - **初始化**:在程序开始时调用`SDL_Init`函数初始化SDL系统。 - **创建窗口**:使用`SDL_CreateWindow`创建一个窗口。 - **处理事件**:通过`SDL_PollEvent`或`SDL_PeepEvents`函数获取并处理事件。 - **渲染图形*...

    SDL2视频播放器源码

    这个程序可能包含了初始化SDL2窗口、加载FFmpeg解码器、播放视频流、处理用户输入等一系列操作。开发者可以通过分析和修改这个程序,了解如何在QT环境下集成SDL2和FFmpeg,实现自定义的视频播放功能。 通过学习和...

    SDL2-2.0.8.tar.gz

    **描述解析:** "Linux SDL 开源软件源码" 暗示这个压缩包包含的是 SDL2 库的源代码,适用于 Linux 操作系统。开源意味着任何人都可以查看、使用、修改和分发这些代码,遵循特定的开源许可证。 **标签解析:** "SDL...

    SDL2.0.4 源码及编译库

    SDL 2.0.4 源码及编译库,32,64位 & MAC。(Simple DirectMedia Layer)是一个自由的跨平台的多媒体开发包,适用于游戏、游戏SDK、演示软件、模拟器、MPEG播放器和其他应用软件。 用途广泛。

    SDL-1.2.13游戏引擎源码

    6. **视频模式设置**:源码中包含了设置窗口大小、位置、全屏模式等功能的实现,这些是游戏初始化过程的关键部分。 7. **定时器**:游戏通常需要精确的时间控制,例如帧率限制。SDL提供了定时器API,源码中可以看到...

    基于C++和SDL2.0库开发植物大战僵尸游戏源码.zip

    基于C++和SDL2.0库开发植物大战僵尸游戏源码.zip基于C++和SDL2.0库开发植物大战僵尸游戏源码.zip基于C++和SDL2.0库开发植物大战僵尸游戏源码.zip基于C++和SDL2.0库开发植物大战僵尸游戏源码.zip基于C++和SDL2.0库...

    SDL1.2编译完成文件,包括SDL.dll, SDLMain.lib,以及SDL1.2.6的源码

    对SDL1.2的源码进行编译,生成SDL.dll和SDLMain.lib文件,便于不想要进行搭建编译环境,而想要学习SDL1.2的朋友,因为SDL1和SDL2之间的差别还是很大的,对于Focus On SDL而言,就是利用的SDL1.*,而网上下载很少有...

    WINDOWS SDL2库

    在代码中,你可以通过包含`#include &lt;SDL2/SDL.h&gt;`来引入SDL2的主头文件,接着初始化SDL系统,创建窗口,加载图像,处理事件,播放音频等。例如,创建一个基本的SDL窗口的代码片段如下: ```cpp #include &lt;SDL2/SDL...

    SDL全部源代码

    SDL的全部源代码,包括SDL_image-1.2.10;SDL_mixer-1.2.11;SDL_ttf-2.0.10; SDL_net-1.2.7;SDL-1.2.15;几个源码包和为一个包,但是我不推介用源码安装的方法,最好用命令安装,但是看源码可以让你知道程序调用的原理...

    SDL2-2.28.5.zip

    SDL2-2.28.5.zip 是一个包含了SDL 2.28.5版本的压缩包,提供了最新版的SDL库文件和相关的开发资源。 SDL 2.0是SDL的最新主要版本,它在1.2版本的基础上进行了大量的优化和更新,以适应现代操作系统和硬件环境的变化...

Global site tag (gtag.js) - Google Analytics