使用SDL2创建一个灵活的窗口类
这一篇主要讲讲实现一个灵活的窗口程序。现在桌面游戏由2D视角和3D视角两大块,通常2D游戏使用COCOS引擎来开发,而3D游戏则是使用DX或OpenGL这些图形库开发,但是无论什么游戏,都需要运行在一个窗口上,很不错的是,SDL同时提供了2D和3D的支持。
我们创建一个2D游戏需要一个2D的渲染器,而3D游戏使用的是3D渲染器。在SDL中,2D渲染器由SDL_Renderer实现,而3D渲染器则添加OPENGL支持。为了实现灵活的窗口,我们需要实现一个渲染器类,然后在窗口类中包含渲染器的实例或指针。
渲染器设计如下:
//WApplication.h
struct RendererMode {
//union变量用于保存2D或3D渲染器实例,每次创建的Application实例都只能包含其中一个
union Renderer
{
SDL_Renderer* mSDLRenderer;
NOTYPE* mOpenGLContext; //用于保存OpenGL上下文指针,为后面添加OpenGL绘图提供支持
//NOTYPE 为 void类型
}mRenderer;
bool TriDisplay; //3D模式,默认开启OpenGL,否则使用SDLrender
bool VSync; //垂直同步
bool FullScreen;
bool Accelerate; //硬件加速
bool Resizeable;
RendererMode()
{
mRenderer.mOpenGLContext = nullptr;
VSync = false;
FullScreen = false;
Resizeable = false;
Accelerate = true;
TriDisplay = true;
}
RendererMode(bool threed, bool vsync, bool full, bool acc, bool resize) {
mRenderer.mOpenGLContext = nullptr;
VSync = vsync;
FullScreen = full;
Resizeable = resize;
Accelerate = acc;
TriDisplay = threed;
}
};
我上面描述了一个渲染模式结构体,用于保存当前窗口程序的渲染模式,同时为渲染模式添加了一些属性。因为现在3D游戏居多,因此我们默认开启OpenGL支持,但后面我一般会以SDL_Renderer支持来实现游戏引擎的设计。
在实现了渲染模式以后,我们需要设计一个窗口类来创建窗口,并添加渲染环境。为了不添加过多头文件引起命名重复的风险,我们使用SDL中的结构体或变量时,都用前置声明来添加我们需要的SDL变量:
//WApplication.h
//这里的声明需要和SDL中的声明一致,不然会引起不同基类错误
struct SDL_Window;
union SDL_Event;
struct SDL_Renderer;
完成前置声明以后,我们开始设计窗口类,除开一般的Getter和Setter函数,我们还需要一个创建窗口函数,销毁窗口函数。值得注意的是,窗口类本身只是保存窗口属性,为了方便管理,我们最好是手动创建和销毁窗口。
//WApplication.h
using NOTYPE=void;
using INT32=int;
class WApplication {
public:
WApplication(String t, INT32 w, INT32 h, INT32 x, INT32 y, RendererMode* mode);
WApplication() = delete;
WApplication(const WApplication&) = delete;
~WApplication();
const String& GetTitle();
const INT32& GetWidth();
const INT32& GetHeight();
const INT32& GetPosX();
const INT32& GetPosY();
const INT32 GetMousePosX();
const INT32 GetMousePosY();
const INT32 GetMouseOffsetX();
const INT32 GetMouseOffsetY();
const bool GetMouseButtonLeft();
const bool GetMouseButtonMiddle();
const bool GetMouseButtonRight();
const INT32 GetKeyState(INT32 key);
//获取当前程序渲染托管模式
//返回模式:SDL渲染模式,OPENGL渲染模式之一
const INT32 GetRenderMode();
//返回当前渲染器
const RendererMode::Renderer* GetRenderer();
bool CreateApplication();
bool IsAppActive();
NOTYPE SetSize(INT32 w, INT32 h);
NOTYPE SetPosition(INT32 x, INT32 y);
NOTYPE SetTitle(String t);
NOTYPE OpenVSync(bool vsync);
NOTYPE OpenFullScreen(bool full)<