运用SDL库设计窗口

来源:互联网 发布:bershka 知乎 编辑:程序博客网 时间:2024/06/15 11:58

我们组的项目中,窗口设计中使用到了SDL库。通过调用SDL库提供的窗口函数+Opengl完成了窗口设计。

首先贴出我们组的窗口创建函数的主要代码。


bool Window::Initialize(std::string window_title,  int window_width,  int window_heihgt) {// 设置属性window_title_ = window_title;window_width_ = window_width;window_height_ = window_heihgt;// 初始化SDLif (SDL_Init(SDL_INIT_VIDEO) < 0) {std::cout << "SDL could not initialize: " << SDL_GetError() << std::endl;return false;}// 如果使用OpenGL为渲染APISDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);// 创建SDL窗口window_ = SDL_CreateWindow(window_title.c_str(),    SDL_WINDOWPOS_UNDEFINED,    SDL_WINDOWPOS_UNDEFINED,    window_width,    window_heihgt,    SDL_WINDOW_OPENGL);if (window_ == nullptr) {std::cout << "SDL window could not be created: " << SDL_GetError() << std::endl;return false;}                //检测OpenGL窗口是否成功创建SDL_GLContext context = SDL_GL_CreateContext(window_);if (context == NULL) {std::cout << "SDL OpenGL context could not be created: " << SDL_GetError() << std::endl;return false;}SDL_GL_SetSwapInterval(1);                             // 设置时间          current_time_ = 0;          last_time_ = 0;          // 设置初始鼠标位置          SDL_GetMouseState(&mouse_posX_, &mouse_posY_);          last_mouse_posX_ = mouse_posX_;          last_mouse_posY_ = mouse_posY_;                return true;    }


int SDL_GL_GetAttribute(SDL_GLattr attr,                        int*       value)
SDL_GL_SetAttribute函数是sdl库提供的专门用来在窗口创建前设置OpenGL属性的函数。

代码中前两行设定了OpenGL的版本为OpenGL3.3.第三行代码设置了OpenGL的版本号

其它常见的需要提前设定的OpenGL属性包括SDL_GL_DOUBLEBUFFER(多重缓存的个数)SDL_GL_DEPTH_SIZE(深度缓存的大小)


SDL_Window* SDL_CreateWindow(const char* title,                             int         x,                             int         y,                             int         w,                             int         h,                             Uint32      flags)

是SDL库提供的窗口创建函数。

第一个参数title是窗口的标题。

第二三个参数代表了窗口的初始xy坐标,也可设置为SDL_WINDOWPOS_CENTERED或SDL_WINDOWPOS_UNDEFINED。

第四五个参数代表窗口的宽度和高度

最后一个参数flag可传递以下参数,包括了窗口的是否最大化、最小化,能否调整边界等等属性。

 SDL_WINDOW_FULLSCREEN   SDL_WINDOW_OPENGL,
 SDL_WINDOW_HIDDEN,             SDL_WINDOW_BORDERLESS,
 SDL_WINDOW_RESIZABLE,       SDL_WINDOW_MAXIMIZED,
 SDL_WINDOW_MINIMIZED,         SDL_WINDOW_INPUT_GRABBED,
 SDL_WINDOW_ALLOW_HIGHDPI.


SDL_GLContext context = SDL_GL_CreateContext(window_);
该函数创建一个OpenGL的上下文环境以便在SDL窗口中调用OpenGL函数。

同样的,我们也需要检查创建是否正确。如果创建发生错误,需要调用SDL_GetError()函数来返回错误信息。


SDL_GL_SetSwapInterval(1);
设置每次交换缓存时跳过的缓存的个数,这里设置为1.
 SDL_GetMouseState(&mouse_posX_, &mouse_posY_);

获取鼠标当前位置的XY座标。


以下是窗口程序事件处理的代码。

bool Window::Update() {// 处理事件SDL_Event event;SDL_PollEvent(&event);if (event.type == SDL_QUIT)return false;// 更新时间last_time_ = current_time_;current_time_ = SDL_GetTicks();// 跟踪鼠标位置last_mouse_posX_ = mouse_posX_;last_mouse_posY_ = mouse_posY_;SDL_GetMouseState(&mouse_posX_, &mouse_posY_);return true;}
这是窗口事件的处理函数。SDL中定义有一个union变量event,其中的type字段决定了事件的类型。

每个SDL程序都是事件驱动的,每个SDL程序都有一个事件队列。如下图所示


事件队列的一个显著的特性是先进先出,先进入队列的事件会被优先处理。事件在队尾入队,队头出队,先发生的事件先入队,出队的时候也会先出队。

每当窗口出现新事件,通过SDL_PollEvent将该事件加入事件队列。然后程序判断事件类型,如果事件不为退出事件,则开始后续操作,通过SDL_GetMouseStateh获取当前鼠标位置的坐标值,并更新鼠标位置坐标(存储在last_mouse_posX_和last_mouse_posY_中)