diff options
Diffstat (limited to 'source/modules/asura-core/window')
-rw-r--r-- | source/modules/asura-core/window/binding/_window.cpp | 180 | ||||
-rw-r--r-- | source/modules/asura-core/window/window.cpp | 106 | ||||
-rw-r--r-- | source/modules/asura-core/window/window.h | 151 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_glew.cpp | 0 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_glew.h | 0 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_glut.cpp | 0 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_glut.h | 0 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_sdl.cpp | 154 | ||||
-rw-r--r-- | source/modules/asura-core/window/window_impl_sdl.h | 47 |
9 files changed, 638 insertions, 0 deletions
diff --git a/source/modules/asura-core/window/binding/_window.cpp b/source/modules/asura-core/window/binding/_window.cpp new file mode 100644 index 0000000..e477408 --- /dev/null +++ b/source/modules/asura-core/window/binding/_window.cpp @@ -0,0 +1,180 @@ +#include "../../image/image_data.h" + +#include "../window.h" + +using namespace std; +using namespace AEGraphics; + +namespace AsuraEngine +{ + namespace Window + { + + LUAX_REGISTRY(Window) + { + LUAX_REGISTER_METHODS(state, + { "Init", _Init }, + { "Exit", _Exit }, + { "Show", _Show }, + { "Hide", _Hide }, + { "SetSize", _SetSize }, + { "SetPosition", _SetPosition }, + { "SetTitle", _SetTitle }, + { "SetIcon", _SetIcon }, + { "SwapRenderBuffer", _SwapRenderBuffer }, + { "Clear", _Clear }, + { "Draw", _Draw } + ); + } + + LUAX_POSTPROCESS(Window) + { + LUAX_REGISTER_ENUM(state, "EWindowFlag", + { "FULLSCREEN", WINDOW_FULLSCREEN }, + { "OPENGL", WINDOW_OPENGL }, + { "SHOWN", WINDOW_SHOWN }, + { "HIDDEN", WINDOW_HIDDEN }, + { "BORDERLESS", WINDOW_BORDERLESS }, + { "RESIZABLE", WINDOW_RESIZABLE }, + { "MINIMIZED", WINDOW_MINIMIZED }, + { "MAXIMIZED", WINDOW_MAXIMIZED }, + { "INPUT_GRABBED", WINDOW_INPUT_GRABBED }, + { "INPUT_FOCUS", WINDOW_INPUT_FOCUS }, + { "MOUSE_FOCUS", WINDOW_MOUSE_FOCUS }, + { "ALLOW_HIGHDPI", WINDOW_ALLOW_HIGHDPI }, + { "MOUSE_CAPTURE", WINDOW_MOUSE_CAPTURE }, + { "ALWAYS_ON_TOP", WINDOW_ALWAYS_ON_TOP } + ); + + } + + // Window.Init(config_table) + LUAX_IMPL_METHOD(Window, _Init) + { + LUAX_PREPARE(L, Window); + + WindowConfig config; + + if (!state.IsType(1, LUA_TTABLE)) + return state.ErrorType(1, "window config table"); + + config.width = state.GetField(1, "width", 0); + config.height = state.GetField(1, "height", 0); + config.x = state.GetField(1, "x", 0); + config.y = state.GetField(1, "y", 0); + config.flag = state.GetField(1, "flag", WINDOW_OPENGL); + config.title = state.GetField(1, "title", ""); + config.vsync = state.GetField(1, "vsync", true); + config.show = state.GetField(1, "show", true); + + // try set window icon + state.GetField(1, "icon"); + if (state.IsType(1, LUA_TUSERDATA)) + { + ImageData* data = state.CheckUserdata<ImageData>(-1); + if (data) + { + data->Lock(); + config.icon = data; + Window::Get()->Init(config); + data->Unlock(); + return 0; + } + } + else + state.Pop(); + + Window::Get()->Init(config); + + return 0; + } + + // Window.Exit() + LUAX_IMPL_METHOD(Window, _Exit) + { + LUAX_PREPARE(L, Window); + Window::Get()->Exit(); + return 0; + } + + // Window.Show() + LUAX_IMPL_METHOD(Window, _Show) + { + LUAX_PREPARE(L, Window); + Window::Get()->Show(); + return 0; + } + + // Window.Hide() + LUAX_IMPL_METHOD(Window, _Hide) + { + LUAX_PREPARE(L, Window); + Window::Get()->Hide(); + return 0; + } + + // Window.SetSize(w, h) + LUAX_IMPL_METHOD(Window, _SetSize) + { + LUAX_PREPARE(L, Window); + uint w = state.CheckValue<uint>(1); + uint h = state.CheckValue<uint>(2); + Window::Get()->SetSize(w, h); + return 0; + } + + // Window.SetPosition(x, y) + LUAX_IMPL_METHOD(Window, _SetPosition) + { + LUAX_PREPARE(L, Window); + int x = state.CheckValue<int>(1); + int y = state.CheckValue<int>(2); + Window::Get()->SetPosition(x, y); + return 0; + } + + // Window.SetTitle(title) + LUAX_IMPL_METHOD(Window, _SetTitle) + { + LUAX_PREPARE(L, Window); + std::string title = state.CheckValue<string>(1); + Window::Get()->SetTitle(title); + return 0; + } + + // Window.SetIcon(imageData) + LUAX_IMPL_METHOD(Window, _SetIcon) + { + LUAX_PREPARE(L, Window); + ImageData* imgData = state.CheckUserdata<ImageData>(1); + imgData->Lock(); + Window::Get()->SetIcon(imgData); + imgData->Unlock(); + return 0; + } + + // Window.SwapRenderBuffer() + LUAX_IMPL_METHOD(Window, _SwapRenderBuffer) + { + LUAX_PREPARE(L, Window); + Window::Get()->SwapRenderBuffer(); + return 0; + } + + // Window.Clear() + LUAX_IMPL_METHOD(Window, _Clear) + { + LUAX_PREPARE(L, Window); + Window::Get()->Clear(); + return 0; + } + + // Window.Draw() + LUAX_IMPL_METHOD(Window, _Draw) + { + LUAX_PREPARE(L, Window); + return 0; + } + + } +}
\ No newline at end of file diff --git a/source/modules/asura-core/window/window.cpp b/source/modules/asura-core/window/window.cpp new file mode 100644 index 0000000..99433d5 --- /dev/null +++ b/source/modules/asura-core/window/window.cpp @@ -0,0 +1,106 @@ +#include <asura-utils/exceptions/exception.h> + +#include "window.h" + +#include "window_impl_sdl.h" +#include "window_impl_glew.h" +#include "window_impl_glut.h" + +namespace AsuraEngine +{ + namespace Window + { + + Window::Window() + : mImpl(nullptr) + { + } + + Window::~Window() + { + if (mImpl) + delete mImpl; + } + +#define try_init_window(impl) \ + if (!mImpl) \ + { \ + mImpl = new impl(); \ + if (!mImpl->Init(config)) \ + { \ + delete mImpl; \ + mImpl = nullptr; \ + } \ + } + + bool Window::Init(const WindowConfig& config) + { + ASSERT(!mImpl); +#if ASURA_WINDOW_SDL + try_init_window(WindowImplSDL); +#endif + return mImpl != nullptr; + } + + void Window::Exit() + { + if (mImpl) + delete mImpl; + } + + void Window::SetPosition(int x, int y) + { + ASSERT(mImpl); + mImpl->SetPosition(x, y); + } + + void Window::SetTitle(const std::string& title) + { + ASSERT(mImpl); + mImpl->SetTitils(title); + } + + void Window::Show() + { + ASSERT(mImpl); + mImpl->Show(); + } + + void Window::Hide() + { + ASSERT(mImpl); + mImpl->Hide(); + } + + void Window::SwapRenderBuffer() + { + ASSERT(mImpl); + mImpl->SwapRenderBuffer(); + } + + void Window::Clear(const AEGraphics::Color& col /*= AEGraphics::Color::Black*/) + { + ASSERT(mImpl); + glClearColor(col.r, col.g, col.b, col.a); + } + + void Window::Clear(const Math::Recti& quad, const AEGraphics::Color& col /*= AEGraphics::Color::Black*/) + { + ASSERT(mImpl); + + } + + void Window::Draw(const AEGraphics::Drawable* texture, const AEGraphics::RenderState& state) + { + ASSERT(mImpl); + + } + + void Window::Draw(const AEGraphics::Drawable* texture, const Math::Recti& quad, const AEGraphics::RenderState& state) + { + ASSERT(mImpl); + + } + + } +} diff --git a/source/modules/asura-core/window/window.h b/source/modules/asura-core/window/window.h new file mode 100644 index 0000000..8ce0e64 --- /dev/null +++ b/source/modules/asura-core/window/window.h @@ -0,0 +1,151 @@ +#ifndef __ASURA_ENGINE_WINDOW_H__ +#define __ASURA_ENGINE_WINDOW_H__ + +#include <asura-utils/scripting/portable.hpp> +#include <asura-utils/math/vector2.hpp> +#include <asura-utils/singleton.hpp> + +#include "../graphics/image.h" +#include "../graphics/render_state.h" +#include "../graphics/render_target.h" + +namespace AsuraEngine +{ + namespace Window + { + + class WindowImpl; + + /// + /// SDLģһЩõġ + /// + enum WindowFlag + { + WINDOW_FULLSCREEN = 1 << 1, ///< fullscreen window + WINDOW_OPENGL = 1 << 2, ///< window usable with OpenGL context + WINDOW_SHOWN = 1 << 3, ///< window is visible + WINDOW_HIDDEN = 1 << 4, ///< window is not visible + WINDOW_BORDERLESS = 1 << 5, ///< no window decoration + WINDOW_RESIZABLE = 1 << 6, ///< window can be resized + WINDOW_MINIMIZED = 1 << 7, ///< window is minimized + WINDOW_MAXIMIZED = 1 << 8, ///< window is maximized + WINDOW_INPUT_GRABBED = 1 << 9, ///< window has grabbed input focus + WINDOW_INPUT_FOCUS = 1 << 10, ///< window has input focus + WINDOW_MOUSE_FOCUS = 1 << 11, ///< window has mouse focus + WINDOW_ALLOW_HIGHDPI = 1 << 12, ///< window should be created in high-DPI mode if supported. + ///< On macOS NSHighResolutionCapable must be set true in the + ///< application's Info.plist for this to have any effect. + WINDOW_MOUSE_CAPTURE = 1 << 13, ///< window has mouse captured (unrelated to INPUT_GRABBED) + WINDOW_ALWAYS_ON_TOP = 1 << 14, ///< window should always be above others + }; + + /// + /// Windowʼ + /// + struct WindowConfig + { + uint width, height; ///< ߴ + int x, y; ///< ڳʼ + std::string title; ///< + bool vsync; ///< ֱͬ + AEGraphics::ImageData* icon; ///< ͼ + bool show; ///< Ƿʾ + int flag; ///< ڱ + }; + + /// + /// ϷĵڣrunnerֻҪһڡͬĿͻʵִ˽ӿڲֶעᵽlua༭ + /// ᵼ࣬ӵ༭ⴰϡ + /// + class Window ASURA_FINAL + : public AEGraphics::RenderTarget + , public AEScripting::Portable<Window> + , public Singleton<Window> + { + public: + + /// + /// ϷʱĴΨһģ༭õࡣ + /// + LUAX_DECL_SINGLETON(Window); + + Window(); + ~Window(); + + /// + /// ڡ + /// + bool Init(const WindowConfig& config); + void Exit(); + + void SetSize(uint width, uint height); + void SetPosition(int x, int y); + void SetTitle(const std::string& title); + void SetIcon(AEGraphics::ImageData* imgData); + + void Show(); + void Hide(); + + /// + /// ǿ˫ĴڣҪչʾǰ̨ + /// + void SwapRenderBuffer(); + + void Clear(const AEGraphics::Color& col = AEGraphics::Color::Black) override; + void Clear(const Math::Recti& quad, const AEGraphics::Color& col = AEGraphics::Color::Black) override; + + void Draw(const AEGraphics::Drawable* texture, const AEGraphics::RenderState& state) override; + void Draw(const AEGraphics::Drawable* texture, const Math::Recti& quad, const AEGraphics::RenderState& state) override; + + private: + + //----------------------------------------------------------------------------// + + LUAX_DECL_ENUM(WindowFlag, 0); + + LUAX_DECL_METHOD(_Init); + LUAX_DECL_METHOD(_Exit); + LUAX_DECL_METHOD(_Show); + LUAX_DECL_METHOD(_Hide); + LUAX_DECL_METHOD(_SetSize); + LUAX_DECL_METHOD(_SetPosition); + LUAX_DECL_METHOD(_SetTitle); + LUAX_DECL_METHOD(_SetIcon); + LUAX_DECL_METHOD(_SwapRenderBuffer); + LUAX_DECL_METHOD(_Clear); + LUAX_DECL_METHOD(_Draw); + + //----------------------------------------------------------------------------// + + WindowImpl* mImpl; + + }; + + using RenderWindow = Window; + + ASURA_ABSTRACT class WindowImpl + { + public: + + WindowImpl() {}; + virtual ~WindowImpl() {}; + + virtual bool Init(const WindowConfig& config); + + virtual void SetSize(uint width, uint height) = 0; + virtual void SetPosition(int x, int y) = 0; + virtual void SetTitils(const std::string& title) = 0; + + virtual void Show() = 0; + virtual void Hide() = 0; + + virtual void SwapRenderBuffer() = 0; + + }; + + } +} + +namespace AEWindow = AsuraEngine::Window; + +#endif
\ No newline at end of file diff --git a/source/modules/asura-core/window/window_impl_glew.cpp b/source/modules/asura-core/window/window_impl_glew.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/source/modules/asura-core/window/window_impl_glew.cpp diff --git a/source/modules/asura-core/window/window_impl_glew.h b/source/modules/asura-core/window/window_impl_glew.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/source/modules/asura-core/window/window_impl_glew.h diff --git a/source/modules/asura-core/window/window_impl_glut.cpp b/source/modules/asura-core/window/window_impl_glut.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/source/modules/asura-core/window/window_impl_glut.cpp diff --git a/source/modules/asura-core/window/window_impl_glut.h b/source/modules/asura-core/window/window_impl_glut.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/source/modules/asura-core/window/window_impl_glut.h diff --git a/source/modules/asura-core/window/window_impl_sdl.cpp b/source/modules/asura-core/window/window_impl_sdl.cpp new file mode 100644 index 0000000..9554e37 --- /dev/null +++ b/source/modules/asura-core/window/window_impl_sdl.cpp @@ -0,0 +1,154 @@ +#include "../core_config.h" + +#if ASURA_WINDOW_SDL + +#include <SDL2/SDL.h> + +#include <asura-utils/exceptions/exception.h> + +#include "window_impl_sdl.h" + +using namespace AEGraphics; + +namespace AsuraEngine +{ + namespace Window + { + +#define asura_flag_to_sdl_flag(flag, _flag, _sdl_flag) \ + if ((flag & _flag) != 0) \ + flag |= _sdl_flag + + WindowImplSDL::WindowImplSDL() + : mWnd(nullptr) + , mGLContext(0) + { + } + + WindowImplSDL::~WindowImplSDL() + { + SDL_GL_DeleteContext(mGLContext); + SDL_DestroyWindow(mWnd); + SDL_FlushEvent(SDL_WINDOWEVENT); + } + + bool WindowImplSDL::Init(const WindowConfig& config) + { + if (SDL_Init(SDL_INIT_VIDEO) < 0) + return false; + + int flag = 0; + asura_flag_to_sdl_flag(flag, WINDOW_FULLSCREEN, SDL_WINDOW_FULLSCREEN); + asura_flag_to_sdl_flag(flag, WINDOW_OPENGL, SDL_WINDOW_OPENGL); + asura_flag_to_sdl_flag(flag, WINDOW_SHOWN, SDL_WINDOW_SHOWN); + asura_flag_to_sdl_flag(flag, WINDOW_HIDDEN, SDL_WINDOW_HIDDEN); + asura_flag_to_sdl_flag(flag, WINDOW_BORDERLESS, SDL_WINDOW_BORDERLESS); + asura_flag_to_sdl_flag(flag, WINDOW_RESIZABLE, SDL_WINDOW_RESIZABLE); + asura_flag_to_sdl_flag(flag, WINDOW_MINIMIZED, SDL_WINDOW_MINIMIZED); + asura_flag_to_sdl_flag(flag, WINDOW_MAXIMIZED, SDL_WINDOW_MAXIMIZED); + asura_flag_to_sdl_flag(flag, WINDOW_INPUT_GRABBED, SDL_WINDOW_INPUT_GRABBED); + asura_flag_to_sdl_flag(flag, WINDOW_INPUT_FOCUS, SDL_WINDOW_INPUT_FOCUS); + asura_flag_to_sdl_flag(flag, WINDOW_MOUSE_FOCUS, SDL_WINDOW_MOUSE_FOCUS); + asura_flag_to_sdl_flag(flag, WINDOW_ALLOW_HIGHDPI, SDL_WINDOW_ALLOW_HIGHDPI); + asura_flag_to_sdl_flag(flag, WINDOW_MOUSE_CAPTURE, SDL_WINDOW_MOUSE_CAPTURE); + asura_flag_to_sdl_flag(flag, WINDOW_ALWAYS_ON_TOP, SDL_WINDOW_ALWAYS_ON_TOP); + + // Set GL window / framebuffer attributes. + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); + + mWnd = SDL_CreateWindow(config.title.c_str(), config.x, config.y, config.width, config.height, flag); + + if (!mWnd) + return false; + + // ͼ + try + { + if (config.icon) + { + ImageData* img = config.icon; + if (img->format == COLOR_FORMAT_RGBA8) + { + SDL_Surface *surface; + + img->Lock(); + + int w = img->width, h = img->height; + surface = SDL_CreateRGBSurfaceFrom( + img->pixels, + w, h, + 32, + w * 4, + Color32::RMASK, + Color32::GMASK, + Color32::BMASK, + Color32::AMASK + ); + + img->Unlock(); + + SDL_SetWindowIcon(mWnd, surface); + SDL_FreeSurface(surface); + } + } + } + catch (...) + { + } + + mGLContext = SDL_GL_CreateContext(mWnd); + + if (!mGLContext) + { + SDL_DestroyWindow(mWnd); + return false; + } + + SDL_GL_MakeCurrent(mWnd, mGLContext); + SDL_GL_SetSwapInterval(config.vsync ? 1 : 0); + + return true; + } + + void WindowImplSDL::SetSize(uint width, uint height) + { + SDL_SetWindowSize(mWnd, width, height); + } + + void WindowImplSDL::SetPosition(int x, int y) + { + SDL_SetWindowPosition(mWnd, x, y); + } + + void WindowImplSDL::SetTitils(const std::string& title) + { + SDL_SetWindowTitle(mWnd, title.c_str()); + } + + void WindowImplSDL::Show() + { + SDL_ShowWindow(mWnd); + } + + void WindowImplSDL::Hide() + { + SDL_HideWindow(mWnd); + } + + void WindowImplSDL::SwapRenderBuffer() + { + SDL_GL_SwapWindow(mWnd); + } + + } +} + +#endif // ASURA_WINDOW_SDL
\ No newline at end of file diff --git a/source/modules/asura-core/window/window_impl_sdl.h b/source/modules/asura-core/window/window_impl_sdl.h new file mode 100644 index 0000000..de4cafb --- /dev/null +++ b/source/modules/asura-core/window/window_impl_sdl.h @@ -0,0 +1,47 @@ +#ifndef __ASURA_WINDOW_SDL_H_ +#define __ASURA_WINDOW_SDL_H_ + +#include "../core_config.h" + +#if ASURA_WINDOW_SDL + +#include <SDL2/SDL.h> + +#include "window.h" + +namespace AsuraEngine +{ + namespace Window + { + + class WindowImplSDL ASURA_FINAL : public WindowImpl + { + public: + + WindowImplSDL(); + ~WindowImplSDL(); + + bool Init(const WindowConfig& config); + + void SetSize(uint width, uint height) override; + void SetPosition(int x, int y) override; + void SetTitils(const std::string& title) override; + + void Show() override; + void Hide() override; + + void SwapRenderBuffer() override; + + private: + + SDL_Window* mWnd; + SDL_GLContext mGLContext; + + }; + + } +} + +#endif // ASURA_WINDOW_SDL + +#endif
\ No newline at end of file |