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/binding/_window.cpp180
-rw-r--r--source/modules/asura-core/window/window.cpp106
-rw-r--r--source/modules/asura-core/window/window.h151
-rw-r--r--source/modules/asura-core/window/window_impl_glew.cpp0
-rw-r--r--source/modules/asura-core/window/window_impl_glew.h0
-rw-r--r--source/modules/asura-core/window/window_impl_glut.cpp0
-rw-r--r--source/modules/asura-core/window/window_impl_glut.h0
-rw-r--r--source/modules/asura-core/window/window_impl_sdl.cpp154
-rw-r--r--source/modules/asura-core/window/window_impl_sdl.h47
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