summaryrefslogtreecommitdiff
path: root/source/modules/asura-core/Window
diff options
context:
space:
mode:
Diffstat (limited to 'source/modules/asura-core/Window')
-rw-r--r--source/modules/asura-core/Window/Window.cpp104
-rw-r--r--source/modules/asura-core/Window/Window.h138
-rw-r--r--source/modules/asura-core/Window/WindowImplGlew.cpp0
-rw-r--r--source/modules/asura-core/Window/WindowImplGlew.h0
-rw-r--r--source/modules/asura-core/Window/WindowImplGlut.h0
-rw-r--r--source/modules/asura-core/Window/WindowImplSDL.cpp153
-rw-r--r--source/modules/asura-core/Window/WindowImplSDL.h45
-rw-r--r--source/modules/asura-core/Window/WinodwImplGlut.cpp0
-rw-r--r--source/modules/asura-core/Window/binding/_window.cpp179
9 files changed, 619 insertions, 0 deletions
diff --git a/source/modules/asura-core/Window/Window.cpp b/source/modules/asura-core/Window/Window.cpp
new file mode 100644
index 0000000..adba7c9
--- /dev/null
+++ b/source/modules/asura-core/Window/Window.cpp
@@ -0,0 +1,104 @@
+#include <asura-utils/Exceptions/Exception.h>
+
+#include "window.h"
+
+#include "WindowImplSDL.h"
+#include "WindowImplGlew.h"
+#include "WindowImplGlut.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Window)
+
+ Window::Window()
+ : m_Impl(nullptr)
+ {
+ }
+
+ Window::~Window()
+ {
+ if (m_Impl)
+ delete m_Impl;
+ }
+
+#define try_init_window(impl) \
+ if (!m_Impl) \
+ { \
+ m_Impl = new impl(); \
+ if (!m_Impl->Init(config)) \
+ { \
+ delete m_Impl; \
+ m_Impl = nullptr; \
+ } \
+ }
+
+ bool Window::Init(const WindowConfig& config)
+ {
+ ASSERT(!m_Impl);
+#if ASURA_WINDOW_SDL
+ try_init_window(WindowImplSDL);
+#endif
+ return m_Impl != nullptr;
+ }
+
+ void Window::Exit()
+ {
+ if (m_Impl)
+ delete m_Impl;
+ }
+
+ void Window::SetPosition(int x, int y)
+ {
+ ASSERT(m_Impl);
+ m_Impl->SetPosition(x, y);
+ }
+
+ void Window::SetTitle(const std::string& title)
+ {
+ ASSERT(m_Impl);
+ m_Impl->SetTitils(title);
+ }
+
+ void Window::Show()
+ {
+ ASSERT(m_Impl);
+ m_Impl->Show();
+ }
+
+ void Window::Hide()
+ {
+ ASSERT(m_Impl);
+ m_Impl->Hide();
+ }
+
+ void Window::SwapRenderBuffer()
+ {
+ ASSERT(m_Impl);
+ m_Impl->SwapRenderBuffer();
+ }
+
+ void Window::Clear(const AEGraphics::Color& col /*= AEGraphics::Color::Black*/)
+ {
+ ASSERT(m_Impl);
+ glClearColor(col.r, col.g, col.b, col.a);
+ }
+
+ //void Window::Clear(const Math::Recti& quad, const AEGraphics::Color& col /*= AEGraphics::Color::Black*/)
+ //{
+ // ASSERT(m_Impl);
+
+ //}
+
+ void Window::Draw(const AEGraphics::Drawable* texture, const AEGraphics::RenderState& state)
+ {
+ ASSERT(m_Impl);
+
+ }
+/*
+ void Window::Draw(const AEGraphics::Drawable* texture, const Math::Recti& quad, const AEGraphics::RenderState& state)
+ {
+ ASSERT(m_Impl);
+
+ }
+*/
+ }
+}
diff --git a/source/modules/asura-core/Window/Window.h b/source/modules/asura-core/Window/Window.h
new file mode 100644
index 0000000..f5498c1
--- /dev/null
+++ b/source/modules/asura-core/Window/Window.h
@@ -0,0 +1,138 @@
+#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/RenderState.h"
+#include "../Graphics/RenderTarget.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(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; ///< ֱͬ
+ AEImage::ImageData* icon; ///< ͼ
+ bool show; ///< Ƿʾ
+ int flag; ///< ڱ
+};
+
+///
+/// ϷĵڣrunnerֻҪһڡͬĿͻʵִ˽ӿڲֶעᵽlua༭
+/// ᵼ࣬޽ӵ༭ⴰϡ
+///
+class Window ASURA_FINAL
+ : public AEScripting::Portable<Window, AEGraphics::RenderTarget>
+ , 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(AEImage::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:
+
+ WindowImpl* m_Impl;
+
+luaxport:
+
+ 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);
+
+};
+
+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_end
+namespace_end
+
+namespace AEWindow = AsuraEngine::Window;
+
+#endif \ No newline at end of file
diff --git a/source/modules/asura-core/Window/WindowImplGlew.cpp b/source/modules/asura-core/Window/WindowImplGlew.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/modules/asura-core/Window/WindowImplGlew.cpp
diff --git a/source/modules/asura-core/Window/WindowImplGlew.h b/source/modules/asura-core/Window/WindowImplGlew.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/modules/asura-core/Window/WindowImplGlew.h
diff --git a/source/modules/asura-core/Window/WindowImplGlut.h b/source/modules/asura-core/Window/WindowImplGlut.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/modules/asura-core/Window/WindowImplGlut.h
diff --git a/source/modules/asura-core/Window/WindowImplSDL.cpp b/source/modules/asura-core/Window/WindowImplSDL.cpp
new file mode 100644
index 0000000..3cbad70
--- /dev/null
+++ b/source/modules/asura-core/Window/WindowImplSDL.cpp
@@ -0,0 +1,153 @@
+#include "../CoreConfig.h"
+
+#if ASURA_WINDOW_SDL
+
+#include <SDL2/SDL.h>
+
+#include <asura-utils/Exceptions/Exception.h>
+
+#include "WindowImplSDL.h"
+
+using namespace AEGraphics;
+using namespace AEImage;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Window)
+
+#define asura_flag_to_sdl_flag(flag, _flag, _sdl_flag) \
+if ((flag & _flag) != 0) \
+ flag |= _sdl_flag
+
+WindowImplSDL::WindowImplSDL()
+ : m_Wnd(nullptr)
+ , m_GLContext(0)
+{
+}
+
+WindowImplSDL::~WindowImplSDL()
+{
+ SDL_GL_DeleteContext(m_GLContext);
+ SDL_DestroyWindow(m_Wnd);
+ 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);
+
+ m_Wnd = SDL_CreateWindow(config.title.c_str(), config.x, config.y, config.width, config.height, flag);
+
+ if (!m_Wnd)
+ 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(m_Wnd, surface);
+ SDL_FreeSurface(surface);
+ }
+ }
+ }
+ catch (...)
+ {
+ }
+
+ m_GLContext = SDL_GL_CreateContext(m_Wnd);
+
+ if (!m_GLContext)
+ {
+ SDL_DestroyWindow(m_Wnd);
+ return false;
+ }
+
+ SDL_GL_MakeCurrent(m_Wnd, m_GLContext);
+ SDL_GL_SetSwapInterval(config.vsync ? 1 : 0);
+
+ return true;
+}
+
+void WindowImplSDL::SetSize(uint width, uint height)
+{
+ SDL_SetWindowSize(m_Wnd, width, height);
+}
+
+void WindowImplSDL::SetPosition(int x, int y)
+{
+ SDL_SetWindowPosition(m_Wnd, x, y);
+}
+
+void WindowImplSDL::SetTitils(const std::string& title)
+{
+ SDL_SetWindowTitle(m_Wnd, title.c_str());
+}
+
+void WindowImplSDL::Show()
+{
+ SDL_ShowWindow(m_Wnd);
+}
+
+void WindowImplSDL::Hide()
+{
+ SDL_HideWindow(m_Wnd);
+}
+
+void WindowImplSDL::SwapRenderBuffer()
+{
+ SDL_GL_SwapWindow(m_Wnd);
+}
+
+namespace_end
+namespace_end
+
+#endif // ASURA_WINDOW_SDL \ No newline at end of file
diff --git a/source/modules/asura-core/Window/WindowImplSDL.h b/source/modules/asura-core/Window/WindowImplSDL.h
new file mode 100644
index 0000000..5971351
--- /dev/null
+++ b/source/modules/asura-core/Window/WindowImplSDL.h
@@ -0,0 +1,45 @@
+#ifndef _ASURA_WINDOW_SDL_H_
+#define _ASURA_WINDOW_SDL_H_
+
+#include "../CoreConfig.h"
+
+#if ASURA_WINDOW_SDL
+
+#include <SDL2/SDL.h>
+
+#include "Window.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(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* m_Wnd;
+ SDL_GLContext m_GLContext;
+
+};
+
+namespace_end
+namespace_end
+
+#endif // ASURA_WINDOW_SDL
+
+#endif \ No newline at end of file
diff --git a/source/modules/asura-core/Window/WinodwImplGlut.cpp b/source/modules/asura-core/Window/WinodwImplGlut.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/source/modules/asura-core/Window/WinodwImplGlut.cpp
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..1e14a3a
--- /dev/null
+++ b/source/modules/asura-core/Window/binding/_window.cpp
@@ -0,0 +1,179 @@
+#include "../../Image/ImageData.h"
+
+#include "../Window.h"
+
+using namespace std;
+using namespace AEGraphics;
+using namespace AEImage;
+
+namespace_begin(AsuraEngine)
+namespace_begin(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