summaryrefslogtreecommitdiff
path: root/Source/modules/asura-core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/modules/asura-core')
-rw-r--r--Source/modules/asura-core/Application.cpp23
-rw-r--r--Source/modules/asura-core/Application.h69
-rw-r--r--Source/modules/asura-core/CoreConfig.h13
-rw-r--r--Source/modules/asura-core/CoreModule.cpp25
-rw-r--r--Source/modules/asura-core/CoreModule.h26
-rw-r--r--Source/modules/asura-core/Font/Glyph.cpp0
-rw-r--r--Source/modules/asura-core/Font/Glyph.h0
-rw-r--r--Source/modules/asura-core/Font/String.cpp376
-rw-r--r--Source/modules/asura-core/Font/String.hpp595
-rw-r--r--Source/modules/asura-core/Font/String.inc29
-rw-r--r--Source/modules/asura-core/Font/TTF.cpp0
-rw-r--r--Source/modules/asura-core/Font/TTF.h17
-rw-r--r--Source/modules/asura-core/Font/Utf.hpp720
-rw-r--r--Source/modules/asura-core/Font/Utf.inc752
-rw-r--r--Source/modules/asura-core/Graphics/BlendMode.h17
-rw-r--r--Source/modules/asura-core/Graphics/Canvas.cpp49
-rw-r--r--Source/modules/asura-core/Graphics/Canvas.h73
-rw-r--r--Source/modules/asura-core/Graphics/Color.cpp58
-rw-r--r--Source/modules/asura-core/Graphics/Color.h75
-rw-r--r--Source/modules/asura-core/Graphics/Color32.cpp53
-rw-r--r--Source/modules/asura-core/Graphics/Color32.h58
-rw-r--r--Source/modules/asura-core/Graphics/ColorPalette.h0
-rw-r--r--Source/modules/asura-core/Graphics/DrawInfo.cpp10
-rw-r--r--Source/modules/asura-core/Graphics/DrawInfo.h19
-rw-r--r--Source/modules/asura-core/Graphics/DrawUtil.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/DrawUtil.h0
-rw-r--r--Source/modules/asura-core/Graphics/GPUBuffer.cpp151
-rw-r--r--Source/modules/asura-core/Graphics/GPUBuffer.h93
-rw-r--r--Source/modules/asura-core/Graphics/GfxDevice.cpp188
-rw-r--r--Source/modules/asura-core/Graphics/GfxDevice.h141
-rw-r--r--Source/modules/asura-core/Graphics/GraphicsHelper.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/GraphicsHelper.h15
-rw-r--r--Source/modules/asura-core/Graphics/Image.cpp103
-rw-r--r--Source/modules/asura-core/Graphics/Image.h63
-rw-r--r--Source/modules/asura-core/Graphics/IndexBuffer.cpp17
-rw-r--r--Source/modules/asura-core/Graphics/IndexBuffer.h34
-rw-r--r--Source/modules/asura-core/Graphics/MatrixStack.cpp75
-rw-r--r--Source/modules/asura-core/Graphics/MatrixStack.h58
-rw-r--r--Source/modules/asura-core/Graphics/Mesh2D.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/Mesh2D.h52
-rw-r--r--Source/modules/asura-core/Graphics/Polygon2D.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/Polygon2D.h0
-rw-r--r--Source/modules/asura-core/Graphics/Quad.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/Quad.h1
-rw-r--r--Source/modules/asura-core/Graphics/RenderState.h47
-rw-r--r--Source/modules/asura-core/Graphics/RenderTarget.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/RenderTarget.h52
-rw-r--r--Source/modules/asura-core/Graphics/Shader.cpp282
-rw-r--r--Source/modules/asura-core/Graphics/Shader.h117
-rw-r--r--Source/modules/asura-core/Graphics/Shape.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/Shape.h0
-rw-r--r--Source/modules/asura-core/Graphics/SpriteBatch.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/SpriteBatch.h34
-rw-r--r--Source/modules/asura-core/Graphics/Texture.cpp47
-rw-r--r--Source/modules/asura-core/Graphics/Texture.h101
-rw-r--r--Source/modules/asura-core/Graphics/VBO.cpp0
-rw-r--r--Source/modules/asura-core/Graphics/VBO.h27
-rw-r--r--Source/modules/asura-core/Graphics/VertexBuffer.cpp16
-rw-r--r--Source/modules/asura-core/Graphics/VertexBuffer.h34
-rw-r--r--Source/modules/asura-core/Graphics/binding/_canvas.cpp48
-rw-r--r--Source/modules/asura-core/Graphics/binding/_color.cpp130
-rw-r--r--Source/modules/asura-core/Graphics/binding/_color32.cpp66
-rw-r--r--Source/modules/asura-core/Graphics/binding/_gfx_device.cpp151
-rw-r--r--Source/modules/asura-core/Graphics/binding/_gpu_buffer.cpp118
-rw-r--r--Source/modules/asura-core/Graphics/binding/_image.cpp71
-rw-r--r--Source/modules/asura-core/Graphics/binding/_index_buffer.cpp31
-rw-r--r--Source/modules/asura-core/Graphics/binding/_mesh2d.cpp20
-rw-r--r--Source/modules/asura-core/Graphics/binding/_shader.cpp131
-rw-r--r--Source/modules/asura-core/Graphics/binding/_sprite_batch.cpp20
-rw-r--r--Source/modules/asura-core/Graphics/binding/_texture.cpp85
-rw-r--r--Source/modules/asura-core/Graphics/binding/_vertex_buffer.cpp38
-rw-r--r--Source/modules/asura-core/Image/ImageData.cpp62
-rw-r--r--Source/modules/asura-core/Image/ImageData.h81
-rw-r--r--Source/modules/asura-core/Image/ImageDecodeTask.cpp17
-rw-r--r--Source/modules/asura-core/Image/ImageDecodeTask.h35
-rw-r--r--Source/modules/asura-core/Image/ImageDecoder.h33
-rw-r--r--Source/modules/asura-core/Image/PngDecoder.cpp17
-rw-r--r--Source/modules/asura-core/Image/PngDecoder.h25
-rw-r--r--Source/modules/asura-core/Image/StbDecoder.cpp73
-rw-r--r--Source/modules/asura-core/Image/StbDecoder.h26
-rw-r--r--Source/modules/asura-core/Image/binding/_image_data.cpp108
-rw-r--r--Source/modules/asura-core/Image/binding/_image_decode_task.cpp19
-rw-r--r--Source/modules/asura-core/Input/Button.h31
-rw-r--r--Source/modules/asura-core/Input/ClipBoard.cpp0
-rw-r--r--Source/modules/asura-core/Input/ClipBoard.h0
-rw-r--r--Source/modules/asura-core/Input/InputAxis.cpp0
-rw-r--r--Source/modules/asura-core/Input/InputAxis.h15
-rw-r--r--Source/modules/asura-core/Input/InputDevice.cpp10
-rw-r--r--Source/modules/asura-core/Input/InputDevice.h82
-rw-r--r--Source/modules/asura-core/Input/InputEvent.cpp0
-rw-r--r--Source/modules/asura-core/Input/InputEvent.h55
-rw-r--r--Source/modules/asura-core/Input/InputManager.cpp140
-rw-r--r--Source/modules/asura-core/Input/InputManager.h352
-rw-r--r--Source/modules/asura-core/Input/JoystickState.h16
-rw-r--r--Source/modules/asura-core/Input/KeyboardState.h37
-rw-r--r--Source/modules/asura-core/Input/MouseState.h16
-rw-r--r--Source/modules/asura-core/Mesh/Am2Handler.cpp34
-rw-r--r--Source/modules/asura-core/Mesh/Am2Handler.h30
-rw-r--r--Source/modules/asura-core/Mesh/Mesh2DData.cpp0
-rw-r--r--Source/modules/asura-core/Mesh/Mesh2DData.h78
-rw-r--r--Source/modules/asura-core/Mesh/Mesh2DHandler.cpp0
-rw-r--r--Source/modules/asura-core/Mesh/Mesh2DHandler.h32
-rw-r--r--Source/modules/asura-core/Mesh/ObjHandler.cpp0
-rw-r--r--Source/modules/asura-core/Mesh/ObjHandler.h0
-rw-r--r--Source/modules/asura-core/Profiler/GPUProfiler.cpp0
-rw-r--r--Source/modules/asura-core/Profiler/GPUProfiler.h0
-rw-r--r--Source/modules/asura-core/Profiler/Stats.cpp0
-rw-r--r--Source/modules/asura-core/Profiler/Stats.h0
-rw-r--r--Source/modules/asura-core/Threads/Channel.cpp0
-rw-r--r--Source/modules/asura-core/Threads/Channel.h18
-rw-r--r--Source/modules/asura-core/Threads/ThreadEx.cpp20
-rw-r--r--Source/modules/asura-core/Threads/ThreadEx.h45
-rw-r--r--Source/modules/asura-core/Time/Timer.cpp0
-rw-r--r--Source/modules/asura-core/Time/Timer.h0
-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
123 files changed, 7840 insertions, 0 deletions
diff --git a/Source/modules/asura-core/Application.cpp b/Source/modules/asura-core/Application.cpp
new file mode 100644
index 0000000..2f20e45
--- /dev/null
+++ b/Source/modules/asura-core/Application.cpp
@@ -0,0 +1,23 @@
+#include "Application.h"
+
+using namespace Luax;
+
+namespace AsuraEngine
+{
+
+Application::Application()
+{
+
+}
+
+Application::~Application()
+{
+
+}
+
+bool Application::InitSubModules(uint flag)
+{
+ return false;
+}
+
+} \ No newline at end of file
diff --git a/Source/modules/asura-core/Application.h b/Source/modules/asura-core/Application.h
new file mode 100644
index 0000000..cccd6f7
--- /dev/null
+++ b/Source/modules/asura-core/Application.h
@@ -0,0 +1,69 @@
+#ifndef _ASURA_ENGINE_APPLICATION_H_
+#define _ASURA_ENGINE_APPLICATION_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Module.h>
+#include <asura-base/Classes.h>
+#include <queue>
+
+#include "CoreConfig.h"
+
+namespace_begin(AsuraEngine)
+
+/// ģ
+enum SubModules
+{
+ ASURA_MODULE_NONE = 0X00000000U,
+
+ ASURA_MODULE_GRAPHICS = 1 << 1,
+ ASURA_MODULE_AUDIO = 1 << 2,
+ ASURA_MODULE_FONT = 1 << 3,
+ ASURA_MODULE_INPUT = 1 << 4,
+ ASURA_MODULE_MATH = 1 << 5,
+ ASURA_MODULE_PHYSICS = 1 << 6,
+ ASURA_MODULE_TIME = 1 << 7,
+ ASURA_MODULE_WINDOW = 1 << 8,
+
+ ASURA_MODULE_ALL = 0XFFFFFFFFU
+};
+
+///
+/// ѭ
+///
+class Application
+{
+public:
+
+ Application();
+
+ virtual ~Application();
+
+ // ʼǰϵͳ
+ bool InitSubModules(uint flag = ASURA_MODULE_ALL);
+
+ //
+ virtual void Run(int argc, char* args[]);
+
+ // ˳runʱĴ
+ virtual void OnExit();
+
+protected:
+
+ // moduleapplicationӵmoduleȨ
+ void EnqueueModule(Module* module);
+
+private:
+
+ /// ̵߳lua state handleӦѭСһ˵ֻҪ߳һlua_State̲߳Ҫ̼߳
+ /// lua̫ʹˡC++дȻעһصһ̴߳lua_Stateעắִк󷢻
+ /// ̵߳lua_Stateֻ֤һnativeʵ֮һlua_State󶨡
+ Luax::LuaxVM* m_VM;
+
+ // Asura libsᰴն˳ʼ˳ʱִ˳
+ std::queue<Module*> m_Modules;
+
+};
+
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/CoreConfig.h b/Source/modules/asura-core/CoreConfig.h
new file mode 100644
index 0000000..2dd0b03
--- /dev/null
+++ b/Source/modules/asura-core/CoreConfig.h
@@ -0,0 +1,13 @@
+#ifndef _ASURA_CORE_CONFIG_H_
+#define _ASURA_CORE_CONFIG_H_
+
+#define ASURA_WINDOW_SDL 1
+
+#define ASURA_OPENGL_GLAD (1 << 1)
+#define ASURA_OPENGL_GLEE (1 << 2)
+#define ASURA_OPENGL_GLUT (1 << 3)
+#define ASURA_OPENGL_LOADER (ASURA_OPENGL_GLAD|ASURA_OPENGL_GLEE|ASURA_OPENGL_GLUT)
+
+#define ASURA_GL_PROFILE 1
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/CoreModule.cpp b/Source/modules/asura-core/CoreModule.cpp
new file mode 100644
index 0000000..93f8ca0
--- /dev/null
+++ b/Source/modules/asura-core/CoreModule.cpp
@@ -0,0 +1,25 @@
+#include "CoreModule.h"
+
+using namespace AEThreading;
+using namespace AEGraphics;
+
+namespace AsuraEngine
+{
+
+ void CoreModule::Initialize(Luax::LuaxState& state)
+ {
+ // Graphics
+ LUAX_REGISTER_ABSTRACT_FACTORY(state, Texture);
+ LUAX_REGISTER_FACTORY(state, AEGraphics::Image);
+ // Wnd
+ LUAX_REGISTER_SINGLETON(state, AEWindow::Window);
+ // Threads
+ //LUAX_REGISTER_FACTORY(state, ThreadEx);
+ }
+
+ void CoreModule::Finalize(Luax::LuaxState& state)
+ {
+
+ }
+
+} \ No newline at end of file
diff --git a/Source/modules/asura-core/CoreModule.h b/Source/modules/asura-core/CoreModule.h
new file mode 100644
index 0000000..d592f42
--- /dev/null
+++ b/Source/modules/asura-core/CoreModule.h
@@ -0,0 +1,26 @@
+#ifndef _ASURA_CORE_MODULE_H_
+#define _ASURA_CORE_MODULE_H_
+
+#include <asura-base/Module.h>
+#include <asura-base/Classes.h>
+
+#include "graphics/image.h"
+#include "graphics/texture.h"
+#include "window/window.h"
+#include "Threads/ThreadEx.h"
+
+namespace_begin(AsuraEngine)
+
+class CoreModule : public Module
+{
+public:
+
+ void Initialize(Luax::LuaxState& state) override;
+
+ void Finalize(Luax::LuaxState& state) override;
+
+};
+
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Font/Glyph.cpp b/Source/modules/asura-core/Font/Glyph.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Font/Glyph.cpp
diff --git a/Source/modules/asura-core/Font/Glyph.h b/Source/modules/asura-core/Font/Glyph.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Font/Glyph.h
diff --git a/Source/modules/asura-core/Font/String.cpp b/Source/modules/asura-core/Font/String.cpp
new file mode 100644
index 0000000..1731338
--- /dev/null
+++ b/Source/modules/asura-core/Font/String.cpp
@@ -0,0 +1,376 @@
+//#include "String.hpp"
+//#include "Utf.hpp"
+//
+//namespace AsuraEngine
+//{
+// namespace Text
+// {
+//
+//
+// ////////////////////////////////////////////////////////////
+// const std::size_t String::InvalidPos = std::basic_string<uint32>::npos;
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String()
+// {
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(char ansiChar, const std::locale& locale)
+// {
+// m_String += Utf32::DecodeAnsi(ansiChar, locale);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(wchar_t wideChar)
+// {
+// m_String += Utf32::DecodeWide(wideChar);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(uint32 utf32Char)
+// {
+// m_String += utf32Char;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const char* ansiString, const std::locale& locale)
+// {
+// if (ansiString)
+// {
+// std::size_t length = strlen(ansiString);
+// if (length > 0)
+// {
+// m_String.reserve(length + 1);
+// Utf32::FromAnsi(ansiString, ansiString + length, std::back_inserter(m_String), locale);
+// }
+// }
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const std::string& ansiString, const std::locale& locale)
+// {
+// m_String.reserve(ansiString.length() + 1);
+// Utf32::FromAnsi(ansiString.begin(), ansiString.end(), std::back_inserter(m_String), locale);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const wchar_t* wideString)
+// {
+// if (wideString)
+// {
+// std::size_t length = std::wcslen(wideString);
+// if (length > 0)
+// {
+// m_String.reserve(length + 1);
+// Utf32::FromWide(wideString, wideString + length, std::back_inserter(m_String));
+// }
+// }
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const std::wstring& wideString)
+// {
+// m_String.reserve(wideString.length() + 1);
+// Utf32::FromWide(wideString.begin(), wideString.end(), std::back_inserter(m_String));
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const uint32* utf32String)
+// {
+// if (utf32String)
+// m_String = utf32String;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const std::basic_string<uint32>& utf32String) :
+// m_String(utf32String)
+// {
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::String(const String& copy) :
+// m_String(copy.mString)
+// {
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::operator std::string() const
+// {
+// return ToAnsiString();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::operator std::wstring() const
+// {
+// return ToWideString();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::string String::ToAnsiString(const std::locale& locale) const
+// {
+// // Prepare the output string
+// std::string output;
+// output.reserve(m_String.length() + 1);
+//
+// // Convert
+// Utf32::ToAnsi(m_String.begin(), m_String.end(), std::back_inserter(output), 0, locale);
+//
+// return output;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::wstring String::ToWideString() const
+// {
+// // Prepare the output string
+// std::wstring output;
+// output.reserve(m_String.length() + 1);
+//
+// // Convert
+// Utf32::ToWide(m_String.begin(), m_String.end(), std::back_inserter(output), 0);
+//
+// return output;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint8> String::ToUtf8() const
+// {
+// // Prepare the output string
+// std::basic_string<uint8> output;
+// output.reserve(m_String.length());
+//
+// // Convert
+// Utf32::ToUtf8(m_String.begin(), m_String.end(), std::back_inserter(output));
+//
+// return output;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint16> String::ToUtf16() const
+// {
+// // Prepare the output string
+// std::basic_string<uint16> output;
+// output.reserve(m_String.length());
+//
+// // Convert
+// Utf32::ToUtf16(m_String.begin(), m_String.end(), std::back_inserter(output));
+//
+// return output;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint32> String::ToUtf32() const
+// {
+// return m_String;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String& String::operator =(const String& right)
+// {
+// m_String = right.mString;
+// return *this;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String& String::operator +=(const String& right)
+// {
+// m_String += right.mString;
+// return *this;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// uint32 String::operator [](std::size_t index) const
+// {
+// return m_String[index];
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// uint32& String::operator [](std::size_t index)
+// {
+// return m_String[index];
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// void String::Clear()
+// {
+// m_String.clear();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::size_t String::GetSize() const
+// {
+// return m_String.size();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool String::IsEmpty() const
+// {
+// return m_String.empty();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// void String::Erase(std::size_t position, std::size_t count)
+// {
+// m_String.erase(position, count);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// void String::Insert(std::size_t position, const String& str)
+// {
+// m_String.insert(position, str.mString);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// std::size_t String::Find(const String& str, std::size_t start) const
+// {
+// return m_String.find(str.mString, start);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// void String::Replace(std::size_t position, std::size_t length, const String& replaceWith)
+// {
+// m_String.replace(position, length, replaceWith.mString);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// void String::Replace(const String& searchFor, const String& replaceWith)
+// {
+// std::size_t step = replaceWith.GetSize();
+// std::size_t len = searchFor.GetSize();
+// std::size_t pos = Find(searchFor);
+//
+// // Replace each occurrence of search
+// while (pos != InvalidPos)
+// {
+// Replace(pos, len, replaceWith);
+// pos = Find(searchFor, pos + step);
+// }
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String String::Substring(std::size_t position, std::size_t length) const
+// {
+// return m_String.substr(position, length);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// const uint32* String::GetData() const
+// {
+// return m_String.c_str();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::Iterator String::Begin()
+// {
+// return m_String.begin();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::ConstIterator String::Begin() const
+// {
+// return m_String.begin();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::Iterator String::End()
+// {
+// return m_String.end();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String::ConstIterator String::End() const
+// {
+// return m_String.end();
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator ==(const String& left, const String& right)
+// {
+// return left.mString == right.mString;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator !=(const String& left, const String& right)
+// {
+// return !(left == right);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator <(const String& left, const String& right)
+// {
+// return left.mString < right.mString;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator >(const String& left, const String& right)
+// {
+// return right < left;
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator <=(const String& left, const String& right)
+// {
+// return !(right < left);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// bool operator >=(const String& left, const String& right)
+// {
+// return !(left < right);
+// }
+//
+//
+// ////////////////////////////////////////////////////////////
+// String operator +(const String& left, const String& right)
+// {
+// String string = left;
+// string += right;
+//
+// return string;
+// }
+//
+//
+// }
+//}
diff --git a/Source/modules/asura-core/Font/String.hpp b/Source/modules/asura-core/Font/String.hpp
new file mode 100644
index 0000000..845a1d5
--- /dev/null
+++ b/Source/modules/asura-core/Font/String.hpp
@@ -0,0 +1,595 @@
+//#ifndef _ASURA_ENGINE_STRING_H_
+//#define _ASURA_ENGINE_STRING_H_
+//
+//#include <asura-base/type.h>
+//
+//#include <iterator>
+//#include <locale>
+//#include <string>
+//
+//namespace AsuraEngine
+//{
+// namespace Text
+// {
+//
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Utility string class that automatically handles
+// /// conversions between types and encodings
+// ///
+// ////////////////////////////////////////////////////////////
+// class String
+// {
+// public:
+//
+// ////////////////////////////////////////////////////////////
+// // Types
+// ////////////////////////////////////////////////////////////
+// typedef std::basic_string<uint32>::iterator Iterator; ///< Iterator type
+// typedef std::basic_string<uint32>::const_iterator ConstIterator; ///< Read-only iterator type
+//
+// ////////////////////////////////////////////////////////////
+// // Static member data
+// ////////////////////////////////////////////////////////////
+// static const std::size_t InvalidPos; ///< Represents an invalid position in the string
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Default constructor
+// ///
+// /// This constructor creates an empty string.
+// ///
+// ////////////////////////////////////////////////////////////
+// String();
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from a single ANSI character and a locale
+// ///
+// /// The source character is converted to UTF-32 according
+// /// to the given locale.
+// ///
+// /// \param ansiChar ANSI character to convert
+// /// \param locale Locale to use for conversion
+// ///
+// ////////////////////////////////////////////////////////////
+// String(char ansiChar, const std::locale& locale = std::locale());
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from single wide character
+// ///
+// /// \param wideChar Wide character to convert
+// ///
+// ////////////////////////////////////////////////////////////
+// String(wchar_t wideChar);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from single UTF-32 character
+// ///
+// /// \param utf32Char UTF-32 character to convert
+// ///
+// ////////////////////////////////////////////////////////////
+// String(uint utf32Char);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from a null-terminated C-style ANSI string and a locale
+// ///
+// /// The source string is converted to UTF-32 according
+// /// to the given locale.
+// ///
+// /// \param ansiString ANSI string to convert
+// /// \param locale Locale to use for conversion
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const char* ansiString, const std::locale& locale = std::locale());
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from an ANSI string and a locale
+// ///
+// /// The source string is converted to UTF-32 according
+// /// to the given locale.
+// ///
+// /// \param ansiString ANSI string to convert
+// /// \param locale Locale to use for conversion
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const std::string& ansiString, const std::locale& locale = std::locale());
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from null-terminated C-style wide string
+// ///
+// /// \param wideString Wide string to convert
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const wchar_t* wideString);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from a wide string
+// ///
+// /// \param wideString Wide string to convert
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const std::wstring& wideString);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from a null-terminated C-style UTF-32 string
+// ///
+// /// \param utf32String UTF-32 string to assign
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const uint* utf32String);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Construct from an UTF-32 string
+// ///
+// /// \param utf32String UTF-32 string to assign
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const std::basic_string<uint>& utf32String);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Copy constructor
+// ///
+// /// \param copy Instance to copy
+// ///
+// ////////////////////////////////////////////////////////////
+// String(const String& copy);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Create a new sf::String from a UTF-8 encoded string
+// ///
+// /// \param begin Forward iterator to the beginning of the UTF-8 sequence
+// /// \param end Forward iterator to the end of the UTF-8 sequence
+// ///
+// /// \return A sf::String containing the source string
+// ///
+// /// \see fromUtf16, fromUtf32
+// ///
+// ////////////////////////////////////////////////////////////
+// template <typename T>
+// static String FromUtf8(T begin, T end);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Create a new sf::String from a UTF-16 encoded string
+// ///
+// /// \param begin Forward iterator to the beginning of the UTF-16 sequence
+// /// \param end Forward iterator to the end of the UTF-16 sequence
+// ///
+// /// \return A sf::String containing the source string
+// ///
+// /// \see fromUtf8, fromUtf32
+// ///
+// ////////////////////////////////////////////////////////////
+// template <typename T>
+// static String FromUtf16(T begin, T end);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Create a new sf::String from a UTF-32 encoded string
+// ///
+// /// This function is provided for consistency, it is equivalent to
+// /// using the constructors that takes a const sf::uint* or
+// /// a std::basic_string<sf::uint>.
+// ///
+// /// \param begin Forward iterator to the beginning of the UTF-32 sequence
+// /// \param end Forward iterator to the end of the UTF-32 sequence
+// ///
+// /// \return A sf::String containing the source string
+// ///
+// /// \see fromUtf8, fromUtf16
+// ///
+// ////////////////////////////////////////////////////////////
+// template <typename T>
+// static String FromUtf32(T begin, T end);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Implicit conversion operator to std::string (ANSI string)
+// ///
+// /// The current global locale is used for conversion. If you
+// /// want to explicitly specify a locale, see toAnsiString.
+// /// Characters that do not fit in the target encoding are
+// /// discarded from the returned string.
+// /// This operator is defined for convenience, and is equivalent
+// /// to calling toAnsiString().
+// ///
+// /// \return Converted ANSI string
+// ///
+// /// \see toAnsiString, operator std::wstring
+// ///
+// ////////////////////////////////////////////////////////////
+// operator std::string() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Implicit conversion operator to std::wstring (wide string)
+// ///
+// /// Characters that do not fit in the target encoding are
+// /// discarded from the returned string.
+// /// This operator is defined for convenience, and is equivalent
+// /// to calling toWideString().
+// ///
+// /// \return Converted wide string
+// ///
+// /// \see toWideString, operator std::string
+// ///
+// ////////////////////////////////////////////////////////////
+// operator std::wstring() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Convert the Unicode string to an ANSI string
+// ///
+// /// The UTF-32 string is converted to an ANSI string in
+// /// the encoding defined by \a locale.
+// /// Characters that do not fit in the target encoding are
+// /// discarded from the returned string.
+// ///
+// /// \param locale Locale to use for conversion
+// ///
+// /// \return Converted ANSI string
+// ///
+// /// \see toWideString, operator std::string
+// ///
+// ////////////////////////////////////////////////////////////
+// std::string ToAnsiString(const std::locale& locale = std::locale()) const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Convert the Unicode string to a wide string
+// ///
+// /// Characters that do not fit in the target encoding are
+// /// discarded from the returned string.
+// ///
+// /// \return Converted wide string
+// ///
+// /// \see toAnsiString, operator std::wstring
+// ///
+// ////////////////////////////////////////////////////////////
+// std::wstring ToWideString() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Convert the Unicode string to a UTF-8 string
+// ///
+// /// \return Converted UTF-8 string
+// ///
+// /// \see toUtf16, toUtf32
+// ///
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint8> ToUtf8() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Convert the Unicode string to a UTF-16 string
+// ///
+// /// \return Converted UTF-16 string
+// ///
+// /// \see toUtf8, toUtf32
+// ///
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint16> ToUtf16() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Convert the Unicode string to a UTF-32 string
+// ///
+// /// This function doesn't perform any conversion, since the
+// /// string is already stored as UTF-32 internally.
+// ///
+// /// \return Converted UTF-32 string
+// ///
+// /// \see toUtf8, toUtf16
+// ///
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint> ToUtf32() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Overload of assignment operator
+// ///
+// /// \param right Instance to assign
+// ///
+// /// \return Reference to self
+// ///
+// ////////////////////////////////////////////////////////////
+// String& operator =(const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Overload of += operator to append an UTF-32 string
+// ///
+// /// \param right String to append
+// ///
+// /// \return Reference to self
+// ///
+// ////////////////////////////////////////////////////////////
+// String& operator +=(const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Overload of [] operator to access a character by its position
+// ///
+// /// This function provides read-only access to characters.
+// /// Note: the behavior is undefined if \a index is out of range.
+// ///
+// /// \param index Index of the character to get
+// ///
+// /// \return Character at position \a index
+// ///
+// ////////////////////////////////////////////////////////////
+// uint operator [](std::size_t index) const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Overload of [] operator to access a character by its position
+// ///
+// /// This function provides read and write access to characters.
+// /// Note: the behavior is undefined if \a index is out of range.
+// ///
+// /// \param index Index of the character to get
+// ///
+// /// \return Reference to the character at position \a index
+// ///
+// ////////////////////////////////////////////////////////////
+// uint& operator [](std::size_t index);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Clear the string
+// ///
+// /// This function removes all the characters from the string.
+// ///
+// /// \see isEmpty, erase
+// ///
+// ////////////////////////////////////////////////////////////
+// void Clear();
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Get the size of the string
+// ///
+// /// \return Number of characters in the string
+// ///
+// /// \see isEmpty
+// ///
+// ////////////////////////////////////////////////////////////
+// std::size_t GetSize() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Check whether the string is empty or not
+// ///
+// /// \return True if the string is empty (i.e. contains no character)
+// ///
+// /// \see clear, getSize
+// ///
+// ////////////////////////////////////////////////////////////
+// bool IsEmpty() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Erase one or more characters from the string
+// ///
+// /// This function removes a sequence of \a count characters
+// /// starting from \a position.
+// ///
+// /// \param position Position of the first character to erase
+// /// \param count Number of characters to erase
+// ///
+// ////////////////////////////////////////////////////////////
+// void Erase(std::size_t position, std::size_t count = 1);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Insert one or more characters into the string
+// ///
+// /// This function inserts the characters of \a str
+// /// into the string, starting from \a position.
+// ///
+// /// \param position Position of insertion
+// /// \param str Characters to insert
+// ///
+// ////////////////////////////////////////////////////////////
+// void Insert(std::size_t position, const String& str);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Find a sequence of one or more characters in the string
+// ///
+// /// This function searches for the characters of \a str
+// /// in the string, starting from \a start.
+// ///
+// /// \param str Characters to find
+// /// \param start Where to begin searching
+// ///
+// /// \return Position of \a str in the string, or String::InvalidPos if not found
+// ///
+// ////////////////////////////////////////////////////////////
+// std::size_t Find(const String& str, std::size_t start = 0) const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Replace a substring with another string
+// ///
+// /// This function replaces the substring that starts at index \a position
+// /// and spans \a length characters with the string \a replaceWith.
+// ///
+// /// \param position Index of the first character to be replaced
+// /// \param length Number of characters to replace. You can pass InvalidPos to
+// /// replace all characters until the end of the string.
+// /// \param replaceWith String that replaces the given substring.
+// ///
+// ////////////////////////////////////////////////////////////
+// void Replace(std::size_t position, std::size_t length, const String& replaceWith);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Replace all occurrences of a substring with a replacement string
+// ///
+// /// This function replaces all occurrences of \a searchFor in this string
+// /// with the string \a replaceWith.
+// ///
+// /// \param searchFor The value being searched for
+// /// \param replaceWith The value that replaces found \a searchFor values
+// ///
+// ////////////////////////////////////////////////////////////
+// void Replace(const String& searchFor, const String& replaceWith);
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Return a part of the string
+// ///
+// /// This function returns the substring that starts at index \a position
+// /// and spans \a length characters.
+// ///
+// /// \param position Index of the first character
+// /// \param length Number of characters to include in the substring (if
+// /// the string is shorter, as many characters as possible
+// /// are included). \ref InvalidPos can be used to include all
+// /// characters until the end of the string.
+// ///
+// /// \return String object containing a substring of this object
+// ///
+// ////////////////////////////////////////////////////////////
+// String Substring(std::size_t position, std::size_t length = InvalidPos) const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Get a pointer to the C-style array of characters
+// ///
+// /// This functions provides a read-only access to a
+// /// null-terminated C-style representation of the string.
+// /// The returned pointer is temporary and is meant only for
+// /// immediate use, thus it is not recommended to store it.
+// ///
+// /// \return Read-only pointer to the array of characters
+// ///
+// ////////////////////////////////////////////////////////////
+// const uint* GetData() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Return an iterator to the beginning of the string
+// ///
+// /// \return Read-write iterator to the beginning of the string characters
+// ///
+// /// \see end
+// ///
+// ////////////////////////////////////////////////////////////
+// Iterator Begin();
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Return an iterator to the beginning of the string
+// ///
+// /// \return Read-only iterator to the beginning of the string characters
+// ///
+// /// \see end
+// ///
+// ////////////////////////////////////////////////////////////
+// ConstIterator Begin() const;
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Return an iterator to the end of the string
+// ///
+// /// The end iterator refers to 1 position past the last character;
+// /// thus it represents an invalid character and should never be
+// /// accessed.
+// ///
+// /// \return Read-write iterator to the end of the string characters
+// ///
+// /// \see begin
+// ///
+// ////////////////////////////////////////////////////////////
+// Iterator End();
+//
+// ////////////////////////////////////////////////////////////
+// /// \brief Return an iterator to the end of the string
+// ///
+// /// The end iterator refers to 1 position past the last character;
+// /// thus it represents an invalid character and should never be
+// /// accessed.
+// ///
+// /// \return Read-only iterator to the end of the string characters
+// ///
+// /// \see begin
+// ///
+// ////////////////////////////////////////////////////////////
+// ConstIterator End() const;
+//
+// private:
+//
+// friend bool operator ==(const String& left, const String& right);
+// friend bool operator <(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// // Member data
+// ////////////////////////////////////////////////////////////
+// std::basic_string<uint> m_String; ///< Internal string of UTF-32 characters
+// };
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of == operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if both strings are equal
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator ==(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of != operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if both strings are different
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator !=(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of < operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if \a left is lexicographically before \a right
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator <(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of > operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if \a left is lexicographically after \a right
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator >(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of <= operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if \a left is lexicographically before or equivalent to \a right
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator <=(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of >= operator to compare two UTF-32 strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return True if \a left is lexicographically after or equivalent to \a right
+// ///
+// ////////////////////////////////////////////////////////////
+// bool operator >=(const String& left, const String& right);
+//
+// ////////////////////////////////////////////////////////////
+// /// \relates String
+// /// \brief Overload of binary + operator to concatenate two strings
+// ///
+// /// \param left Left operand (a string)
+// /// \param right Right operand (a string)
+// ///
+// /// \return Concatenated string
+// ///
+// ////////////////////////////////////////////////////////////
+// String operator +(const String& left, const String& right);
+//
+// #include "String.inc"
+//
+// }
+//}
+//
+//#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Font/String.inc b/Source/modules/asura-core/Font/String.inc
new file mode 100644
index 0000000..ef18228
--- /dev/null
+++ b/Source/modules/asura-core/Font/String.inc
@@ -0,0 +1,29 @@
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf8(T begin, T end)
+{
+ String string;
+ Utf8::toUtf32(begin, end, std::back_inserter(string.m_string));
+ return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf16(T begin, T end)
+{
+ String string;
+ Utf16::toUtf32(begin, end, std::back_inserter(string.m_string));
+ return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf32(T begin, T end)
+{
+ String string;
+ string.m_string.assign(begin, end);
+ return string;
+}
diff --git a/Source/modules/asura-core/Font/TTF.cpp b/Source/modules/asura-core/Font/TTF.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Font/TTF.cpp
diff --git a/Source/modules/asura-core/Font/TTF.h b/Source/modules/asura-core/Font/TTF.h
new file mode 100644
index 0000000..b83cf76
--- /dev/null
+++ b/Source/modules/asura-core/Font/TTF.h
@@ -0,0 +1,17 @@
+#ifndef _ASURA_TTF_H_
+#define _ASURA_TTF_H_
+
+namespace AsuraEngine
+{
+ namespace Text
+ {
+
+ class TTF
+ {
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Font/Utf.hpp b/Source/modules/asura-core/Font/Utf.hpp
new file mode 100644
index 0000000..59f62ed
--- /dev/null
+++ b/Source/modules/asura-core/Font/Utf.hpp
@@ -0,0 +1,720 @@
+#ifndef _ASURA_UTF_HPP_
+#define _ASURA_UTF_HPP_
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <algorithm>
+#include <locale>
+#include <string>
+#include <cstdlib>
+
+namespace AsuraEngine
+{
+ namespace Text
+ {
+
+ template <unsigned int N>
+ class Utf;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-8
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<8>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-8 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-8 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-8 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-8.
+ ///
+ /// \param input Codepoint to encode as UTF-8
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint8 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-8 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-8 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-8
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-8
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-16
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<16>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-16 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-16 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-16 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-16.
+ ///
+ /// \param input Codepoint to encode as UTF-16
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint16 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-16 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-16 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-16
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-16
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-32
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<32>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-32 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ /// For UTF-32, the character value is the same as the codepoint.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-32 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-32.
+ /// For UTF-32, the codepoint is the same as the character value.
+ ///
+ /// \param input Codepoint to encode as UTF-32
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-32 character
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-32 sequence
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-32
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-32
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single ANSI character to UTF-32
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param input Input ANSI character
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static Uint32 DecodeAnsi(In input, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single wide character to UTF-32
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param input Input wide character
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static Uint32 DecodeWide(In input);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to ANSI
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to skip it)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeAnsi(Uint32 codepoint, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to wide
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to wide (use 0 to skip it)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeWide(Uint32 codepoint, Out output, wchar_t replacement = 0);
+ };
+
+#include "Utf.inc"
+
+ // Make typedefs to get rid of the template syntax
+ typedef Utf<8> Utf8;
+ typedef Utf<16> Utf16;
+ typedef Utf<32> Utf32;
+
+ } // namespace sf
+
+}
+
+
+#endif // SFML_UTF_HPP
diff --git a/Source/modules/asura-core/Font/Utf.inc b/Source/modules/asura-core/Font/Utf.inc
new file mode 100644
index 0000000..69a523b
--- /dev/null
+++ b/Source/modules/asura-core/Font/Utf.inc
@@ -0,0 +1,752 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+// References:
+//
+// https://www.unicode.org/
+// https://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
+// https://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h
+// https://people.w3.org/rishida/scripts/uniview/conversion
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+ // Some useful precomputed data
+ static const int trailing[256] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
+ };
+ static const Uint32 offsets[6] =
+ {
+ 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080
+ };
+
+ // decode the character
+ int trailingBytes = trailing[static_cast<Uint8>(*begin)];
+ if (begin + trailingBytes < end)
+ {
+ output = 0;
+ switch (trailingBytes)
+ {
+ case 5: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 4: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 3: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 2: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 1: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 0: output += static_cast<Uint8>(*begin++);
+ }
+ output -= offsets[trailingBytes];
+ }
+ else
+ {
+ // Incomplete character
+ begin = end;
+ output = replacement;
+ }
+
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<8>::Encode(Uint32 input, Out output, Uint8 replacement)
+{
+ // Some useful precomputed data
+ static const Uint8 firstBytes[7] =
+ {
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
+ };
+
+ // encode the character
+ if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF)))
+ {
+ // Invalid character
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // Valid character
+
+ // Get the number of bytes to write
+ std::size_t bytestoWrite = 1;
+ if (input < 0x80) bytestoWrite = 1;
+ else if (input < 0x800) bytestoWrite = 2;
+ else if (input < 0x10000) bytestoWrite = 3;
+ else if (input <= 0x0010FFFF) bytestoWrite = 4;
+
+ // Extract the bytes to write
+ Uint8 bytes[4];
+ switch (bytestoWrite)
+ {
+ case 4: bytes[3] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 3: bytes[2] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 2: bytes[1] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 1: bytes[0] = static_cast<Uint8> (input | firstBytes[bytestoWrite]);
+ }
+
+ // Add them to the output
+ output = std::copy(bytes, bytes + bytestoWrite, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::Next(In begin, In end)
+{
+ Uint32 codepoint;
+ return Decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<8>::Count(In begin, In end)
+{
+ std::size_t length = 0;
+ while (begin < end)
+ {
+ begin = Next(begin, end);
+ ++length;
+ }
+
+ return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ output = Encode(*begin++, output);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeWide(codepoint, output, replacement);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint < 256 ? static_cast<char>(codepoint) : replacement;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf8(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf16(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<16>::Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf32(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+ Uint16 first = *begin++;
+
+ // If it's a surrogate pair, first convert to a single UTF-32 character
+ if ((first >= 0xD800) && (first <= 0xDBFF))
+ {
+ if (begin < end)
+ {
+ Uint32 second = *begin++;
+ if ((second >= 0xDC00) && (second <= 0xDFFF))
+ {
+ // The second element is valid: convert the two elements to a UTF-32 character
+ output = ((first - 0xD800) << 10) + (second - 0xDC00) + 0x0010000;
+ }
+ else
+ {
+ // Invalid character
+ output = replacement;
+ }
+ }
+ else
+ {
+ // Invalid character
+ begin = end;
+ output = replacement;
+ }
+ }
+ else
+ {
+ // We can make a direct copy
+ output = first;
+ }
+
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<16>::Encode(Uint32 input, Out output, Uint16 replacement)
+{
+ if (input <= 0xFFFF)
+ {
+ // The character can be copied directly, we just need to check if it's in the valid range
+ if ((input >= 0xD800) && (input <= 0xDFFF))
+ {
+ // Invalid character (this range is reserved)
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // Valid character directly convertible to a single UTF-16 character
+ *output++ = static_cast<Uint16>(input);
+ }
+ }
+ else if (input > 0x0010FFFF)
+ {
+ // Invalid character (greater than the maximum Unicode value)
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // The input character will be converted to two UTF-16 elements
+ input -= 0x0010000;
+ *output++ = static_cast<Uint16>((input >> 10) + 0xD800);
+ *output++ = static_cast<Uint16>((input & 0x3FFUL) + 0xDC00);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::Next(In begin, In end)
+{
+ Uint32 codepoint;
+ return Decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<16>::Count(In begin, In end)
+{
+ std::size_t length = 0;
+ while (begin < end)
+ {
+ begin = Next(begin, end);
+ ++length;
+ }
+
+ return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeWide(codepoint, output, replacement);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+ begin++;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf8(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<8>::Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf16(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf32(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::Decode(In begin, In /*end*/, Uint32& output, Uint32 /*replacement*/)
+{
+ output = *begin++;
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::Encode(Uint32 input, Out output, Uint32 /*replacement*/)
+{
+ *output++ = input;
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::Next(In begin, In /*end*/)
+{
+ return ++begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<32>::Count(In begin, In end)
+{
+ return begin - end;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ *output++ = DecodeAnsi(*begin++, locale);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ *output++ = DecodeWide(*begin++);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ output = EncodeAnsi(*begin++, output, replacement, locale);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ output = EncodeWide(*begin++, output, replacement);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+ begin++;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf8(In begin, In end, Out output)
+{
+ while (begin < end)
+ output = Utf<8>::Encode(*begin++, output);
+
+ return output;
+}
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf16(In begin, In end, Out output)
+{
+ while (begin < end)
+ output = Utf<16>::Encode(*begin++, output);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf32(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::DecodeAnsi(In input, const std::locale& locale)
+{
+ // On Windows, GCC's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
+
+ #if defined(SFML_SYSTEM_WINDOWS) && /* if Windows ... */ \
+ (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
+ !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+ (void)locale; // to avoid warnings
+
+ wchar_t character = 0;
+ mbtowc(&character, &input, 1);
+ return static_cast<Uint32>(character);
+
+ #else
+
+ // Get the facet of the locale which deals with character conversion
+ const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+ // Use the facet to convert each character of the input string
+ return static_cast<Uint32>(facet.widen(input));
+
+ #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::DecodeWide(In input)
+{
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4,
+ // and UCS-4 *is* UTF-32).
+
+ return input;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::EncodeAnsi(Uint32 codepoint, Out output, char replacement, const std::locale& locale)
+{
+ // On Windows, gcc's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
+
+ #if defined(SFML_SYSTEM_WINDOWS) && /* if Windows ... */ \
+ (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
+ !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+ (void)locale; // to avoid warnings
+
+ char character = 0;
+ if (wctomb(&character, static_cast<wchar_t>(codepoint)) >= 0)
+ *output++ = character;
+ else if (replacement)
+ *output++ = replacement;
+
+ return output;
+
+ #else
+
+ // Get the facet of the locale which deals with character conversion
+ const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+ // Use the facet to convert each character of the input string
+ *output++ = facet.narrow(static_cast<wchar_t>(codepoint), replacement);
+
+ return output;
+
+ #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::EncodeWide(Uint32 codepoint, Out output, wchar_t replacement)
+{
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4).
+ // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32).
+
+ switch (sizeof(wchar_t))
+ {
+ case 4:
+ {
+ *output++ = static_cast<wchar_t>(codepoint);
+ break;
+ }
+
+ default:
+ {
+ if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF)))
+ {
+ *output++ = static_cast<wchar_t>(codepoint);
+ }
+ else if (replacement)
+ {
+ *output++ = replacement;
+ }
+ break;
+ }
+ }
+
+ return output;
+}
diff --git a/Source/modules/asura-core/Graphics/BlendMode.h b/Source/modules/asura-core/Graphics/BlendMode.h
new file mode 100644
index 0000000..fb17b45
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/BlendMode.h
@@ -0,0 +1,17 @@
+#ifndef _ASURA_ENGINE_BLEND_MODE_H_
+#define _ASURA_ENGINE_BLEND_MODE_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+enum BlendMode
+{
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Canvas.cpp b/Source/modules/asura-core/Graphics/Canvas.cpp
new file mode 100644
index 0000000..60c8f87
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Canvas.cpp
@@ -0,0 +1,49 @@
+#include "Canvas.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+Canvas::Canvas()
+ : m_Width(0)
+ , m_Height(0)
+ , m_FBO(0)
+{
+ // Fix: ôСʼʱframebufferԴ
+ //glGenFramebuffers(1, &m_FBO);
+ //GLint current_fbo;
+ //glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
+ //glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
+ //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TexID, 0);
+ //glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
+}
+
+void Canvas::SetSize(uint w, uint h)
+{
+ if (m_FBO == 0)
+ {
+ glGenFramebuffers(1, &m_FBO);
+ if (m_FBO == 0)
+ throw Exception("OpenGL glGenFramebuffers cannot generate frame buffer object.");
+ //
+ if (m_TexID == 0)
+ {
+ glGenTextures(1, &m_TexID);
+ if (m_TexID == 0)
+ throw Exception("OpenGL glGenTextures cannot generate texture.");
+ }
+ GLint current_fbo;
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_TexID, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
+ }
+ GLint current_tex;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_tex);
+ glBindTexture(GL_TEXTURE_2D, m_TexID);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glBindTexture(GL_TEXTURE_2D, current_tex);
+}
+
+namespace_end
+
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Canvas.h b/Source/modules/asura-core/Graphics/Canvas.h
new file mode 100644
index 0000000..de02b9d
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Canvas.h
@@ -0,0 +1,73 @@
+#ifndef _ASURA_ENGINE_CANVAS_H_
+#define _ASURA_ENGINE_CANVAS_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Math/Rect.hpp>
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Exception.h>
+
+#include "GfxDevice.h"
+#include "Texture.h"
+#include "RenderTarget.h"
+#include "RenderState.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+///
+/// CanvasҲԳΪrender textureҲΪtextureȾ
+///
+class Canvas ASURA_FINAL
+ : public Scripting::Portable<Canvas, RenderTarget>
+{
+public:
+
+ Canvas();
+
+ ~Canvas();
+
+ ///
+ /// render textureĴС
+ ///
+ void SetSize(uint w, uint h) ASURA_THROW(Exception);
+
+ void Clear(const Color& col = Color::Black) override;
+/*
+ void Clear(const Math::Recti& quad, const Color& col = Color::Black) override;
+*/
+ void Render(const RenderTarget* rt, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
+
+ void Render(const RenderTarget* rt, const Math::Rectf& quad, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
+
+ void Draw(const Drawable* texture, const RenderState& state);
+
+ void Draw(const Drawable* texture, const Math::Recti& quad, const RenderState& state);
+
+private:
+
+ GLuint m_FBO;
+
+ GLuint m_TexID;
+
+ uint m_Width, m_Height;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Canvas, RenderTarget);
+
+ LUAX_DECL_METHOD(_SetSize);
+ LUAX_DECL_METHOD(_Bind);
+ LUAX_DECL_METHOD(_Unbind);
+
+};
+
+///
+/// CanvasΪRenderTexture
+///
+typedef Canvas RenderTexture;
+
+} // Graphics
+} // AsuraEngine
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Color.cpp b/Source/modules/asura-core/Graphics/Color.cpp
new file mode 100644
index 0000000..5a66291
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Color.cpp
@@ -0,0 +1,58 @@
+#include "Color.h"
+#include "Color32.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+Color::Color()
+{
+ r = g = b = a = 0;
+}
+
+Color::Color(const Color& c)
+{
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+}
+
+Color::Color(float r, float g, float b, float a)
+{
+ this->r = r;
+ this->g = g;
+ this->b = b;
+ this->a = a;
+}
+
+Color::Color(const Color32& c)
+{
+ r = c.r / 255.f;
+ g = c.g / 255.f;
+ b = c.b / 255.f;
+ a = c.a / 255.f;
+}
+
+Color::~Color()
+{
+}
+
+void Color::Set(float r, float g, float b, float a)
+{
+ this->r = r;
+ this->g = g;
+ this->b = b;
+ this->a = a;
+}
+
+//Color Color::operator *(const Color& c)
+//{
+// r *= c.r;
+// g *= c.g;
+// b *= c.b;
+// a *= c.a;
+
+//}
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Graphics/Color.h b/Source/modules/asura-core/Graphics/Color.h
new file mode 100644
index 0000000..c81b601
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Color.h
@@ -0,0 +1,75 @@
+#ifndef _ASURA_ENGINE_COLOR_H_
+#define _ASURA_ENGINE_COLOR_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Classes.h>
+
+#include "../CoreConfig.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class Color32;
+
+///
+/// 淶ɫColor32иIJԡ
+///
+class Color ASURA_FINAL
+ : public Scripting::Portable<Color>
+{
+public:
+
+ static Color Black;
+ static Color White;
+ static Color Red;
+ static Color Green;
+ static Color Blue;
+
+ Color();
+
+ Color(const Color& c);
+
+ Color(float r, float g, float b, float a);
+
+ Color(const Color32& c);
+
+ ~Color();
+
+ Color operator *(const Color& c);
+
+ void Set(float r, float g, float b, float a);
+
+ GET_SET(float, Red, r);
+ GET_SET(float, Green, g);
+ GET_SET(float, Blue, b);
+ GET_SET(float, Alpha, a);
+
+ float r, g, b, a;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Color);
+
+ LUAX_DECL_METHOD(_ToColor32);
+ LUAX_DECL_METHOD(_SetColor);
+ LUAX_DECL_METHOD(_GetColor);
+ LUAX_DECL_METHOD(_GetR);
+ LUAX_DECL_METHOD(_GetG);
+ LUAX_DECL_METHOD(_GetB);
+ LUAX_DECL_METHOD(_GetA);
+
+ // Ԫ
+ LUAX_DECL_METHOD(___eq); // __eq
+ LUAX_DECL_METHOD(___add); // __add
+ LUAX_DECL_METHOD(___sub); // __sub
+ LUAX_DECL_METHOD(___mul); // __mul
+ LUAX_DECL_METHOD(___div); // __div
+
+};
+
+namespace_end
+namespace_end
+
+namespace AEGraphics = AsuraEngine::Graphics;
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Color32.cpp b/Source/modules/asura-core/Graphics/Color32.cpp
new file mode 100644
index 0000000..f1f0b74
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Color32.cpp
@@ -0,0 +1,53 @@
+#include "Color.h"
+#include "Color32.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+#if ASURA_LITTLE_ENDIAN
+// СˣֽڵAlphaڸߵַ
+const uint32 Color32::RMASK = 0x000000ff;
+const uint32 Color32::GMASK = 0x0000ff00;
+const uint32 Color32::BMASK = 0x00ff0000;
+const uint32 Color32::AMASK = 0xff000000;
+#endif
+
+Color32::Color32()
+{
+ r = g = b = a = 0;
+}
+
+Color32::Color32(const Color32& c)
+{
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+}
+
+Color32::Color32(const Color& c)
+{
+ r = 255.f * c.r;
+ g = 255.f * c.g;
+ b = 255.f * c.b;
+ a = 255.f * c.a;
+}
+
+Color32::Color32(byte r, byte g, byte b, byte a)
+{
+ this->r = r;
+ this->g = g;
+ this->b = b;
+ this->a = a;
+}
+
+void Color32::Set(const Color32& c32)
+{
+ r = c32.r;
+ g = c32.g;
+ b = c32.b;
+ a = c32.a;
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Color32.h b/Source/modules/asura-core/Graphics/Color32.h
new file mode 100644
index 0000000..4dbfe2d
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Color32.h
@@ -0,0 +1,58 @@
+#ifndef _ASURA_ENGINE_COLOR32_H__
+#define _ASURA_ENGINE_COLOR32_H__
+
+#include <asura-base/Classes.h>
+#include <asura-base/Scripting/Scripting.h>
+
+#include "../CoreConfig.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class Color;
+
+///
+/// 32bitsɫ
+///
+class Color32 ASURA_FINAL
+ : public Scripting::Portable<Color32>
+{
+public:
+
+ static const uint32 RMASK;
+ static const uint32 GMASK;
+ static const uint32 BMASK;
+ static const uint32 AMASK;
+
+ Color32();
+
+ ~Color32();
+
+ Color32(const Color32& c);
+
+ Color32(const Color& c);
+
+ Color32(byte r, byte g, byte b, byte a);
+
+ void Set(const Color32& c32);
+
+ byte r, g, b, a;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Color32);
+
+ LUAX_DECL_METHOD(_ToColor);
+ LUAX_DECL_METHOD(_SetColor);
+ LUAX_DECL_METHOD(_GetColor);
+ LUAX_DECL_METHOD(_GetRed);
+ LUAX_DECL_METHOD(_GetGreen);
+ LUAX_DECL_METHOD(_GetBlue);
+ LUAX_DECL_METHOD(_GetAlpha);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/ColorPalette.h b/Source/modules/asura-core/Graphics/ColorPalette.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/ColorPalette.h
diff --git a/Source/modules/asura-core/Graphics/DrawInfo.cpp b/Source/modules/asura-core/Graphics/DrawInfo.cpp
new file mode 100644
index 0000000..c7a6912
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/DrawInfo.cpp
@@ -0,0 +1,10 @@
+#include "DrawInfo.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Graphics/DrawInfo.h b/Source/modules/asura-core/Graphics/DrawInfo.h
new file mode 100644
index 0000000..0082102
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/DrawInfo.h
@@ -0,0 +1,19 @@
+#ifndef _ASURA_ENGINE_DRAWINFO_H_
+#define _ASURA_ENGINE_DRAWINFO_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+struct DrawInfo
+{
+
+};
+
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/DrawUtil.cpp b/Source/modules/asura-core/Graphics/DrawUtil.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/DrawUtil.cpp
diff --git a/Source/modules/asura-core/Graphics/DrawUtil.h b/Source/modules/asura-core/Graphics/DrawUtil.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/DrawUtil.h
diff --git a/Source/modules/asura-core/Graphics/GPUBuffer.cpp b/Source/modules/asura-core/Graphics/GPUBuffer.cpp
new file mode 100644
index 0000000..f28b914
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GPUBuffer.cpp
@@ -0,0 +1,151 @@
+#include "GPUBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+GPUBuffer::GPUBuffer(BufferType type, BufferUsage usage, BufferDataType dataType, size_t size)
+ : m_Target(GL_ZERO)
+ , m_Buffer(GL_ZERO)
+ , m_Size(0)
+#if ASURA_DEBUG
+ , m_Data(nullptr)
+#endif
+{
+ m_Target = ConvertBufferType(type);
+ m_Usage = ConvertBufferUsage(usage);
+ m_DataType = ConvertBufferDataType(dataType);
+ m_Size = size;
+}
+
+GPUBuffer::~GPUBuffer()
+{
+#if ASURA_DEBUG
+ if (m_Data)
+ free(m_Data);
+#endif
+ glDeleteBuffers(1, &m_Buffer);
+}
+
+GLenum GPUBuffer::ConvertBufferType(BufferType type)
+{
+ switch (type)
+ {
+ case BUFFER_TYPE_VERTEX:
+ return GL_ARRAY_BUFFER;
+ case BUFFER_TYPE_INDEX:
+ return GL_ELEMENT_ARRAY_BUFFER;
+ }
+}
+
+GLenum GPUBuffer::ConvertBufferUsage(BufferUsage usage)
+{
+ switch (usage)
+ {
+ case BUFFER_USAGE_STREAM:
+ return GL_STREAM_DRAW;
+ case BUFFER_USAGE_DYNAMIC:
+ return GL_DYNAMIC_DRAW;
+ case BUFFER_USAGE_STATIC:
+ return GL_STATIC_DRAW;
+ }
+}
+
+GLenum GPUBuffer::ConvertBufferDataType(BufferDataType type)
+{
+ switch (type)
+ {
+ case BUFFER_DATA_TYPE_INT:
+ return GL_INT;
+ case BUFFER_DATA_TYPE_FLOAT:
+ return GL_FLOAT;
+ case BUFFER_DATA_TYPE_UNSIGNED_BYTE:
+ return GL_UNSIGNED_BYTE;
+ }
+}
+
+bool GPUBuffer::Fill(const void * data, size_t size, uint offset)
+{
+ if (data == nullptr)
+ return false;
+ if (m_Buffer == 0)
+ {
+ g_Device.WipeError();
+ glGenBuffers(1, &m_Buffer);
+ if (m_Buffer == 0)
+ throw Exception("OpenGL glGenBuffers failed.");
+ glBindBuffer(m_Target, m_Buffer);
+ glBufferData(m_Target, m_Size, NULL, m_Usage);
+ if (g_Device.HasError())
+ {
+ glBindBuffer(m_Target, 0);
+ throw Exception("OpenGL glBufferData failed. Errorcode=%d.", g_Device.GetError());
+ }
+#if ASURA_DEBUG
+ m_Data = (byte*)malloc(size);
+ memset(m_Data, 0, size);
+#endif
+ }
+ else
+ glBindBuffer(m_Target, m_Buffer);
+ glBufferSubData(m_Target, offset, size, data);
+ if (g_Device.HasError())
+ {
+ glBindBuffer(m_Target, 0);
+ throw Exception("OpenGL glBufferSubData failed. Errorcode=%d.", g_Device.GetError());
+ }
+ glBindBuffer(m_Target, 0);
+#if ASURA_DEBUG
+ memcpy(m_Data + offset, data, size);
+#endif
+ return true;
+}
+
+void GPUBuffer::Bind()
+{
+ glBindBuffer(m_Target, m_Buffer);
+}
+
+void GPUBuffer::UnBind()
+{
+ glBindBuffer(m_Target, 0);
+}
+
+uint GPUBuffer::GetBufferSize()
+{
+ return m_Size;
+}
+
+GLenum GPUBuffer::GetDataType()
+{
+ return m_DataType;
+}
+
+size_t GPUBuffer::GetDataTypeSize()
+{
+ //https://blog.csdn.net/nklinux/article/details/16919017
+ switch (m_DataType)
+ {
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLbyte);
+ case GL_FLOAT :
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ }
+}
+
+size_t GPUBuffer::GetDataTypeSize(GLenum datatype)
+{
+ switch (datatype)
+ {
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLbyte);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ }
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/GPUBuffer.h b/Source/modules/asura-core/Graphics/GPUBuffer.h
new file mode 100644
index 0000000..565db17
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GPUBuffer.h
@@ -0,0 +1,93 @@
+#ifndef _ASURA_GPU_BUFFER_H_
+#define _ASURA_GPU_BUFFER_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Exception.h>
+#include <asura-base/type.h>
+
+#include "GfxDevice.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+enum BufferType
+{
+ BUFFER_TYPE_VERTEX, ///< 㻺壬position\tangent\normal\color\texcoord(n)
+ BUFFER_TYPE_INDEX, ///<
+};
+
+enum BufferUsage
+{
+ BUFFER_USAGE_STREAM, ///< ޸һΣʹô
+ BUFFER_USAGE_DYNAMIC, ///< ޸һΣʹ
+ BUFFER_USAGE_STATIC, ///< ޸ĺʹ
+};
+
+enum BufferDataType
+{
+ BUFFER_DATA_TYPE_INT,
+ BUFFER_DATA_TYPE_FLOAT,
+ BUFFER_DATA_TYPE_UNSIGNED_BYTE,
+};
+
+///
+/// VRAM壬ֶ㻺vboebo֣ÿζڴԴϴݡframeworkrenderersй
+///
+ASURA_ABSTRACT class GPUBuffer
+{
+public:
+
+ GPUBuffer(BufferType type, BufferUsage usage, BufferDataType datatype, size_t size);
+ virtual ~GPUBuffer();
+
+ static size_t GetDataTypeSize(GLenum datatype);
+
+ bool Fill(const void* data, size_t size, uint offset = 0) ASURA_THROW(Exception);
+
+ void Bind();
+ void UnBind();
+
+ uint GetBufferSize();
+ uint GetBufferCount();
+ GLenum GetDataType();
+ size_t GetDataTypeSize();
+
+private:
+
+ GLenum ConvertBufferType(BufferType type);
+ GLenum ConvertBufferUsage(BufferUsage type);
+ GLenum ConvertBufferDataType(BufferDataType type);
+
+ GLenum m_Target;
+ GLuint m_Buffer;
+
+ /// openglԴ滺岢ûж͵ҪֻglVertexAttribPointerʱָdrawcall ʱݸ
+ /// ʼַʹbufferȡඥݣԲͬͿԱһbufferСΪ˱ֽӿڵļ࣬
+ /// ʼbufferʱָͣڱ͵һ£Բͬͷͬbuffer
+
+ GLenum m_DataType;
+ GLuint m_Usage;
+ uint m_Size;
+
+#if ASURA_DEBUG
+ byte* m_Data;
+#endif
+
+luaxport:
+
+ LUAX_DECL_ABSTRACT_FACTORY(GPUBuffer);
+
+ LUAX_DECL_ENUM(BufferType, 1);
+ LUAX_DECL_ENUM(BufferUsage, 1);
+ LUAX_DECL_ENUM(BufferDataType, 2);
+
+ LUAX_DECL_METHOD(_Fill);
+ LUAX_DECL_METHOD(_GetSize);
+ LUAX_DECL_METHOD(_GetCount);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/GfxDevice.cpp b/Source/modules/asura-core/Graphics/GfxDevice.cpp
new file mode 100644
index 0000000..529a76c
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GfxDevice.cpp
@@ -0,0 +1,188 @@
+#include <asura-base/type.h>
+
+#include "../CoreConfig.h"
+
+#include "GfxDevice.h"
+#include "Shader.h"
+#include "MatrixStack.h"
+#include "Color.h"
+
+using namespace AEMath;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+#if ASURA_DEBUG
+static bool instantiated = false;
+#endif
+
+GfxDevice g_Device;
+
+GfxDevice::GfxDevice()
+{
+#if ASURA_DEBUG
+ ASSERT(!instantiated);
+ instantiated = true;
+#endif
+}
+
+GfxDevice::~GfxDevice()
+{
+}
+
+GfxDevice& GfxDevice::Get()
+{
+ return g_Device;
+}
+
+static bool inited = false;
+
+bool GfxDevice::Init(const AEMath::Recti& view)
+{
+ bool loaded = false;
+#if ASURA_OPENGL_LOADER & ASURA_OPENGL_GLAD
+ if (!loaded)
+ loaded = gladLoadGL();
+#endif
+ if (!loaded)
+ return false;
+ SetViewport(view);
+
+ inited = true;
+ return true;
+}
+
+bool GfxDevice::Inited()
+{
+ return inited;
+}
+
+void GfxDevice::WipeError()
+{
+ while (glGetError() != GL_NO_ERROR);
+}
+
+bool GfxDevice::HasError()
+{
+ return glGetError() != GL_NO_ERROR;
+}
+
+GLenum GfxDevice::GetError()
+{
+ return glGetError();
+}
+
+void GfxDevice::SetDrawColor(float r, float g, float b, float a)
+{
+ state.drawColor.Set(r, g, b, a);
+}
+
+Color& GfxDevice::GetDrawColor()
+{
+ return state.drawColor;
+}
+
+void GfxDevice::SetViewport(const Recti v)
+{
+ state.viewport = v;
+ glViewport(v.x, v.y, v.w, v.h);
+}
+
+const Recti& GfxDevice::GetViewport()
+{
+ return state.viewport;
+}
+
+void GfxDevice::SetActiveShader(Shader* shader)
+{
+ if (state.shader == shader)
+ return;
+ if (state.shader)
+ state.shader->OnDisable();
+ state.shader = shader;
+ if (shader)
+ {
+ GLint program = shader->GetGLProgram();
+ glUseProgram(program);
+#if ASURA_GL_PROFILE
+ ++stats.shaderSwitch;
+#endif
+ shader->OnEnable();
+ }
+}
+
+Shader* GfxDevice::GetActiveShader() const
+{
+ return state.shader;
+}
+
+void GfxDevice::DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ glDrawArrays(mode, first, count);
+#if ASURA_GL_PROFILE
+ ++stats.drawCall;
+#endif
+ if (state.shader)
+ state.shader->OnUsed();
+}
+
+void GfxDevice::PushMatrix ()
+{
+ state.matrix[state.matrixMode].Push ();
+}
+
+void GfxDevice::PopMatrix ()
+{
+ state.matrix[state.matrixMode].Pop();
+}
+
+void GfxDevice::LoadIdentity()
+{
+ state.matrix[state.matrixMode].LoadIdentity();
+}
+
+void GfxDevice::Rotate (float angle)
+{
+ state.matrix[state.matrixMode].Rotate(angle);
+}
+
+void GfxDevice::Translate (float x, float y)
+{
+ state.matrix[state.matrixMode].Translate(x, y);
+}
+
+void GfxDevice::Scale (float x, float y)
+{
+ state.matrix[state.matrixMode].Scale(x, y);
+}
+
+void GfxDevice::Ortho(float l, float r, float b, float t, float n, float f)
+{
+ state.matrix[state.matrixMode].Ortho(l, r, b, t, n, f);
+}
+
+AEMath::Matrix44& GfxDevice::GetMatrix(MatrixMode mode)
+{
+ return state.matrix[mode].GetTop();
+}
+
+AEMath::Matrix44 GfxDevice::GetMVPMatrix()
+{
+ return state.matrix[MATRIX_MODE_PROJECTION].GetTop()
+ * state.matrix[MATRIX_MODE_VIEW].GetTop()
+ * state.matrix[MATRIX_MODE_MODEL].GetTop();
+}
+
+uint GfxDevice::GetMatrixDepth()
+{
+ return state.matrix[state.matrixMode].GetCapacity();
+}
+
+uint GfxDevice::GetMatrixIndex()
+{
+ return state.matrix[state.matrixMode].GetTopIndex();
+}
+
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/GfxDevice.h b/Source/modules/asura-core/Graphics/GfxDevice.h
new file mode 100644
index 0000000..2b105df
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GfxDevice.h
@@ -0,0 +1,141 @@
+#ifndef _ASURA_ENGINE_GFX_DEVICE_H_
+#define _ASURA_ENGINE_GFX_DEVICE_H_
+
+#include <stack>
+
+#include <glad/glad.h>
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Math/Rect.hpp>
+#include <asura-base/Math/matrix44.h>
+#include <asura-base/Math/vector4.h>
+
+#include "Color.h"
+#include "MatrixStack.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class Profiler;
+class Shader;
+class GPUBuffer;
+class Canvas;
+
+enum MatrixMode
+{
+ MATRIX_MODE_PROJECTION = 0,
+ MATRIX_MODE_MODEL = 1,
+ MATRIX_MODE_VIEW = 2,
+};
+
+enum GLParams
+{
+ GL_PARAM_MAX_TEXTURE_UNIT = 1,
+};
+
+class GfxDevice : public AEScripting::Portable<GfxDevice>
+{
+public:
+
+ GfxDevice();
+ ~GfxDevice();
+
+ static GfxDevice& Get();
+
+ int GetParam(GLParams param);
+
+ bool Init(const AEMath::Recti& viewport);
+ bool Inited();
+
+ void SetViewport(const AEMath::Recti viewport);
+
+ const AEMath::Recti& GetViewport();
+
+ void PushMatrix();
+ void PopMatrix();
+
+ void LoadIdentity();
+ void Rotate(float angle);
+ void Translate(float x, float y);
+ void Scale(float x, float y);
+ void Ortho(float l, float r, float b, float t, float n, float f);
+
+ uint GetMatrixDepth();
+ uint GetMatrixIndex();
+
+ void DrawArrays(GLenum mode, GLint first, GLsizei count);
+
+ AEMath::Matrix44& GetMatrix(MatrixMode mode);
+ AEMath::Matrix44 GetMVPMatrix();
+
+ void SetDrawColor(float r, float g, float b, float a);
+ Color& GetDrawColor();
+
+ void SetActiveShader(Shader* = NULL);
+ Shader* GetActiveShader() const;
+
+ void WipeError();
+ bool HasError();
+ GLenum GetError();
+
+ GET_SET(MatrixMode, MatrixMode, state.matrixMode);
+ GET_SET(Canvas*, ActiveCanvas, state.canvas);
+
+private:
+
+ friend class Profiler;
+
+ struct
+ {
+ AEMath::Recti viewport; ///< ǰлHDC߱ڴСı߲ˢʱ䶯
+ MatrixStack matrix[3]; ///< model, view, projection
+ MatrixMode matrixMode; ///< ǰľ
+ Color drawColor; ///< Ƶɫ
+ Canvas* canvas; ///< ǰcanvas
+ Shader* shader; ///< ǰʹõshader
+ } state;
+
+#if ASURA_GL_PROFILE
+ struct
+ {
+ uint drawCall; ///< ͳdrawcall
+ uint canvasSwitch; ///< лtextureĴ
+ uint shaderSwitch; ///< лshaderĴ
+ } stats;
+#endif
+
+luaxport:
+
+ LUAX_DECL_SINGLETON(GfxDevice);
+
+ LUAX_DECL_ENUM(MatrixMode, 1);
+ LUAX_DECL_ENUM(GLParams, 1);
+
+ LUAX_DECL_METHOD(_SetMatrixMode);
+ LUAX_DECL_METHOD(_GetMatrixMode);
+ LUAX_DECL_METHOD(_PushMatrix);
+ LUAX_DECL_METHOD(_PopMatrix);
+ LUAX_DECL_METHOD(_LoadIdentity);
+ LUAX_DECL_METHOD(_Rotate);
+ LUAX_DECL_METHOD(_Translate);
+ LUAX_DECL_METHOD(_Scale);
+ LUAX_DECL_METHOD(_Ortho);
+ LUAX_DECL_METHOD(_GetMatrixDepth);
+ LUAX_DECL_METHOD(_GetMatrixIndex);
+ LUAX_DECL_METHOD(_UseShader);
+ LUAX_DECL_METHOD(_UnuseShader);
+
+};
+
+extern GfxDevice g_Device;
+
+
+#define GL_CALL(x) do { x; /*GLAssert(); */} while(0)
+
+
+
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/GraphicsHelper.cpp b/Source/modules/asura-core/Graphics/GraphicsHelper.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GraphicsHelper.cpp
diff --git a/Source/modules/asura-core/Graphics/GraphicsHelper.h b/Source/modules/asura-core/Graphics/GraphicsHelper.h
new file mode 100644
index 0000000..3125292
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/GraphicsHelper.h
@@ -0,0 +1,15 @@
+#ifndef _ASURA_GRAPHICS_HELPER_H_
+#define _ASURA_GRAPHICS_HELPER_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+
+
+namespace_end
+namespace_end
+
+#endif
diff --git a/Source/modules/asura-core/Graphics/Image.cpp b/Source/modules/asura-core/Graphics/Image.cpp
new file mode 100644
index 0000000..36d2478
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Image.cpp
@@ -0,0 +1,103 @@
+#include <asura-base/Exception.h>
+
+#include "../CoreConfig.h"
+
+#include "Shader.h"
+#include "Image.h"
+#include "GfxDevice.h"
+
+using namespace AEFileSystem;
+using namespace AEImage;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+Image::Image()
+ : m_Width(0)
+ , m_Height(0)
+{
+}
+
+Image::~Image()
+{
+}
+
+bool Image::Load(ImageData* imgData)
+{
+ if (!imgData) return false;
+
+ if (m_TexID == 0)
+ {
+ glGenTextures(1, &m_TexID);
+ if (m_TexID == 0)
+ throw Exception("OpenGL glGenTextures failed.");
+ }
+
+ glBindTexture(GL_TEXTURE_2D, m_TexID);
+ imgData->Lock();
+ int width = imgData->width;
+ int height = imgData->height;
+ TextureFormat tf = ConvertColorFormat(imgData->format);
+ glTexImage2D(
+ GL_TEXTURE_2D
+ , 0
+ , tf.internalformat
+ , width, height
+ , 0
+ , tf.externalformat
+ , tf.type
+ , imgData->pixels
+ );
+
+ m_Width = imgData->width;
+ m_Height = imgData->height;
+ imgData->Unlock();
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR)
+ throw Exception("OpenGL glTexImage2D cause error, error code=%d", err);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+bool Image::Load(ImageData* imgData, const AEMath::Vector2i& pos)
+{
+ if (!imgData) return false;
+
+ glBindTexture(GL_TEXTURE_2D, m_TexID);
+ imgData->Lock();
+ int width = imgData->width;
+ int height = imgData->height;
+ TextureFormat tf = ConvertColorFormat(imgData->format);
+ glTexSubImage2D(
+ GL_TEXTURE_2D
+ , 0
+ , pos.x
+ , pos.y
+ , imgData->width
+ , imgData->height
+ , tf.externalformat
+ , tf.type
+ , imgData->pixels
+ );
+ imgData->Unlock();
+ GLenum err = glGetError();
+ if (err != GL_NO_ERROR)
+ throw Exception("OpenGL glTexSubImage2D cause error, error code=%d", err);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+uint32 Image::GetWidth()
+{
+ return m_Width;
+}
+
+uint32 Image::GetHeight()
+{
+ return m_Height;
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Image.h b/Source/modules/asura-core/Graphics/Image.h
new file mode 100644
index 0000000..a76d06f
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Image.h
@@ -0,0 +1,63 @@
+#ifndef _ASURA_ENGINE_IMAGE_H_
+#define _ASURA_ENGINE_IMAGE_H_
+
+// asura modules
+#include <asura-base/Math/Rect.hpp>
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/FileSystem/Renewable.h>
+#include <asura-base/Utilities/Stringmap.hpp>
+#include <asura-base/Manager.hpp>
+
+// module
+#include "../Image/ImageData.h"
+
+// folder
+#include "Color.h"
+#include "Color32.h"
+#include "RenderState.h"
+#include "GPUBuffer.h"
+#include "Texture.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class Image ASURA_FINAL : public AEScripting::Portable<Image, Texture>
+{
+public:
+
+ Image();
+ ~Image();
+
+ bool Load(AEImage::ImageData* decodeData);
+ bool Load(AEImage::ImageData* decodeData, const AEMath::Vector2i& pos);
+
+ uint GetWidth();
+ uint GetHeight();
+
+ GPUBuffer* GenGPUBuffer();
+
+private:
+
+ uint32 m_Width, m_Height;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Image, Texture);
+
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_Load);
+ LUAX_DECL_METHOD(_GetWidth);
+ LUAX_DECL_METHOD(_GetHeight);
+ LUAX_DECL_METHOD(_GetSize);
+ LUAX_DECL_METHOD(_GetPixel);
+ LUAX_DECL_METHOD(_Render);
+
+};
+
+namespace_end
+namespace_end
+
+namespace AEGraphics = AsuraEngine::Graphics;
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/IndexBuffer.cpp b/Source/modules/asura-core/Graphics/IndexBuffer.cpp
new file mode 100644
index 0000000..bb3eea7
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/IndexBuffer.cpp
@@ -0,0 +1,17 @@
+#include "IndexBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+IndexBuffer::IndexBuffer(BufferUsage usage, BufferDataType datatype, size_t size)
+ : GPUBuffer(BUFFER_TYPE_INDEX, usage, datatype, size)
+{
+}
+
+IndexBuffer::~IndexBuffer()
+{
+}
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Graphics/IndexBuffer.h b/Source/modules/asura-core/Graphics/IndexBuffer.h
new file mode 100644
index 0000000..b7886b7
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/IndexBuffer.h
@@ -0,0 +1,34 @@
+#ifndef _ASURA_INDEX_BUFFER_H_
+#define _ASURA_INDEX_BUFFER_H_
+
+#include <asura-base/Scripting/Scripting.h>
+
+#include "GPUBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+///
+///
+class IndexBuffer ASURA_FINAL
+ : public AEScripting::Portable<IndexBuffer>
+ , public GPUBuffer
+{
+public:
+
+ IndexBuffer(BufferUsage usage, BufferDataType datatype, size_t size);
+ ~IndexBuffer();
+
+luaxport:
+
+ LUAX_DECL_FACTORY(IndexBuffer);
+
+ LUAX_DECL_METHOD(_New);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/MatrixStack.cpp b/Source/modules/asura-core/Graphics/MatrixStack.cpp
new file mode 100644
index 0000000..987d29c
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/MatrixStack.cpp
@@ -0,0 +1,75 @@
+#include "MatrixStack.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+MatrixStack::MatrixStack()
+ : top(0)
+{
+ // ջʼջô˱֤ջԶǿգȡֵ
+ m_Stack[top].SetIdentity();
+}
+
+MatrixStack::~MatrixStack()
+{
+}
+
+void MatrixStack::LoadIdentity()
+{
+ m_Stack[top].SetIdentity();
+}
+
+bool MatrixStack::Push()
+{
+ if (top == ASURA_MAX_MATRIX_STACK_DEPTH - 1)
+ return false;
+ ++top;
+ m_Stack[top] = m_Stack[top - 1];
+ return true;
+}
+
+bool MatrixStack::Pop()
+{
+ if (top == 0)
+ return false;
+ --top;
+ return true;
+}
+
+AEMath::Matrix44& MatrixStack::GetTop()
+{
+ return m_Stack[top];
+}
+
+uint MatrixStack::GetTopIndex()
+{
+ return top;
+}
+
+uint MatrixStack::GetCapacity()
+{
+ return ASURA_MAX_MATRIX_STACK_DEPTH;
+}
+
+void MatrixStack::Ortho(float left, float right, float bottom, float top, float near, float far)
+{
+ m_Stack[this->top].Ortho(left, right, bottom, top, near, far);
+}
+
+void MatrixStack::Rotate(float angle)
+{
+ m_Stack[top].Rotate(angle);
+}
+
+void MatrixStack::Translate(float x, float y)
+{
+ m_Stack[top].Translate(x, y);
+}
+
+void MatrixStack::Scale(float x, float y)
+{
+ m_Stack[top].Scale(x, y);
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/MatrixStack.h b/Source/modules/asura-core/Graphics/MatrixStack.h
new file mode 100644
index 0000000..8dd56bf
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/MatrixStack.h
@@ -0,0 +1,58 @@
+#ifndef _ASURA_MATRIX_STACK_H_
+#define _ASURA_MATRIX_STACK_H_
+
+#include <asura-base/Type.h>
+#include <asura-base/Math/Matrix44.h>
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// ջľȡ
+///
+#define ASURA_MAX_MATRIX_STACK_DEPTH 32 // 2KB
+
+///
+/// ջ״ָ̬֮ǰ״̬ջеһstack[i]ֵstack[0]*..*stack[i-1]
+/// ֵһϵtransform
+///
+/// TODO: template<uint _capacity> MatrixStack
+///
+class MatrixStack
+{
+public:
+
+ MatrixStack();
+ ~MatrixStack();
+
+ void LoadIdentity();
+ bool Push();
+ bool Pop();
+
+ AEMath::Matrix44& GetTop();
+ void GetTop(ASURA_OUT AEMath::Matrix44& mat44);
+
+ void LoadMatrix(const AEMath::Matrix44& mat44);
+ void MultMatrix(const AEMath::Matrix44& mat44);
+
+ void Rotate(float angle);
+ void Translate(float x, float y);
+ void Scale(float x, float y);
+
+ void Ortho(float l, float r, float b, float t, float n, float f);
+
+ uint GetTopIndex();
+ uint GetCapacity();
+
+private:
+
+ AEMath::Matrix44 m_Stack[ASURA_MAX_MATRIX_STACK_DEPTH];
+ uint8 top;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Mesh2D.cpp b/Source/modules/asura-core/Graphics/Mesh2D.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Mesh2D.cpp
diff --git a/Source/modules/asura-core/Graphics/Mesh2D.h b/Source/modules/asura-core/Graphics/Mesh2D.h
new file mode 100644
index 0000000..7a0f62e
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Mesh2D.h
@@ -0,0 +1,52 @@
+#ifndef _ASURA_ENGINE_MESH2D_H__
+#define _ASURA_ENGINE_MESH2D_H__
+
+// cpp
+#include <vector>
+
+// asura modules
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Math/Vector2.hpp>
+
+// module
+#include "../Mesh/Mesh2dData.h"
+
+// folder
+#include "Color.h"
+#include "VertexBuffer.h"
+#include "IndexBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// 2D meshһЩ㶯
+/// https://en.wikipedia.org/wiki/Polygon_mesh
+///
+class Mesh2D ASURA_FINAL
+ : public Scripting::Portable<Mesh2D>
+{
+public:
+
+ Mesh2D();
+ ~Mesh2D();
+
+ bool Load(AEMesh::Mesh2DData* data);
+
+private:
+
+ VertexBuffer* m_VBO; ///< vertex buffer
+ IndexBuffer* m_IBO; ///< index buffer
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Mesh2D);
+
+ LUAX_DECL_METHOD(_SetVertex);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Polygon2D.cpp b/Source/modules/asura-core/Graphics/Polygon2D.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Polygon2D.cpp
diff --git a/Source/modules/asura-core/Graphics/Polygon2D.h b/Source/modules/asura-core/Graphics/Polygon2D.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Polygon2D.h
diff --git a/Source/modules/asura-core/Graphics/Quad.cpp b/Source/modules/asura-core/Graphics/Quad.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Quad.cpp
diff --git a/Source/modules/asura-core/Graphics/Quad.h b/Source/modules/asura-core/Graphics/Quad.h
new file mode 100644
index 0000000..b7dd3d9
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Quad.h
@@ -0,0 +1 @@
+// Quadrectڣrectǵıƫᣬquadһ
diff --git a/Source/modules/asura-core/Graphics/RenderState.h b/Source/modules/asura-core/Graphics/RenderState.h
new file mode 100644
index 0000000..23804d8
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/RenderState.h
@@ -0,0 +1,47 @@
+#ifndef _ASURA_ENGINE_RENDER_STATE_H_
+#define _ASURA_ENGINE_RENDER_STATE_H_
+
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Math/Transform.h>
+
+#include "BlendMode.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class Shader;
+
+///
+/// Ⱦǰķʽ
+///
+struct RenderState ASURA_FINAL
+{
+ ///
+ /// Ĭϵrender state
+ ///
+ static RenderState Default;
+
+ RenderState();
+ ~RenderState();
+
+ ///
+ /// λášλúת
+ ///
+ Math::Transform transform;
+
+ ///
+ /// ɫ
+ ///
+ Shader* shader;
+
+ ///
+ /// Ϸʽ
+ ///
+ BlendMode blendMode;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/RenderTarget.cpp b/Source/modules/asura-core/Graphics/RenderTarget.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/RenderTarget.cpp
diff --git a/Source/modules/asura-core/Graphics/RenderTarget.h b/Source/modules/asura-core/Graphics/RenderTarget.h
new file mode 100644
index 0000000..ab09e35
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/RenderTarget.h
@@ -0,0 +1,52 @@
+#ifndef _ASURA_ENGINE_RENDERTARGET_H_
+#define _ASURA_ENGINE_RENDERTARGET_H_
+
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Math/Rect.hpp>
+#include <asura-base/Scripting/Scripting.h>
+
+#include "Texture.h"
+#include "Color.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// ɱΪȾĿ࣬
+/// Canvas(RenderTexture)
+/// Window(RenderWindow)
+///
+class RenderTarget : public AEScripting::Object
+{
+public:
+
+ RenderTarget() {};
+
+ virtual ~RenderTarget() {};
+
+ ///
+ /// ɫcolRT
+ ///
+ virtual void Clear(const Color& col = Color::Black) = 0;
+
+ ///
+ /// ɫcolղRT
+ ///
+ virtual void Clear(const Math::Recti& quad, const Color& col = Color::Black) = 0;
+
+ ///
+ /// textureRT
+ ///
+ virtual void Draw(const Drawable* texture, const RenderState& state) = 0;
+
+ ///
+ /// һtextureRT
+ ///
+ virtual void Draw(const Drawable* texture, const Math::Recti& quad, const RenderState& state) = 0;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Shader.cpp b/Source/modules/asura-core/Graphics/Shader.cpp
new file mode 100644
index 0000000..329b3f1
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Shader.cpp
@@ -0,0 +1,282 @@
+#include <asura-base/Exception.h>
+
+#include "GfxDevice.h"
+#include "Shader.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+// texture unit
+static uint8 texUnit = 0;
+
+Shader::Shader()
+{
+}
+
+Shader::~Shader()
+{
+ if(m_VertShader) glDeleteShader(m_VertShader);
+ if(m_FragShader) glDeleteShader(m_FragShader);
+ if(m_Program) glDeleteProgram(m_Program);
+}
+
+void Shader::SetActive(Shader* shader)
+{
+ g_Device.SetActiveShader(shader);
+}
+
+Shader* Shader::GetActive()
+{
+ return g_Device.GetActiveShader();
+}
+
+bool Shader::Load(const string& vert, const string& frag)
+{
+ string warnning = "";
+
+ if (!m_Program)
+ {
+ m_Program = glCreateProgram();
+ if (!m_Program)
+ throw Exception("Cannot create OpenGL shader program.");
+ }
+
+ if (!CompileVertexShader(vert, warnning))
+ {
+ throw Exception("Compile vertex shader failed:%s", warnning);
+ }
+
+ if (!CompileFragementShader(frag, warnning))
+ {
+ throw Exception("Compile fragment shader failed:%s", warnning);
+ }
+
+ glAttachShader(m_Program, m_VertShader);
+ glAttachShader(m_Program, m_FragShader);
+
+ glLinkProgram(m_Program);
+ GLint success;
+ glGetProgramiv(m_Program, GL_LINK_STATUS, &success);
+ if (success == GL_FALSE)
+ {
+ warnning = GetProgramWarnings();
+ throw Exception("Link shader program failed:\n%s", warnning.c_str());
+ }
+
+ return true;
+}
+
+bool Shader::CompileVertexShader(const string& vert, string& outError)
+{
+ if (!m_VertShader)
+ {
+ m_VertShader = glCreateShader(GL_VERTEX_SHADER);
+ if (!m_VertShader)
+ {
+ outError = "Cannot create OpenGL Vertex shader.";
+ return false;
+ }
+ }
+
+ const GLchar* source = vert.c_str();
+ GLint success;
+
+ glShaderSource(m_VertShader, 1, &source, NULL);
+ glCompileShader(m_VertShader);
+ glGetShaderiv(m_VertShader, GL_COMPILE_STATUS, &success);
+ if (success == GL_FALSE)
+ {
+ outError = GetShaderWarnings(m_VertShader);
+ return false;
+ }
+
+ return true;
+}
+
+bool Shader::CompileFragementShader(const string& frag, string& outError)
+{
+ if (!m_FragShader)
+ {
+ m_FragShader = glCreateShader(GL_FRAGMENT_SHADER);
+ if (!m_FragShader)
+ {
+ outError = "Cannot create OpenGL fragment shader.";
+ return false;
+ }
+ }
+
+ const GLchar* source = frag.c_str();
+ GLint success;
+
+ source = frag.c_str();
+ glShaderSource(m_FragShader, 1, &source, NULL);
+ glCompileShader(m_FragShader);
+ glGetShaderiv(m_FragShader, GL_COMPILE_STATUS, &success);
+ if (success == GL_FALSE)
+ {
+ outError = GetShaderWarnings(m_FragShader);
+ return false;
+ }
+
+ return true;
+}
+
+void Shader::OnEnable()
+{
+ texUnit = 0;
+}
+
+void Shader::OnDisable()
+{
+ texUnit = 0;
+}
+
+void Shader::OnUsed()
+{
+ texUnit = 0;
+}
+
+uint Shader::GetUniformLocation(const std::string& uniform)
+{
+ GLint loc = glGetUniformLocation(m_Program, uniform.c_str());
+ return loc;
+}
+
+bool Shader::HasUniform(const std::string& uniform)
+{
+ GLint loc = glGetUniformLocation(m_Program, uniform.c_str());
+ return loc != -1;
+}
+
+GLuint Shader::GetGLProgram()
+{
+ return m_Program;
+}
+
+void Shader::SetUniformFloat(uint loc, float value)
+{
+ if(g_Device.GetActiveShader() == this)
+ glUniform1f(loc, value);
+}
+
+bool Shader::SetUniformTexture(uint loc, const Texture& texture)
+{
+ if (g_Device.GetActiveShader() != this)
+ return false;
+
+ g_Device.WipeError();
+ glActiveTexture(GL_TEXTURE0 + texUnit);
+ if (g_Device.HasError())
+ return false;
+ GLint tex = texture.GetGLTexture();
+ glBindTexture(GL_TEXTURE_2D, tex);
+ if (g_Device.HasError())
+ return false;
+ glUniform1i(loc, texUnit);
+ if (g_Device.HasError())
+ return false;
+ ++texUnit;
+}
+
+void Shader::SetUniformVector2(uint loc, const Math::Vector2f& vec2)
+{
+ if (g_Device.GetActiveShader() == this)
+ glUniform2f(loc, vec2.x, vec2.y);
+}
+
+void Shader::SetUniformVector3(uint loc, const Math::Vector3f& vec3)
+{
+ if (g_Device.GetActiveShader() == this)
+ glUniform3f(loc, vec3.x, vec3.y, vec3.z);
+}
+
+void Shader::SetUniformVector4(uint loc, const Math::Vector4f& vec4)
+{
+ if (g_Device.GetActiveShader() == this)
+ glUniform4f(loc, vec4.x, vec4.y, vec4.z, vec4.w);
+}
+
+void Shader::SetUniformMatrix44(uint loc, const Math::Matrix44& mat)
+{
+ if (g_Device.GetActiveShader() == this)
+ glUniformMatrix4fv(loc, 1, GL_FALSE, mat.GetElements());
+}
+
+void Shader::SetUniformColor(uint loc, const Color& color)
+{
+ if (g_Device.GetActiveShader() == this)
+ glUniform4f(loc, color.r, color.g, color.b, color.a);
+}
+
+uint Shader::GetGLTextureUnitCount()
+{
+ GLint maxTextureUnits;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
+ return (uint)maxTextureUnits;
+}
+
+std::string Shader::GetProgramWarnings()
+{
+ GLint strsize, nullpos;
+ glGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &strsize);
+
+ if (strsize == 0)
+ return "";
+
+ char *tempstr = new char[strsize];
+
+ memset(tempstr, '\0', strsize);
+ glGetProgramInfoLog(m_Program, strsize, &nullpos, tempstr);
+ tempstr[nullpos] = '\0';
+
+ std::string warnings(tempstr);
+ delete[] tempstr;
+
+ return warnings;
+}
+
+std::string Shader::GetShaderWarnings(GLuint shader)
+{
+ GLint strsize, nullpos;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &strsize);
+
+ if (strsize == 0)
+ return "";
+
+ char *tempstr = new char[strsize];
+
+ memset(tempstr, '\0', strsize);
+ glGetShaderInfoLog(shader, strsize, &nullpos, tempstr);
+ tempstr[nullpos] = '\0';
+
+ std::string warnings(tempstr);
+ delete[] tempstr;
+
+ return warnings;
+}
+
+void Shader::SetAttribute(int loc, VertexBuffer* vbo, uint offseti, uint stridei, bool normalized)
+{
+ GLsizei offset = offseti * vbo->GetDataTypeSize();
+ GLsizei stride = stridei * vbo->GetDataTypeSize();
+ glEnableVertexAttribArray(loc);
+ vbo->Bind();
+ glVertexAttribPointer(loc, 2, vbo->GetDataType(), normalized, stride, (GLvoid*)offset);
+ vbo->UnBind();
+}
+
+int Shader::GetAttributeLocation(const std::string& attribute)
+{
+ int loc = glGetAttribLocation(m_Program, attribute.c_str());
+ return loc;
+}
+
+void Shader::DisableAttribute(int loc)
+{
+ glDisableVertexAttribArray(loc);
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Shader.h b/Source/modules/asura-core/Graphics/Shader.h
new file mode 100644
index 0000000..615b028
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Shader.h
@@ -0,0 +1,117 @@
+#ifndef _ASURA_ENGINE_SHADER_H_
+#define _ASURA_ENGINE_SHADER_H_
+
+#include <map>
+#include <string>
+
+#include <asura-base/Exception.h>
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/FileSystem/Renewable.h>
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Math/vector3.hpp>
+#include <asura-base/Math/vector4.h>
+#include <asura-base/Math/matrix44.h>
+#include <asura-base/Utilities/Stringmap.hpp>
+#include <asura-base/Manager.hpp>
+
+#include "GfxDevice.h"
+#include "Color.h"
+#include "Texture.h"
+#include "VertexBuffer.h"
+#include "IndexBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// һshaderһڲʼ乲ijShaderuniformsͶݣֻṩ uniformsuseɫ
+/// ķ༭ÿshaderͨshaderҵuniforms¶frameworkmaterial
+/// á
+///
+class Shader ASURA_FINAL
+ : public Scripting::Portable<Shader>
+ , public AEFileSystem::Renewable
+{
+public:
+
+ Shader();
+
+ ~Shader();
+
+ static void SetActive(Shader* shader);
+ static Shader* GetActive();
+
+ bool Load(const std::string& vert, const std::string& frag) ASURA_THROW(Exception);
+
+ // ʹSetActiveлshaderʱ
+ void OnEnable();
+ void OnDisable();
+ // Draw call֮
+ void OnUsed();
+
+ void SetAttribute(int loc, VertexBuffer* vbo, uint offseti = 0, uint stridei = 0, bool normalized = false);
+ int GetAttributeLocation(const std::string& attribute);
+ void DisableAttribute(int loc);
+
+ bool HasUniform(const std::string& uniform);
+ uint GetUniformLocation(const std::string& uniform);
+ void SetUniformFloat(uint loc, float value);
+ void SetUniformVector2(uint loc, const Math::Vector2f& vec2);
+ void SetUniformVector3(uint loc, const Math::Vector3f& vec3);
+ void SetUniformVector4(uint loc, const Math::Vector4f& vec4);
+ void SetUniformColor(uint loc, const Color& color);
+ void SetUniformMatrix44(uint loc, const Math::Matrix44& mat44);
+ bool SetUniformTexture(uint loc, const Texture& texture);
+
+ float GetUniformFloat(uint loc);
+ AEMath::Vector2f GetUniformVector2(uint loc);
+ AEMath::Vector3f GetUniformVector3(uint loc);
+ AEMath::Vector4f GetUniformVector4s(uint loc);
+ AEMath::Matrix44 GetUniformMatrix44(uint loc);
+
+ GLuint GetGLProgram();
+
+ static uint GetGLTextureUnitCount();
+
+private:
+
+ bool CompileVertexShader(const std::string& vert, std::string& outError);
+ bool CompileFragementShader(const std::string& frag, std::string& outError);
+
+ std::string GetProgramWarnings();
+ std::string GetShaderWarnings(GLuint shader);
+
+ GLuint m_Program;
+ GLuint m_VertShader;
+ GLuint m_FragShader;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(Shader);
+
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_Load);
+ LUAX_DECL_METHOD(_Update);
+ LUAX_DECL_METHOD(_HasUniform);
+ LUAX_DECL_METHOD(_GetUniformLocation);
+ LUAX_DECL_METHOD(_SetUniformFloat);
+ LUAX_DECL_METHOD(_SetUniformTexture);
+ LUAX_DECL_METHOD(_SetUniformVector2);
+ LUAX_DECL_METHOD(_SetUniformVector3);
+ LUAX_DECL_METHOD(_SetUniformVector4);
+ LUAX_DECL_METHOD(_SetUniformColor);
+
+ LUAX_DECL_METHOD(_GetAttributeLocation);
+ LUAX_DECL_METHOD(_SetAttribute);
+ LUAX_DECL_METHOD(_DisableAttribute);
+
+ LUAX_DECL_METHOD(_SetBuiltInUniforms);
+
+};
+
+typedef Shader GpuProgram;
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Shape.cpp b/Source/modules/asura-core/Graphics/Shape.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Shape.cpp
diff --git a/Source/modules/asura-core/Graphics/Shape.h b/Source/modules/asura-core/Graphics/Shape.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Shape.h
diff --git a/Source/modules/asura-core/Graphics/SpriteBatch.cpp b/Source/modules/asura-core/Graphics/SpriteBatch.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/SpriteBatch.cpp
diff --git a/Source/modules/asura-core/Graphics/SpriteBatch.h b/Source/modules/asura-core/Graphics/SpriteBatch.h
new file mode 100644
index 0000000..30cb56c
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/SpriteBatch.h
@@ -0,0 +1,34 @@
+#ifndef _ASURA_ENGINE_SPRITE_BATCH_H_
+#define _ASURA_ENGINE_SPRITE_BATCH_H_
+
+#include <asura-base/Scripting/Scripting.h>
+
+#include "GPUBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// Sprite batchȾͼƬĵطϵͳ
+///
+class SpriteBatch ASURA_FINAL
+ : public Scripting::Portable<SpriteBatch>
+{
+public:
+
+ SpriteBatch();
+
+ ~SpriteBatch();
+
+private:
+
+luaxport:
+
+ LUAX_DECL_FACTORY(SpriteBatch);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Texture.cpp b/Source/modules/asura-core/Graphics/Texture.cpp
new file mode 100644
index 0000000..03f005d
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Texture.cpp
@@ -0,0 +1,47 @@
+#include <asura-base/Exception.h>
+
+#include "Texture.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+Texture::Texture()
+ : m_TexID(0)
+{
+}
+
+Texture::~Texture()
+{
+ // ͷԴ
+ if(m_TexID != 0)
+ glDeleteTextures(1, &m_TexID);
+}
+
+GLuint Texture::GetGLTexture() const
+{
+ return m_TexID;
+}
+
+TextureFormat Texture::ConvertColorFormat(const ColorFormat& colorformat)
+{
+ TextureFormat t;
+ switch (colorformat)
+ {
+ case COLOR_FORMAT_RGBA8:
+ t.internalformat = GL_RGBA8; // 4*sizeof(byte) ~= 4 bytes
+ t.externalformat = GL_RGBA;
+ t.type = GL_UNSIGNED_BYTE;
+ break;
+ case COLOR_FORMAT_RGBA32F:
+ t.internalformat = GL_RGBA32F; // 4*sizeof(float) = 16 bytes
+ t.externalformat = GL_RGBA;
+ t.type = GL_FLOAT;
+ break;
+ default:
+ ASSERT(false);
+ }
+ return t;
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/Texture.h b/Source/modules/asura-core/Graphics/Texture.h
new file mode 100644
index 0000000..76b9a8f
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/Texture.h
@@ -0,0 +1,101 @@
+#ifndef _ASURA_TEXTURE_H_
+#define _ASURA_TEXTURE_H_
+
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Math/Rect.hpp>
+
+#include "../CoreConfig.h"
+
+#include "RenderState.h"
+#include "GfxDevice.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+class RenderTarget;
+
+/// UVʽ
+enum WrapMode
+{
+ WRAP_MODE_REPEAT,
+ WRAP_MODE_MIRROR,
+ WRAP_MODE_CLAMPTOEDGE,
+ WRAP_MODE_CLAMPTOBORDER,
+};
+
+/// ˲ģʽ
+enum FilterMode
+{
+ FILTER_MODE_NEAREST,
+ FILTER_MODE_LINEAR,
+};
+
+/// ͼݵɫʽ
+enum ColorFormat
+{
+ COLOR_FORMAT_UNKNOWN,
+ COLOR_FORMAT_RGBA8, ///< RGBA8bits int
+ COLOR_FORMAT_RGBA32F, ///< RGBA32bits float
+};
+
+/// ʽGPUڲCPUⲿʽ
+struct TextureFormat
+{
+ GLenum internalformat; ///< GPUڲʽ
+ GLenum externalformat; ///< CPUⲿʽ
+ GLenum type; ///< ⲿʽÿchannelֵ
+};
+
+///
+/// 2D࣬2d meshrender targetбʹáTextureȾԭϽǣϷϲԵѿ
+/// ϵΪ׼EditorҲϽΪԭ㣬Ϊ˷㡣
+///
+ASURA_ABSTRACT class Texture : public AEScripting::Object
+{
+public:
+
+ LUAX_DECL_ABSTRACT_FACTORY(Texture);
+
+ Texture();
+ virtual ~Texture();
+
+ GLuint GetGLTexture() const;
+
+ void SetFilterMode(FilterMode min, FilterMode mag);
+ void SetWrapMode(WrapMode wrapMode);
+
+ void GetFilterMode();
+ void GetWrapMode();
+
+ /// UVfilterΪ
+ bool IsGenMipmap();
+
+protected:
+
+ /// תcolor formatΪtexture format
+ TextureFormat ConvertColorFormat(const ColorFormat& colorformat);
+
+ GLuint m_TexID;
+ FilterMode m_MinFilter;
+ FilterMode m_MagFilter;
+ WrapMode m_WrapMode;
+ bool m_IsGenMipmap;
+
+ LUAX_DECL_ENUM(ColorFormat, 1);
+ LUAX_DECL_ENUM(FilterMode, 1);
+ LUAX_DECL_ENUM(WrapMode, 1);
+
+ LUAX_DECL_METHOD(_SetFilterMode);
+ LUAX_DECL_METHOD(_SetWrapMode);
+ LUAX_DECL_METHOD(_GetFilterMode);
+ LUAX_DECL_METHOD(_GetWrapMode);
+ LUAX_DECL_METHOD(_IsGenMipmap);
+
+};
+
+typedef Texture Drawable;
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/VBO.cpp b/Source/modules/asura-core/Graphics/VBO.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/VBO.cpp
diff --git a/Source/modules/asura-core/Graphics/VBO.h b/Source/modules/asura-core/Graphics/VBO.h
new file mode 100644
index 0000000..f80991e
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/VBO.h
@@ -0,0 +1,27 @@
+#ifndef _ASURA_ENGINE_VBO_H_
+#define _ASURA_ENGINE_VBO_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+struct VertexBufferData
+{
+
+};
+
+struct IndexBufferData
+{
+
+};
+
+class VBO
+{
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/VertexBuffer.cpp b/Source/modules/asura-core/Graphics/VertexBuffer.cpp
new file mode 100644
index 0000000..c44e9be
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/VertexBuffer.cpp
@@ -0,0 +1,16 @@
+#include "VertexBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+VertexBuffer::VertexBuffer(BufferUsage usage, BufferDataType datatype, size_t size)
+ : GPUBuffer(BUFFER_TYPE_VERTEX, usage, datatype, size)
+{
+}
+
+VertexBuffer::~VertexBuffer()
+{
+}
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Graphics/VertexBuffer.h b/Source/modules/asura-core/Graphics/VertexBuffer.h
new file mode 100644
index 0000000..0622388
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/VertexBuffer.h
@@ -0,0 +1,34 @@
+#ifndef _ASURA_VERTEX_BUFFER_H_
+#define _ASURA_VERTEX_BUFFER_H_
+
+#include <asura-base/Scripting/Scripting.h>
+
+#include "GPUBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+///
+/// frameworkṩ˴Դ滺Ĺܣֱû壬ֱܶͨöݡ
+///
+class VertexBuffer ASURA_FINAL
+ : public AEScripting::Portable<VertexBuffer>
+ , public GPUBuffer
+{
+public:
+
+ VertexBuffer(BufferUsage usage, BufferDataType datatype, size_t size);
+ ~VertexBuffer();
+
+luaxport:
+
+ LUAX_DECL_FACTORY(VertexBuffer);
+
+ LUAX_DECL_METHOD(_New);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/binding/_canvas.cpp b/Source/modules/asura-core/Graphics/binding/_canvas.cpp
new file mode 100644
index 0000000..44841f5
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_canvas.cpp
@@ -0,0 +1,48 @@
+#include "../Canvas.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Canvas)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "SetSize", _SetSize },
+ { "Bind", _Bind },
+ { "Unbind", _Unbind }
+ );
+ }
+
+ LUAX_POSTPROCESS(Canvas)
+ {
+
+ }
+
+ // canvas:SetSize()
+ LUAX_IMPL_METHOD(Canvas, _SetSize)
+ {
+ LUAX_PREPARE(L, Canvas);
+ return 0;
+
+ }
+
+ // canvas:Bind()
+ LUAX_IMPL_METHOD(Canvas, _Bind)
+ {
+ LUAX_PREPARE(L, Canvas);
+
+ return 0;
+ }
+
+ // canvas:Unbind()
+ LUAX_IMPL_METHOD(Canvas, _Unbind)
+ {
+ LUAX_PREPARE(L, Canvas);
+ return 0;
+
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_color.cpp b/Source/modules/asura-core/Graphics/binding/_color.cpp
new file mode 100644
index 0000000..008d9c2
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_color.cpp
@@ -0,0 +1,130 @@
+#include "../Color.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+LUAX_REGISTRY(Color)
+{
+ LUAX_REGISTER_METHODS(state,
+ { "ToColor32", _ToColor32 },
+ { "SetColor", _SetColor },
+ { "GetColor", _GetColor },
+ { "GetR", _GetR },
+ { "GetG", _GetG },
+ { "GetB", _GetB },
+ { "GetA", _GetA },
+ { "__eq", ___eq },
+ { "__add", ___add },
+ { "__sub", ___sub },
+ { "__mul", ___mul },
+ { "__div", ___div }
+ );
+}
+
+LUAX_POSTPROCESS(Color)
+{
+
+}
+
+// color:ToColor32()
+LUAX_IMPL_METHOD(Color, _ToColor32)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:SetColor()
+LUAX_IMPL_METHOD(Color, _SetColor)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:GetColor()
+LUAX_IMPL_METHOD(Color, _GetColor)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:GetR()
+LUAX_IMPL_METHOD(Color, _GetR)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:GetG()
+LUAX_IMPL_METHOD(Color, _GetG)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:GetB()
+LUAX_IMPL_METHOD(Color, _GetB)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:GetA()
+LUAX_IMPL_METHOD(Color, _GetA)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:__eq()
+LUAX_IMPL_METHOD(Color, ___eq)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:__add()
+LUAX_IMPL_METHOD(Color, ___add)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:__sub()
+LUAX_IMPL_METHOD(Color, ___sub)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:__mul()
+LUAX_IMPL_METHOD(Color, ___mul)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+// color:__div()
+LUAX_IMPL_METHOD(Color, ___div)
+{
+ LUAX_PREPARE(L, Color);
+
+ return 0;
+}
+
+}
+} \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/binding/_color32.cpp b/Source/modules/asura-core/Graphics/binding/_color32.cpp
new file mode 100644
index 0000000..7613361
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_color32.cpp
@@ -0,0 +1,66 @@
+#include "../Color32.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Color32)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "ToColor", _ToColor },
+ { "GetRed", _GetRed },
+ { "GetGreen", _GetGreen },
+ { "GetBlue", _GetBlue },
+ { "GetAlpha", _GetAlpha }
+ );
+ }
+
+ LUAX_POSTPROCESS(Color32)
+ {
+
+ }
+
+ // color32:ToColor()
+ LUAX_IMPL_METHOD(Color32, _ToColor)
+ {
+ LUAX_PREPARE(L, Color32);
+ return 0;
+
+ }
+
+ // color32:GetRed()
+ LUAX_IMPL_METHOD(Color32, _GetRed)
+ {
+ LUAX_PREPARE(L, Color32);
+ return 0;
+ }
+
+ // color32:GetGreen()
+ LUAX_IMPL_METHOD(Color32, _GetGreen)
+ {
+ LUAX_PREPARE(L, Color32);
+
+ return 0;
+ }
+
+ // color32:GetBlue()
+ LUAX_IMPL_METHOD(Color32, _GetBlue)
+ {
+ LUAX_PREPARE(L, Color32);
+
+ return 0;
+ }
+
+ // color32:GetAlpha()
+ LUAX_IMPL_METHOD(Color32, _GetAlpha)
+ {
+ LUAX_PREPARE(L, Color32);
+
+ return 0;
+ }
+
+ }
+}
+ \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/binding/_gfx_device.cpp b/Source/modules/asura-core/Graphics/binding/_gfx_device.cpp
new file mode 100644
index 0000000..f6c2004
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_gfx_device.cpp
@@ -0,0 +1,151 @@
+#include "../GfxDevice.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(GfxDevice)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "SetMatrixMode", _SetMatrixMode },
+ { "GetMatrixMode", _GetMatrixMode },
+ { "PushMatrix", _PushMatrix },
+ { "PopMatrix", _PopMatrix },
+ { "LoadIdentity", _LoadIdentity },
+ { "Rotate", _Rotate },
+ { "Translate", _Translate },
+ { "Scale", _Scale },
+ { "Ortho", _Ortho },
+ { "GetMatrixDepth", _GetMatrixDepth },
+ { "GetMatrixIndex", _GetMatrixIndex },
+ { "UseShader", _UseShader },
+ { "UnuseShader", _UnuseShader }
+ );
+ }
+
+ LUAX_POSTPROCESS(GfxDevice)
+ {
+ LUAX_REGISTER_ENUM(state, "EMatrixMode",
+ { "PROJECTION", MATRIX_MODE_PROJECTION },
+ { "0", 0 },
+ { "MODEL", MATRIX_MODE_MODEL },
+ { "1", 1 },
+ { "VIEW", MATRIX_MODE_VIEW },
+ { "2", 2 }
+ );
+ LUAX_REGISTER_ENUM(state, "EGLParams",
+ { "MAX_TEXTURE_UNIT", GL_PARAM_MAX_TEXTURE_UNIT },
+ { "1", 1 }
+ );
+
+ }
+
+ // gfxdevice:SetMatrixMode()
+ LUAX_IMPL_METHOD(GfxDevice, _SetMatrixMode)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:GetMatrixMode()
+ LUAX_IMPL_METHOD(GfxDevice, _GetMatrixMode)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:PushMatrix()
+ LUAX_IMPL_METHOD(GfxDevice, _PushMatrix)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:PopMatrix()
+ LUAX_IMPL_METHOD(GfxDevice, _PopMatrix)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:LoadIdentity()
+ LUAX_IMPL_METHOD(GfxDevice, _LoadIdentity)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:Rotate()
+ LUAX_IMPL_METHOD(GfxDevice, _Rotate)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:Translate()
+ LUAX_IMPL_METHOD(GfxDevice, _Translate)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:Scale()
+ LUAX_IMPL_METHOD(GfxDevice, _Scale)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:Ortho()
+ LUAX_IMPL_METHOD(GfxDevice, _Ortho)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:GetMatrixDepth()
+ LUAX_IMPL_METHOD(GfxDevice, _GetMatrixDepth)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:GetMatrixIndex()
+ LUAX_IMPL_METHOD(GfxDevice, _GetMatrixIndex)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:UseShader()
+ LUAX_IMPL_METHOD(GfxDevice, _UseShader)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ // gfxdevice:UnuseShader()
+ LUAX_IMPL_METHOD(GfxDevice, _UnuseShader)
+ {
+ LUAX_PREPARE(L, GfxDevice);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_gpu_buffer.cpp b/Source/modules/asura-core/Graphics/binding/_gpu_buffer.cpp
new file mode 100644
index 0000000..8c39a59
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_gpu_buffer.cpp
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+
+#include "../image.h"
+#include "../GPUBuffer.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(GPUBuffer)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "Fill", _Fill },
+ { "GetSize", _GetSize },
+ { "GetCount", _GetCount }
+ );
+ }
+
+ LUAX_POSTPROCESS(GPUBuffer)
+ {
+ LUAX_REGISTER_ENUM(state, "EBufferType",
+ { "VERTEX", BUFFER_TYPE_VERTEX },
+ { "INDEX", BUFFER_TYPE_INDEX }
+ );
+ LUAX_REGISTER_ENUM(state, "EBufferUsage",
+ { "STREAM", BUFFER_USAGE_STREAM },
+ { "DYNAMIC", BUFFER_USAGE_DYNAMIC },
+ { "STATIC", BUFFER_USAGE_STATIC }
+ );
+ LUAX_REGISTER_ENUM(state, "EBufferDataType",
+ { "INT", BUFFER_DATA_TYPE_INT },
+ { "FLOAT", BUFFER_DATA_TYPE_FLOAT },
+ { "UNSIGNED_BYTE", BUFFER_DATA_TYPE_UNSIGNED_BYTE }
+ );
+
+ }
+
+ // buffer = GPUBuffer.New(bufferType, bufferUsage, bufferDataType, size)
+ // buffer = GPUBuffer.New(image)
+ // buffer = GPUBuffer.New(mesh2d)
+ // buffer = GPUBuffer.New(canvas)
+ // buffer = GPUBuffer.New(shape)
+ //LUAX_IMPL_METHOD(GPUBuffer, _New)
+ //{
+ // LUAX_STATE(L);
+
+ // return 0;
+ //}
+
+ // gpubuffer:Fill({data_unit_list}, offseti)
+ // data_unit_list ݵtable
+ // offseti : ʼǵĵطڵ(0ʼ
+ LUAX_IMPL_METHOD(GPUBuffer, _Fill)
+ {
+ LUAX_PREPARE(L, GPUBuffer);
+
+ // ʹbufferӦ޸bufferڵһεʱʼsizeСbufferȻ䡣
+ int offset = state.GetValue(3, 0);
+ int count = lua_objlen(L, 2);
+ int size = count * self->GetDataTypeSize();
+ byte* data = (byte*)malloc(size);
+ int unit = self->GetDataTypeSize();
+ int i = 1;
+ lua_rawgeti(L, 2, i);
+ while (!lua_isnil(L, -1))
+ {
+ switch (self->m_DataType)
+ {
+ case GL_INT:
+ {
+ int n = state.CheckValue<int>(-1);
+ memcpy(data + (i - 1)*unit, &n, unit);
+ break;
+ }
+ case GL_FLOAT:
+ {
+ float n = state.CheckValue<float>(-1);
+ memcpy(data + (i - 1)*unit, &n, unit);
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ unsigned char n = state.CheckValue<unsigned char>(-1);
+ memcpy(data + (i - 1)*unit, &n, unit);
+ break;
+ }
+ }
+ state.Pop(1); // value
+ lua_rawgeti(L, 2, ++i);
+ }
+ state.Pop(); // nil
+
+ self->Fill(data, size, offset * unit);
+
+ free(data);
+ return 0;
+ }
+
+ // gpubuffer:GetSize()
+ LUAX_IMPL_METHOD(GPUBuffer, _GetSize)
+ {
+ LUAX_PREPARE(L, GPUBuffer);
+ state.Push(self->m_Size);
+ return 0;
+ }
+
+ LUAX_IMPL_METHOD(GPUBuffer, _GetCount)
+ {
+ LUAX_PREPARE(L, GPUBuffer);
+ state.Push(self->m_Size / self->GetDataTypeSize());
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_image.cpp b/Source/modules/asura-core/Graphics/binding/_image.cpp
new file mode 100644
index 0000000..0e4cb16
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_image.cpp
@@ -0,0 +1,71 @@
+#include "../image.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Image)
+ {
+ LUAX_INHERIT(state, Texture);
+
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New },
+ { "GetWidth", _GetWidth },
+ { "GetHeight", _GetHeight },
+ { "GetSize", _GetSize },
+ { "Render", _Render }
+ );
+ }
+
+ LUAX_POSTPROCESS(Image)
+ {
+ }
+
+ // image = Image.New()
+ LUAX_IMPL_METHOD(Image, _New)
+ {
+ LUAX_STATE(L);
+ Image* img = new Image();
+ img->PushLuaxUserdata(state);
+ return 1;
+ }
+
+ // width = image:GetWidth()
+ LUAX_IMPL_METHOD(Image, _GetWidth)
+ {
+ LUAX_PREPARE(L, Image);
+ state.Push(self->GetWidth());
+ return 1;
+ }
+
+ // height = image:GetHeight()
+ LUAX_IMPL_METHOD(Image, _GetHeight)
+ {
+ LUAX_PREPARE(L, Image);
+ state.Push(self->GetHeight());
+ return 1;
+ }
+
+ // width, height = image:GetSize()
+ LUAX_IMPL_METHOD(Image, _GetSize)
+ {
+ LUAX_PREPARE(L, Image);
+ int width = self->GetWidth();
+ int height = self->GetHeight();
+ state.Push(width);
+ state.Push(height);
+ return 2;
+ }
+
+ // image:Render()
+ LUAX_IMPL_METHOD(Image, _Render)
+ {
+ LUAX_PREPARE(L, Image);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_index_buffer.cpp b/Source/modules/asura-core/Graphics/binding/_index_buffer.cpp
new file mode 100644
index 0000000..151dc98
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_index_buffer.cpp
@@ -0,0 +1,31 @@
+#include "../IndexBuffer.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(IndexBuffer)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New }
+ );
+ }
+
+ LUAX_POSTPROCESS(IndexBuffer)
+ {
+
+ }
+
+ // IndexBuffer.New()
+ LUAX_IMPL_METHOD(IndexBuffer, _New)
+ {
+ LUAX_STATE(L);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_mesh2d.cpp b/Source/modules/asura-core/Graphics/binding/_mesh2d.cpp
new file mode 100644
index 0000000..4e3f426
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_mesh2d.cpp
@@ -0,0 +1,20 @@
+#include "../mesh2d.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Mesh2D)
+ {
+
+ }
+
+ LUAX_POSTPROCESS(Mesh2D)
+ {
+
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_shader.cpp b/Source/modules/asura-core/Graphics/binding/_shader.cpp
new file mode 100644
index 0000000..85fd388
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_shader.cpp
@@ -0,0 +1,131 @@
+#include "../shader.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Shader)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New },
+ { "Load", _Load },
+ { "Update", _Update },
+ { "HasUniform", _HasUniform },
+ { "GetUniformLocation", _GetUniformLocation },
+ { "SetBuiltInUniforms", _SetBuiltInUniforms },
+ { "SetUniformFloat", _SetUniformFloat },
+ { "SetUniformTexture", _SetUniformTexture },
+ { "SetUniformVector2", _SetUniformVector2 },
+ { "SetUniformVector3", _SetUniformVector3 },
+ { "SetUniformVector4", _SetUniformVector4 },
+ { "SetUniformColor", _SetUniformColor },
+ { "SetBuiltInUniforms", _SetBuiltInUniforms }
+ );
+ }
+
+ LUAX_POSTPROCESS(Shader)
+ {
+
+ }
+
+ // Shader.New()
+ LUAX_IMPL_METHOD(Shader, _New)
+ {
+ LUAX_STATE(L);
+
+ return 0;
+ }
+
+ // shader:Load()
+ LUAX_IMPL_METHOD(Shader, _Load)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:Update()
+ LUAX_IMPL_METHOD(Shader, _Update)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:HasUniform()
+ LUAX_IMPL_METHOD(Shader, _HasUniform)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:GetUniformLocation()
+ LUAX_IMPL_METHOD(Shader, _GetUniformLocation)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetBuiltInUniforms()
+ LUAX_IMPL_METHOD(Shader, _SetBuiltInUniforms)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformFloat()
+ LUAX_IMPL_METHOD(Shader, _SetUniformFloat)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformTexture()
+ LUAX_IMPL_METHOD(Shader, _SetUniformTexture)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformVector2()
+ LUAX_IMPL_METHOD(Shader, _SetUniformVector2)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformVector3()
+ LUAX_IMPL_METHOD(Shader, _SetUniformVector3)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformVector4()
+ LUAX_IMPL_METHOD(Shader, _SetUniformVector4)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ // shader:SetUniformColor()
+ LUAX_IMPL_METHOD(Shader, _SetUniformColor)
+ {
+ LUAX_PREPARE(L, Shader);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_sprite_batch.cpp b/Source/modules/asura-core/Graphics/binding/_sprite_batch.cpp
new file mode 100644
index 0000000..6b7d25c
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_sprite_batch.cpp
@@ -0,0 +1,20 @@
+#include "../SpriteBatch.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(SpriteBatch)
+ {
+
+ }
+
+ LUAX_POSTPROCESS(SpriteBatch)
+ {
+
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Graphics/binding/_texture.cpp b/Source/modules/asura-core/Graphics/binding/_texture.cpp
new file mode 100644
index 0000000..f5e5f17
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_texture.cpp
@@ -0,0 +1,85 @@
+#include "../texture.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(Texture)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "SetFilterMode", _SetFilterMode },
+ { "SetWrapMode", _SetWrapMode },
+ { "GetFilterMode", _GetFilterMode },
+ { "GetWrapMode", _GetWrapMode },
+ { "IsGenMipmap", _IsGenMipmap }
+ );
+ }
+
+ LUAX_POSTPROCESS(Texture)
+ {
+ LUAX_REGISTER_ENUM(state, "EColorFormat",
+ { "UNKNOWN", COLOR_FORMAT_UNKNOWN },
+ { "RGBA8", COLOR_FORMAT_RGBA8 },
+ { "RGBA32F", COLOR_FORMAT_RGBA32F }
+ );
+ LUAX_REGISTER_ENUM(state, "EFilterMode",
+ { "NEAREST", FILTER_MODE_NEAREST },
+ { "LINEAR", FILTER_MODE_LINEAR }
+ );
+ LUAX_REGISTER_ENUM(state, "EWrapMode",
+ { "REPEAT", WRAP_MODE_REPEAT },
+ { "MIRROR", WRAP_MODE_MIRROR },
+ { "CLAMPTOEDGE", WRAP_MODE_CLAMPTOEDGE },
+ { "CLAMPTOBORDER", WRAP_MODE_CLAMPTOBORDER }
+ );
+
+ }
+
+ // texture:SetFilterMode(minFilter, magFilter)
+ LUAX_IMPL_METHOD(Texture, _SetFilterMode)
+ {
+ LUAX_PREPARE(L, Texture);
+ FilterMode min = (FilterMode)state.CheckValue<int>(2);
+ FilterMode mag = (FilterMode)state.CheckValue<int>(3);
+ self->SetFilterMode(min, mag);
+ return 0;
+ }
+
+ // texture:SetWrapMode(wrap_mode)
+ LUAX_IMPL_METHOD(Texture, _SetWrapMode)
+ {
+ LUAX_PREPARE(L, Texture);
+ WrapMode wrap_mode = (WrapMode)state.CheckValue<int>(2);
+ self->SetWrapMode(wrap_mode);
+ return 0;
+ }
+
+ // min, mag = texture:GetFilterMode()
+ LUAX_IMPL_METHOD(Texture, _GetFilterMode)
+ {
+ LUAX_PREPARE(L, Texture);
+ state.Push((int)self->m_MinFilter);
+ state.Push((int)self->m_MagFilter);
+ return 2;
+ }
+
+ // wrapmode= texture:GetWrapMode()
+ LUAX_IMPL_METHOD(Texture, _GetWrapMode)
+ {
+ LUAX_PREPARE(L, Texture);
+ state.Push((int)self->m_WrapMode);
+ return 1;
+ }
+
+ // texture:IsGenMipmap()
+ LUAX_IMPL_METHOD(Texture, _IsGenMipmap)
+ {
+ LUAX_PREPARE(L, Texture);
+ state.Push(self->IsGenMipmap());
+ return 1;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/Source/modules/asura-core/Graphics/binding/_vertex_buffer.cpp b/Source/modules/asura-core/Graphics/binding/_vertex_buffer.cpp
new file mode 100644
index 0000000..8ed487b
--- /dev/null
+++ b/Source/modules/asura-core/Graphics/binding/_vertex_buffer.cpp
@@ -0,0 +1,38 @@
+#include "../VertexBuffer.h"
+
+using namespace std;
+using namespace Luax;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Graphics)
+
+
+ LUAX_REGISTRY(VertexBuffer)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New }
+ );
+ }
+
+ LUAX_POSTPROCESS(VertexBuffer)
+ {
+
+ }
+
+ // vbo = VertexBuffer.New(usage, data_type, count)
+ LUAX_IMPL_METHOD(VertexBuffer, _New)
+ {
+ LUAX_STATE(L);
+
+ BufferUsage usage = (BufferUsage)state.CheckValue<uint>(1);
+ BufferDataType datatype = (BufferDataType)state.CheckValue<uint>(2);
+ uint count = state.CheckValue<uint>(3);
+
+ VertexBuffer* vbo = new VertexBuffer(usage, datatype, count * GPUBuffer::GetDataTypeSize(datatype));
+ vbo->PushLuaxUserdata(state);
+
+ return 1;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Image/ImageData.cpp b/Source/modules/asura-core/Image/ImageData.cpp
new file mode 100644
index 0000000..bbfd177
--- /dev/null
+++ b/Source/modules/asura-core/Image/ImageData.cpp
@@ -0,0 +1,62 @@
+#include "ImageData.h"
+#include "PngDecoder.h"
+#include "StbDecoder.h"
+#include "ImageDecoder.h"
+
+using namespace std;
+
+using namespace AEGraphics;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+// imagedecoderΪԡ
+list<ImageDecoder*> ImageData::ImageDecoders = {
+ new PNGDecoder(), // png
+ new STBDecoder() // jpeg, tga, bmp
+};
+
+ImageData::ImageData()
+ : pixels(nullptr)
+ , size(0)
+ , width(0)
+ , height(0)
+ , format(COLOR_FORMAT_UNKNOWN)
+{
+}
+
+ImageData::~ImageData()
+{
+ if (pixels)
+ delete[] pixels;
+}
+
+void ImageData::Decode(FileSystem::DataBuffer& buffer)
+{
+ for (ImageDecoder* decoder : ImageDecoders)
+ {
+ if (decoder->CanDecode(buffer))
+ {
+ decoder->Decode(buffer, *this);
+ return;
+ }
+ }
+}
+
+Color ImageData::GetPixel(uint x, uint y)
+{
+ return Color();
+}
+
+void ImageData::Lock()
+{
+ m_Mutex.Lock();
+}
+
+void ImageData::Unlock()
+{
+ m_Mutex.Unlock();
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/ImageData.h b/Source/modules/asura-core/Image/ImageData.h
new file mode 100644
index 0000000..2d70edc
--- /dev/null
+++ b/Source/modules/asura-core/Image/ImageData.h
@@ -0,0 +1,81 @@
+#ifndef _ASURA_ENGINE_IMAGEDATA_H_
+#define _ASURA_ENGINE_IMAGEDATA_H_
+
+#include <list>
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/FileSystem/DecodedData.h>
+#include <asura-base/FileSystem/DataBuffer.h>
+#include <asura-base/Threads/Thread.h>
+#include <asura-base/Threads/Mutex.h>
+
+#include "../Graphics/Texture.h"
+#include "../Graphics/Color.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+class ImageDecoder;
+
+class ImageData ASURA_FINAL
+ : public Scripting::Portable<ImageData>
+ , public AEFileSystem::DecodedData
+{
+public:
+
+ ///
+ /// ͼƬļϢʧܣ׳쳣
+ ///
+ ImageData();
+ ~ImageData();
+
+ void Decode(AEFileSystem::DataBuffer& buffer) override;
+
+ void Lock();
+ void Unlock();
+
+ AEGraphics::Color GetPixel(uint x, uint y);
+
+ //----------------------------------------------------------------------------//
+
+ uint width, height; // سߴ
+ AEGraphics::ColorFormat format; // ʽ
+ byte* pixels; //
+ std::size_t size; // ݳ
+
+ //----------------------------------------------------------------------------//
+
+private:
+
+ ///
+ /// ڵһ׼image dataʱṩdecoderڼdecodersмѡԡ
+ ///
+ static std::list<ImageDecoder*> ImageDecoders;
+
+ ///
+ /// дݵ
+ ///
+ AEThreading::Mutex m_Mutex;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(ImageData);
+
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_GetPixel);
+ LUAX_DECL_METHOD(_GetSize);
+ LUAX_DECL_METHOD(_GetWidth);
+ LUAX_DECL_METHOD(_GetHeight);
+ LUAX_DECL_METHOD(_GetPixelFormat);
+ LUAX_DECL_METHOD(_Decode);
+ LUAX_DECL_METHOD(_DecodeAsync);
+ LUAX_DECL_METHOD(_IsAvailable);
+
+};
+
+namespace_end
+namespace_end
+
+namespace AEImage = AsuraEngine::Image;
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/ImageDecodeTask.cpp b/Source/modules/asura-core/Image/ImageDecodeTask.cpp
new file mode 100644
index 0000000..16c166e
--- /dev/null
+++ b/Source/modules/asura-core/Image/ImageDecodeTask.cpp
@@ -0,0 +1,17 @@
+#include "ImageDecodeTask.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+bool ImageDecodeTask::Execute()
+{
+ return false;
+}
+
+void ImageDecodeTask::Invoke(lua_State* invokeThreaad)
+{
+
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/ImageDecodeTask.h b/Source/modules/asura-core/Image/ImageDecodeTask.h
new file mode 100644
index 0000000..194ac3e
--- /dev/null
+++ b/Source/modules/asura-core/Image/ImageDecodeTask.h
@@ -0,0 +1,35 @@
+#ifndef _ASURA_IMAGE_DECODE_TASK_H_
+#define _ASURA_IMAGE_DECODE_TASK_H_
+
+#include <asura-base/Threads/task.h>
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+class ImageDecodeTask
+ : public AEScripting::Portable<ImageDecodeTask, AEThreading::Task>
+{
+public:
+
+ ///
+ /// ִɺ󷵻trueûص
+ ///
+ bool Execute() override;
+
+ ///
+ /// ûصinvoke threadص
+ ///
+ void Invoke(lua_State* invokeThreaad) override;
+
+luaxport:
+
+ LUAX_DECL_FACTORY(ImageDecodeTask, AEThreading::Task);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/ImageDecoder.h b/Source/modules/asura-core/Image/ImageDecoder.h
new file mode 100644
index 0000000..6cea8fd
--- /dev/null
+++ b/Source/modules/asura-core/Image/ImageDecoder.h
@@ -0,0 +1,33 @@
+#ifndef _ASURA_ENGINE_IMAGE_DECODER_H_
+#define _ASURA_ENGINE_IMAGE_DECODER_H_
+
+#include <asura-base/FileSystem/DataBuffer.h>
+
+#include "ImageData.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+ASURA_ABSTRACT class ImageDecoder
+{
+public:
+
+ ImageDecoder() {};
+ virtual ~ImageDecoder() {};
+
+ ///
+ /// жڴǷñdecoderѹ
+ ///
+ virtual bool CanDecode(AEFileSystem::DataBuffer& input) = 0;
+
+ ///
+ /// һڴ棬һѹImage dataѹʧܷnullptr
+ ///
+ virtual void Decode(AEFileSystem::DataBuffer& input, ImageData& target) = 0;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/PngDecoder.cpp b/Source/modules/asura-core/Image/PngDecoder.cpp
new file mode 100644
index 0000000..b314561
--- /dev/null
+++ b/Source/modules/asura-core/Image/PngDecoder.cpp
@@ -0,0 +1,17 @@
+#include "PngDecoder.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+bool PNGDecoder::CanDecode(AEFileSystem::DataBuffer& buffer)
+{
+ return false;
+}
+
+void PNGDecoder::Decode(AEFileSystem::DataBuffer& buffer, ImageData& data)
+{
+
+}
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Image/PngDecoder.h b/Source/modules/asura-core/Image/PngDecoder.h
new file mode 100644
index 0000000..3b2a39c
--- /dev/null
+++ b/Source/modules/asura-core/Image/PngDecoder.h
@@ -0,0 +1,25 @@
+#ifndef _ASURA_ENGINE_PNGDECODER_H_
+#define _ASURA_ENGINE_PNGDECODER_H_
+
+#include "ImageDecoder.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+///
+/// ʹlodepngѹpngļ
+///
+class PNGDecoder ASURA_FINAL: public ImageDecoder
+{
+public:
+
+ bool CanDecode(AEFileSystem::DataBuffer& buffer) override;
+
+ void Decode(AEFileSystem::DataBuffer& buffer, ImageData& data) override;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/StbDecoder.cpp b/Source/modules/asura-core/Image/StbDecoder.cpp
new file mode 100644
index 0000000..101b148
--- /dev/null
+++ b/Source/modules/asura-core/Image/StbDecoder.cpp
@@ -0,0 +1,73 @@
+#include <asura-base/Exception.h>
+
+#include "StbDecoder.h"
+
+#define STB_IMAGE_IMPLEMENTATION
+#include <stb/stb_image.h>
+
+using namespace AEGraphics;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+bool STBDecoder::CanDecode(FileSystem::DataBuffer& buffer)
+{
+ int w = 0;
+ int h = 0;
+ int comp = 0;
+
+ int status = stbi_info_from_memory((const stbi_uc*)buffer.GetData(), buffer.GetSize(), &w, &h, &comp);
+
+ return status == 1 && w > 0 && h > 0;
+}
+
+void STBDecoder::Decode(FileSystem::DataBuffer& db, ImageData& imageData)
+{
+ const stbi_uc *buffer = (const stbi_uc *)db.GetData();
+ // databufferݳ
+ int bufferlen = db.GetSize();
+
+ int width, height;
+ int comp = 0;
+ byte* data = nullptr;
+ ColorFormat format = COLOR_FORMAT_UNKNOWN;
+ std::size_t size = 0;
+
+ if (stbi_is_hdr_from_memory(buffer, bufferlen))
+ {
+ // 4channelfloat
+ data = (byte*)stbi_loadf_from_memory(buffer, bufferlen, &width, &height, &comp, STBI_rgb_alpha);
+ format = COLOR_FORMAT_RGBA32F;
+ size = width * height * 4 * sizeof(float);
+ }
+ else
+ {
+ data = (byte*)stbi_load_from_memory(buffer, bufferlen, &width, &height, &comp, STBI_rgb_alpha);
+ format = COLOR_FORMAT_RGBA8;
+ size = width * height * 4;
+ }
+ if (data)
+ {
+ imageData.Lock();
+
+ if (imageData.pixels)
+ free(imageData.pixels);
+ imageData.pixels = (byte*)data;
+ imageData.format = format;
+ imageData.width = width;
+ imageData.height = height;
+ imageData.size = size;
+
+ imageData.Unlock();
+ }
+ else
+ {
+ const char *err = stbi_failure_reason();
+ if (err == nullptr)
+ err = "unknown error";
+ throw Exception("Could not decode image with stb_image (%s).", err);
+ }
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/StbDecoder.h b/Source/modules/asura-core/Image/StbDecoder.h
new file mode 100644
index 0000000..23e8c38
--- /dev/null
+++ b/Source/modules/asura-core/Image/StbDecoder.h
@@ -0,0 +1,26 @@
+#ifndef _ASURA_ENGINE_STBDECODER_H_
+#define _ASURA_ENGINE_STBDECODER_H_
+
+#include "ImageDecoder.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+///
+/// ʹstb_imageѹJPEGTGABMPļ
+///
+class STBDecoder ASURA_FINAL
+ : public ImageDecoder
+{
+public:
+
+ bool CanDecode(AEFileSystem::DataBuffer& buffer) override;
+
+ void Decode(AEFileSystem::DataBuffer& buffer, ImageData& data) override;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Image/binding/_image_data.cpp b/Source/modules/asura-core/Image/binding/_image_data.cpp
new file mode 100644
index 0000000..375f854
--- /dev/null
+++ b/Source/modules/asura-core/Image/binding/_image_data.cpp
@@ -0,0 +1,108 @@
+#include <asura-base/Threads/Thread.h>
+#include <asura-base/FileSystem/DataBuffer.h>
+
+#include "../ImageData.h"
+
+using namespace std;
+using namespace AEThreading;
+using namespace AEFileSystem;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+LUAX_REGISTRY(ImageData)
+ {
+ LUAX_REGISTER_METHODS(state,
+ { "New", _New },
+ { "GetPixel", _GetPixel },
+ { "GetSize", _GetSize },
+ { "GetWidth", _GetWidth },
+ { "GetHeight", _GetHeight },
+ { "GetPixelFormat", _GetPixelFormat },
+ { "Decode", _Decode },
+ { "DecodeAsync", _DecodeAsync },
+ { "IsAvailable", _IsAvailable }
+ );
+ }
+
+ LUAX_POSTPROCESS(ImageData)
+ {
+
+ }
+
+ // ImageData.New()
+ LUAX_IMPL_METHOD(ImageData, _New)
+ {
+ LUAX_STATE(L);
+
+ return 0;
+ }
+
+ // imagedata:GetPixel()
+ LUAX_IMPL_METHOD(ImageData, _GetPixel)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:GetSize()
+ LUAX_IMPL_METHOD(ImageData, _GetSize)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:GetWidth()
+ LUAX_IMPL_METHOD(ImageData, _GetWidth)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:GetHeight()
+ LUAX_IMPL_METHOD(ImageData, _GetHeight)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:GetPixelFormat()
+ LUAX_IMPL_METHOD(ImageData, _GetPixelFormat)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:Decode()
+ LUAX_IMPL_METHOD(ImageData, _Decode)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ // imagedata:DecodeAsync(thread, databuffer, callback)
+ LUAX_IMPL_METHOD(ImageData, _DecodeAsync)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ Thread* thread = state.CheckUserdata<Thread>(2);
+ DataBuffer* buffer = state.CheckUserdata<DataBuffer>(3);
+
+ return 0;
+ }
+
+ // imagedata:IsAvailable()
+ LUAX_IMPL_METHOD(ImageData, _IsAvailable)
+ {
+ LUAX_PREPARE(L, ImageData);
+
+ return 0;
+ }
+
+ }
+}
diff --git a/Source/modules/asura-core/Image/binding/_image_decode_task.cpp b/Source/modules/asura-core/Image/binding/_image_decode_task.cpp
new file mode 100644
index 0000000..3c8ed4b
--- /dev/null
+++ b/Source/modules/asura-core/Image/binding/_image_decode_task.cpp
@@ -0,0 +1,19 @@
+#include "../ImageDecodeTask.h"
+
+using namespace std;
+
+namespace_begin(AsuraEngine)
+namespace_begin(Image)
+
+LUAX_REGISTRY(ImageDecodeTask)
+{
+
+}
+
+LUAX_POSTPROCESS(ImageDecodeTask)
+{
+
+}
+
+}
+}
diff --git a/Source/modules/asura-core/Input/Button.h b/Source/modules/asura-core/Input/Button.h
new file mode 100644
index 0000000..528063d
--- /dev/null
+++ b/Source/modules/asura-core/Input/Button.h
@@ -0,0 +1,31 @@
+#ifndef __BUTTON_H__
+#define __BUTTON_H__
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+/// keyboard button \ mouse button \ joystick button
+class Button
+{
+public:
+ inline Button(int key, bool state) :
+ key(key),
+ state(state)
+ {
+ }
+
+ inline int GetKey(void) const { return this->key; }
+ inline bool GetState(void) const { return this->state; }
+
+private:
+ int key;
+ bool state;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/ClipBoard.cpp b/Source/modules/asura-core/Input/ClipBoard.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Input/ClipBoard.cpp
diff --git a/Source/modules/asura-core/Input/ClipBoard.h b/Source/modules/asura-core/Input/ClipBoard.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Input/ClipBoard.h
diff --git a/Source/modules/asura-core/Input/InputAxis.cpp b/Source/modules/asura-core/Input/InputAxis.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputAxis.cpp
diff --git a/Source/modules/asura-core/Input/InputAxis.h b/Source/modules/asura-core/Input/InputAxis.h
new file mode 100644
index 0000000..9f721d7
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputAxis.h
@@ -0,0 +1,15 @@
+#ifndef _ASURA_ENGINE_INPUT_AXIS_H_
+#define _ASURA_ENGINE_INPUT_AXIS_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+class InputAxis {};
+
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/InputDevice.cpp b/Source/modules/asura-core/Input/InputDevice.cpp
new file mode 100644
index 0000000..0c9c42f
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputDevice.cpp
@@ -0,0 +1,10 @@
+#include "InputDevice.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+
+
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/InputDevice.h b/Source/modules/asura-core/Input/InputDevice.h
new file mode 100644
index 0000000..2b3ff9b
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputDevice.h
@@ -0,0 +1,82 @@
+#ifndef _ASURA_ENGINE_INPUT_BASE_H_
+#define _ASURA_ENGINE_INPUT_BASE_H_
+
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Singleton.hpp>
+
+#include <windows.h>
+
+#include "../CoreConfig.h"
+
+#include "KeyboardState.h"
+#include "MouseState.h"
+#include "JoystickState.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+class InputDevice ASURA_FINAL
+{
+public:
+
+ InputDevice();
+ ~InputDevice();
+
+#if ASURA_EDITOR
+
+ bool Open(HWND window);
+ void Close();
+
+ bool ToggleFullscreen(bool fullscreen, HWND window);
+
+ bool Process(bool discard);
+ LRESULT OnKey(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
+ LRESULT OnInput(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
+ LRESULT OnDeviceChange(LPCWSTR name, bool add);
+
+ static bool ConvertPositionToClientAreaCoord(HWND activeWindow, POINT position, AEMath::Vector2f& newPos);
+
+#elif ASURA_RUNNER
+
+ bool Open();
+ void Close();
+
+#endif
+
+ bool Activate(bool active);
+
+ bool GetJoystickNames(std::vector<std::string> &names);
+
+protected:
+
+ bool UpdateState();
+
+ MouseState m_Mouse;
+ KeyboardState m_Keyboard;
+ JoystickState m_Joysticks;
+
+private:
+
+ bool UpdateMousePosition();
+
+};
+
+extern InputDevice g_InputDevice;
+
+#if ASURA_EDITOR
+
+bool ConvertPositionToClientAreaCoord();
+
+#elif ASURA_RUNNER
+
+bool ConvertPositionToClientAreaCoord();
+
+#endif
+
+namespace_end
+namespace_end
+
+namespace AEInput = AsuraEngine::Input;
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/InputEvent.cpp b/Source/modules/asura-core/Input/InputEvent.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputEvent.cpp
diff --git a/Source/modules/asura-core/Input/InputEvent.h b/Source/modules/asura-core/Input/InputEvent.h
new file mode 100644
index 0000000..c643b75
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputEvent.h
@@ -0,0 +1,55 @@
+#ifndef _ASURA_ENGINE_INPUT_EVENT_H_
+#define _ASURA_ENGINE_INPUT_EVENT_H_
+
+#include <asura-base/Configure.h>
+#include <asura-base/Classes.h>
+#include <asura-base/Math/Vector2.hpp>
+
+#include <windows.h>
+#include <vector>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+// еĿͻ¼̡ػ桢
+struct InputEvent
+{
+ InputEvent();
+ ~InputEvent();
+
+#if ASURA_EDITOR
+
+ bool Open(HWND window);
+ void Close(void);
+
+ bool GetJoystickNames(std::vector<std::string> &names);
+
+ bool Activate(bool active);
+ bool ToggleFullscreen(bool fullscreen, HWND window);
+
+ bool Process(bool discard);
+ LRESULT OnKey(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
+ LRESULT OnInput(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
+ LRESULT OnDeviceChange(LPCWSTR name, bool add);
+
+ static bool ConvertPositionToClientAreaCoord(HWND activeWindow, POINT position, AEMath::Vector2f& newPos);
+
+#elif ASURA_RUNNER
+
+ bool Open();
+
+#endif
+
+ enum
+ {
+
+ };
+
+};
+
+//InputEvent ConvertInputEvent();
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/InputManager.cpp b/Source/modules/asura-core/Input/InputManager.cpp
new file mode 100644
index 0000000..cec1b36
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputManager.cpp
@@ -0,0 +1,140 @@
+#include "InputManager.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+InputManager::InputManager()
+{
+}
+
+InputManager::~InputManager()
+{
+}
+
+void InputManager::Reset()
+{
+}
+
+bool InputManager::GetButton(const std::string& name)
+{
+ return 0;
+}
+
+bool InputManager::GetButtonDown(const std::string& name)
+{
+ return 0;
+}
+
+bool InputManager::GetButtonUp(const std::string& name)
+{
+ return 0;
+}
+
+bool InputManager::HasAxisOrButton(const std::string& name)
+{
+ return 0;
+}
+
+float InputManager::GetAxis(const std::string& name)
+{
+ return 0;
+}
+
+float InputManager::GetAxisRaw(const std::string& name)
+{
+ return 0;
+}
+
+bool InputManager::GetMouseButton(int mouseBut)
+{
+ return 0;
+}
+
+bool InputManager::GetMouseButtonState(int mouseBut)
+{
+ return 0;
+}
+
+bool InputManager::GetMouseButtonDown(int mouseBut)
+{
+ return 0;
+}
+
+bool InputManager::GetMouseButtonUp(int mouseBut)
+{
+ return 0;
+}
+
+
+bool InputManager::GetKey(int key)
+{
+ return 0;
+}
+
+bool InputManager::GetKeyDown(int key)
+{
+ return 0;
+}
+
+bool InputManager::GetKeyUp(int key)
+{
+ return 0;
+}
+
+
+const AEMath::Vector2f& InputManager::GetMouseDelta()
+{
+ return m_MouseDelta;
+}
+
+const AEMath::Vector2f& InputManager::GetMousePosition()
+{
+ return m_MousePos;
+}
+
+
+float InputManager::GetJoystickPosition()
+{
+ return 0;
+}
+
+void InputManager::setJoystickPosition()
+{
+}
+
+
+void InputManager::SetKeyState(int key, bool state)
+{
+ // This ignores keyRepeats (multiple keydown without a keyup event between)
+ if (state && !m_CurrentKeyState[key])
+ m_ThisFrameKeyDown[key] = true;
+ if (!state && m_CurrentKeyState[key])
+ m_ThisFrameKeyUp[key] = true;
+
+ m_CurrentKeyState[key] = state;
+}
+
+void InputManager::SetMouseDelta(const AEMath::Vector2f& delta)
+{
+}
+
+void InputManager::SetMousePosition(const AEMath::Vector2f& pos)
+{
+}
+
+void InputManager::SetMouseButton(int button, bool enabled)
+{
+}
+
+
+void InputManager::ProcessInput()
+{
+}
+
+void InputManager::SendInputEvents()
+{
+}
+
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/InputManager.h b/Source/modules/asura-core/Input/InputManager.h
new file mode 100644
index 0000000..3c44745
--- /dev/null
+++ b/Source/modules/asura-core/Input/InputManager.h
@@ -0,0 +1,352 @@
+#ifndef _ASURA_INPUT_MAMANGER_H_
+#define _ASURA_INPUT_MAMANGER_H_
+
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Singleton.hpp>
+#include <asura-base/Classes.h>
+#include <asura-base/Utilities/dynamic_bitset.h>
+
+#include <string>
+#include <vector>
+
+#include "InputAxis.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+class InputManager : public Singleton<InputManager>
+{
+public:
+
+ InputManager();
+ ~InputManager();
+
+ void Reset();
+
+ bool GetButton(const std::string& name);
+ bool GetButtonDown(const std::string& name);
+ bool GetButtonUp(const std::string& name);
+ bool HasAxisOrButton(const std::string& name);
+ float GetAxis(const std::string& name);
+ float GetAxisRaw(const std::string& name);
+
+ bool GetMouseButton(int mouseBut);
+ bool GetMouseButtonState(int mouseBut);
+ bool GetMouseButtonDown(int mouseBut);
+ bool GetMouseButtonUp(int mouseBut);
+
+ bool GetKey(int key);
+ bool GetKeyDown(int key);
+ bool GetKeyUp(int key);
+
+ const AEMath::Vector2f& GetMouseDelta();
+ const AEMath::Vector2f& GetMousePosition();
+
+ float GetJoystickPosition();
+ void setJoystickPosition();
+
+ void SetKeyState(int key, bool state);
+ void SetMouseDelta(const AEMath::Vector2f& delta);
+ void SetMousePosition(const AEMath::Vector2f& pos);
+ void SetMouseButton(int button, bool enabled);
+
+ void ProcessInput();
+ void SendInputEvents();
+
+private:
+
+ dynamic_bitset m_CurrentKeyState;
+ dynamic_bitset m_ThisFrameKeyDown;
+ dynamic_bitset m_ThisFrameKeyUp;
+
+ std::vector<InputAxis> m_Axis;
+
+ AEMath::Vector2f m_MouseDelta;
+ AEMath::Vector2f m_MousePos;
+
+ bool m_MousePresent;
+
+ std::vector<std::vector<float>> m_JoystickPos;
+
+ std::string m_InputString;
+ std::string m_CompositionString;
+
+ AEMath::Vector2f m_TextFieldCursorPos;
+ bool m_TextFieldInput;
+
+ bool m_EatKeyPressOnTextFieldFocus;
+ int m_IMECompositionMode;
+ bool m_IMEIsSelected;
+
+ int m_LastJoyNum, m_LastJoyAxis;
+ bool m_ShouldQuit;
+ bool m_SimulateMouseWithTouches;
+
+};
+
+// keyboard keys
+enum {
+ /* The keyboard syms have been cleverly chosen to map to ASCII */
+ SDLK_UNKNOWN = 0,
+ SDLK_FIRST = 0,
+ SDLK_BACKSPACE = 8,
+ SDLK_TAB = 9,
+ SDLK_CLEAR = 12,
+ SDLK_RETURN = 13,
+ SDLK_PAUSE = 19,
+ SDLK_ESCAPE = 27,
+ SDLK_SPACE = 32,
+ SDLK_EXCLAIM = 33,
+ SDLK_QUOTEDBL = 34,
+ SDLK_HASH = 35,
+ SDLK_DOLLAR = 36,
+ SDLK_AMPERSAND = 38,
+ SDLK_QUOTE = 39,
+ SDLK_LEFTPAREN = 40,
+ SDLK_RIGHTPAREN = 41,
+ SDLK_ASTERISK = 42,
+ SDLK_PLUS = 43,
+ SDLK_COMMA = 44,
+ SDLK_MINUS = 45,
+ SDLK_PERIOD = 46,
+ SDLK_SLASH = 47,
+ SDLK_0 = 48,
+ SDLK_1 = 49,
+ SDLK_2 = 50,
+ SDLK_3 = 51,
+ SDLK_4 = 52,
+ SDLK_5 = 53,
+ SDLK_6 = 54,
+ SDLK_7 = 55,
+ SDLK_8 = 56,
+ SDLK_9 = 57,
+ SDLK_COLON = 58,
+ SDLK_SEMICOLON = 59,
+ SDLK_LESS = 60,
+ SDLK_EQUALS = 61,
+ SDLK_GREATER = 62,
+ SDLK_QUESTION = 63,
+ SDLK_AT = 64,
+ /*
+ Skip uppercase letters
+ */
+ SDLK_LEFTBRACKET = 91,
+ SDLK_BACKSLASH = 92,
+ SDLK_RIGHTBRACKET = 93,
+ SDLK_CARET = 94,
+ SDLK_UNDERSCORE = 95,
+ SDLK_BACKQUOTE = 96,
+ SDLK_a = 97,
+ SDLK_b = 98,
+ SDLK_c = 99,
+ SDLK_d = 100,
+ SDLK_e = 101,
+ SDLK_f = 102,
+ SDLK_g = 103,
+ SDLK_h = 104,
+ SDLK_i = 105,
+ SDLK_j = 106,
+ SDLK_k = 107,
+ SDLK_l = 108,
+ SDLK_m = 109,
+ SDLK_n = 110,
+ SDLK_o = 111,
+ SDLK_p = 112,
+ SDLK_q = 113,
+ SDLK_r = 114,
+ SDLK_s = 115,
+ SDLK_t = 116,
+ SDLK_u = 117,
+ SDLK_v = 118,
+ SDLK_w = 119,
+ SDLK_x = 120,
+ SDLK_y = 121,
+ SDLK_z = 122,
+ SDLK_DELETE = 127,
+ /* End of ASCII mapped keysyms */
+
+ /* International keyboard syms */
+ SDLK_WORLD_0 = 160, /* 0xA0 */
+ SDLK_WORLD_1 = 161,
+ SDLK_WORLD_2 = 162,
+ SDLK_WORLD_3 = 163,
+ SDLK_WORLD_4 = 164,
+ SDLK_WORLD_5 = 165,
+ SDLK_WORLD_6 = 166,
+ SDLK_WORLD_7 = 167,
+ SDLK_WORLD_8 = 168,
+ SDLK_WORLD_9 = 169,
+ SDLK_WORLD_10 = 170,
+ SDLK_WORLD_11 = 171,
+ SDLK_WORLD_12 = 172,
+ SDLK_WORLD_13 = 173,
+ SDLK_WORLD_14 = 174,
+ SDLK_WORLD_15 = 175,
+ SDLK_WORLD_16 = 176,
+ SDLK_WORLD_17 = 177,
+ SDLK_WORLD_18 = 178,
+ SDLK_WORLD_19 = 179,
+ SDLK_WORLD_20 = 180,
+ SDLK_WORLD_21 = 181,
+ SDLK_WORLD_22 = 182,
+ SDLK_WORLD_23 = 183,
+ SDLK_WORLD_24 = 184,
+ SDLK_WORLD_25 = 185,
+ SDLK_WORLD_26 = 186,
+ SDLK_WORLD_27 = 187,
+ SDLK_WORLD_28 = 188,
+ SDLK_WORLD_29 = 189,
+ SDLK_WORLD_30 = 190,
+ SDLK_WORLD_31 = 191,
+ SDLK_WORLD_32 = 192,
+ SDLK_WORLD_33 = 193,
+ SDLK_WORLD_34 = 194,
+ SDLK_WORLD_35 = 195,
+ SDLK_WORLD_36 = 196,
+ SDLK_WORLD_37 = 197,
+ SDLK_WORLD_38 = 198,
+ SDLK_WORLD_39 = 199,
+ SDLK_WORLD_40 = 200,
+ SDLK_WORLD_41 = 201,
+ SDLK_WORLD_42 = 202,
+ SDLK_WORLD_43 = 203,
+ SDLK_WORLD_44 = 204,
+ SDLK_WORLD_45 = 205,
+ SDLK_WORLD_46 = 206,
+ SDLK_WORLD_47 = 207,
+ SDLK_WORLD_48 = 208,
+ SDLK_WORLD_49 = 209,
+ SDLK_WORLD_50 = 210,
+ SDLK_WORLD_51 = 211,
+ SDLK_WORLD_52 = 212,
+ SDLK_WORLD_53 = 213,
+ SDLK_WORLD_54 = 214,
+ SDLK_WORLD_55 = 215,
+ SDLK_WORLD_56 = 216,
+ SDLK_WORLD_57 = 217,
+ SDLK_WORLD_58 = 218,
+ SDLK_WORLD_59 = 219,
+ SDLK_WORLD_60 = 220,
+ SDLK_WORLD_61 = 221,
+ SDLK_WORLD_62 = 222,
+ SDLK_WORLD_63 = 223,
+ SDLK_WORLD_64 = 224,
+ SDLK_WORLD_65 = 225,
+ SDLK_WORLD_66 = 226,
+ SDLK_WORLD_67 = 227,
+ SDLK_WORLD_68 = 228,
+ SDLK_WORLD_69 = 229,
+ SDLK_WORLD_70 = 230,
+ SDLK_WORLD_71 = 231,
+ SDLK_WORLD_72 = 232,
+ SDLK_WORLD_73 = 233,
+ SDLK_WORLD_74 = 234,
+ SDLK_WORLD_75 = 235,
+ SDLK_WORLD_76 = 236,
+ SDLK_WORLD_77 = 237,
+ SDLK_WORLD_78 = 238,
+ SDLK_WORLD_79 = 239,
+ SDLK_WORLD_80 = 240,
+ SDLK_WORLD_81 = 241,
+ SDLK_WORLD_82 = 242,
+ SDLK_WORLD_83 = 243,
+ SDLK_WORLD_84 = 244,
+ SDLK_WORLD_85 = 245,
+ SDLK_WORLD_86 = 246,
+ SDLK_WORLD_87 = 247,
+ SDLK_WORLD_88 = 248,
+ SDLK_WORLD_89 = 249,
+ SDLK_WORLD_90 = 250,
+ SDLK_WORLD_91 = 251,
+ SDLK_WORLD_92 = 252,
+ SDLK_WORLD_93 = 253,
+ SDLK_WORLD_94 = 254,
+ SDLK_WORLD_95 = 255, /* 0xFF */
+
+ /* Numeric keypad */
+ SDLK_KP0 = 256,
+ SDLK_KP1 = 257,
+ SDLK_KP2 = 258,
+ SDLK_KP3 = 259,
+ SDLK_KP4 = 260,
+ SDLK_KP5 = 261,
+ SDLK_KP6 = 262,
+ SDLK_KP7 = 263,
+ SDLK_KP8 = 264,
+ SDLK_KP9 = 265,
+ SDLK_KP_PERIOD = 266,
+ SDLK_KP_DIVIDE = 267,
+ SDLK_KP_MULTIPLY = 268,
+ SDLK_KP_MINUS = 269,
+ SDLK_KP_PLUS = 270,
+ SDLK_KP_ENTER = 271,
+ SDLK_KP_EQUALS = 272,
+
+ /* Arrows + Home/End pad */
+ SDLK_UP = 273,
+ SDLK_DOWN = 274,
+ SDLK_RIGHT = 275,
+ SDLK_LEFT = 276,
+ SDLK_INSERT = 277,
+ SDLK_HOME = 278,
+ SDLK_END = 279,
+ SDLK_PAGEUP = 280,
+ SDLK_PAGEDOWN = 281,
+
+ /* Function keys */
+ SDLK_F1 = 282,
+ SDLK_F2 = 283,
+ SDLK_F3 = 284,
+ SDLK_F4 = 285,
+ SDLK_F5 = 286,
+ SDLK_F6 = 287,
+ SDLK_F7 = 288,
+ SDLK_F8 = 289,
+ SDLK_F9 = 290,
+ SDLK_F10 = 291,
+ SDLK_F11 = 292,
+ SDLK_F12 = 293,
+ SDLK_F13 = 294,
+ SDLK_F14 = 295,
+ SDLK_F15 = 296,
+
+ /* Key state modifier keys */
+ SDLK_NUMLOCK = 300,
+ SDLK_CAPSLOCK = 301,
+ SDLK_SCROLLOCK = 302,
+ SDLK_RSHIFT = 303,
+ SDLK_LSHIFT = 304,
+ SDLK_RCTRL = 305,
+ SDLK_LCTRL = 306,
+ SDLK_RALT = 307,
+ SDLK_LALT = 308,
+ SDLK_RMETA = 309,
+ SDLK_LMETA = 310,
+ SDLK_RGUI = 309,
+ SDLK_LGUI = 310,
+ SDLK_LSUPER = 311, /* Left "Windows" key */
+ SDLK_RSUPER = 312, /* Right "Windows" key */
+ SDLK_MODE = 313, /* "Alt Gr" key */
+ SDLK_COMPOSE = 314, /* Multi-key compose key */
+
+ /* Miscellaneous function keys */
+ SDLK_HELP = 315,
+ SDLK_PRINT = 316,
+ SDLK_SYSREQ = 317,
+ SDLK_BREAK = 318,
+ SDLK_MENU = 319,
+ SDLK_POWER = 320, /* Power Macintosh power key */
+ SDLK_EURO = 321, /* Some european keyboards */
+ SDLK_UNDO = 322, /* Atari keyboard has Undo */
+
+ /* Add any other keys here */
+
+ SDLK_LAST
+};
+
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/JoystickState.h b/Source/modules/asura-core/Input/JoystickState.h
new file mode 100644
index 0000000..e97e235
--- /dev/null
+++ b/Source/modules/asura-core/Input/JoystickState.h
@@ -0,0 +1,16 @@
+#ifndef _ASURA_JOYSTICKSTATE_H_
+#define _ASURA_JOYSTICKSTATE_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+class JoystickState {};
+
+
+namespace_end
+namespace_end
+
+#endif
+
diff --git a/Source/modules/asura-core/Input/KeyboardState.h b/Source/modules/asura-core/Input/KeyboardState.h
new file mode 100644
index 0000000..96d22e7
--- /dev/null
+++ b/Source/modules/asura-core/Input/KeyboardState.h
@@ -0,0 +1,37 @@
+#ifndef __KEYBOARD_STATE_H__
+#define __KEYBOARD_STATE_H__
+
+#include <vector>
+
+#include "Button.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+typedef std::vector<Button> Buttons;
+
+class KeyboardState
+{
+private:
+ Buttons buttons;
+
+public:
+ inline KeyboardState(void)
+ {
+ this->buttons.reserve(256);
+ }
+
+ inline const Buttons &GetButtons(void) const { return this->buttons; }
+ inline void AddButton(int key, bool state) { this->buttons.push_back(Button(key, state)); }
+
+ void Reset(bool full)
+ {
+ this->buttons.clear();
+ }
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Input/MouseState.h b/Source/modules/asura-core/Input/MouseState.h
new file mode 100644
index 0000000..6b44070
--- /dev/null
+++ b/Source/modules/asura-core/Input/MouseState.h
@@ -0,0 +1,16 @@
+#ifndef _ASURA_MOUSESTATE_H_
+#define _ASURA_MOUSESTATE_H_
+
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Input)
+
+class MouseState {};
+
+
+namespace_end
+namespace_end
+
+#endif
+
diff --git a/Source/modules/asura-core/Mesh/Am2Handler.cpp b/Source/modules/asura-core/Mesh/Am2Handler.cpp
new file mode 100644
index 0000000..115797f
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Am2Handler.cpp
@@ -0,0 +1,34 @@
+#include "Am2Handler.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Mesh)
+/*
+Asuramesh2DʽΪ.am2ʽ¡
+ͷ11ֽڱһAsuraMesh2Dļ
+ASURAMESH2D
+v position
+t tangent
+n normal
+[c color]
+[u texcoord0]
+[u texcoord1]
+[u texcoord2]
+[u texcoord3]
+
+f surface
+
+
+ASURAMESH2D
+p 0
+v 0, 0
+t -0.2, 0.45
+n -0.3, 0.6
+p 1
+
+f 0, 1, 2
+*/
+
+
+
+namespace_end
+namespace_end
diff --git a/Source/modules/asura-core/Mesh/Am2Handler.h b/Source/modules/asura-core/Mesh/Am2Handler.h
new file mode 100644
index 0000000..ff5dbfa
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Am2Handler.h
@@ -0,0 +1,30 @@
+#ifndef _ASURA_MESH2D_AM2_HANDLER_H__
+#define _ASURA_MESH2D_AM2_HANDLER_H__
+
+#include "Mesh2dHandler.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Mesh)
+
+///
+/// Asura Mesh Format handler͹Asura.am2ʽmeshļ
+///
+class AM2Handler ASURA_FINAL : public Mesh2DHandler
+{
+public:
+
+ AM2Handler();
+ ~AM2Handler();
+
+ bool CanDecode(AEFileSystem::DataBuffer& input) override;
+
+ void Decode(AEFileSystem::DataBuffer& input, Mesh2DData& target) override;
+
+ void Encode(Mesh2DData& input, AEFileSystem::DataBuffer& target) override;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Mesh/Mesh2DData.cpp b/Source/modules/asura-core/Mesh/Mesh2DData.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Mesh2DData.cpp
diff --git a/Source/modules/asura-core/Mesh/Mesh2DData.h b/Source/modules/asura-core/Mesh/Mesh2DData.h
new file mode 100644
index 0000000..3e30a06
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Mesh2DData.h
@@ -0,0 +1,78 @@
+#ifndef _ASURA_MESH2D_DATA_H__
+#define _ASURA_MESH2D_DATA_H__
+
+// cpp
+#include <vector>
+
+// asura modules
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/FileSystem/DecodedData.h>
+
+// module
+#include "../Graphics/Color.h"
+#include "../Graphics/GPUBuffer.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Mesh)
+
+///
+/// Mesh2DĶݣindexʹáAsura 2D mesh֧4UVһϡ
+///
+struct Vertex
+{
+ AEMath::Vector2f position; ///<
+ AEGraphics::Color color; ///< ɫ
+ AEMath::Vector2f texCoord[4]; ///< UVs
+};
+
+///
+/// meshĶݺ
+///
+class Mesh2DData
+ : AEFileSystem::DecodedData
+ , AEScripting::Portable<Mesh2DData>
+{
+public:
+
+ enum Mesh2DComponent
+ {
+ MESH2D_COMPONENT_POSITION,
+ MESH2D_COMPONENT_COLOR,
+ MESH2D_COMPONENT_TEXCOORD0,
+ MESH2D_COMPONENT_TEXCOORD1,
+ MESH2D_COMPONENT_TEXCOORD2,
+ MESH2D_COMPONENT_TEXCOORD3,
+ };
+
+ void Decode(AEFileSystem::DataBuffer& buffer) override;
+
+private:
+
+ LUAX_DECL_FACTORY(Mesh2DData);
+
+ LUAX_DECL_ENUM(Mesh2DComponent, 1);
+
+ LUAX_DECL_METHOD(_GetVertices);
+ LUAX_DECL_METHOD(_GetVertex);
+
+ ///
+ /// meshж㡣
+ ///
+ std::vector<Vertex*> m_Vertices;
+
+ ///
+ /// ebo
+ ///
+ std::vector<int> m_Indices;
+
+ int m_Components;
+
+};
+
+namespace_end
+namespace_end
+
+namespace AEMesh = AsuraEngine::Mesh;
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Mesh/Mesh2DHandler.cpp b/Source/modules/asura-core/Mesh/Mesh2DHandler.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Mesh2DHandler.cpp
diff --git a/Source/modules/asura-core/Mesh/Mesh2DHandler.h b/Source/modules/asura-core/Mesh/Mesh2DHandler.h
new file mode 100644
index 0000000..9ddb724
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/Mesh2DHandler.h
@@ -0,0 +1,32 @@
+#ifndef _ASURA_MESH2D_HANDLER_H__
+#define _ASURA_MESH2D_HANDLER_H__
+
+#include <asura-base/FileSystem/DataBuffer.h>
+#include <asura-base/Type.h>
+
+#include "Mesh2dData.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Mesh)
+
+///
+/// ͱmesh
+///
+ASURA_ABSTRACT class Mesh2DHandler
+{
+public:
+ Mesh2DHandler() {};
+ virtual ~Mesh2DHandler() {};
+
+ virtual bool CanDecode(AEFileSystem::DataBuffer& input) = 0;
+
+ virtual void Decode(AEFileSystem::DataBuffer& input, Mesh2DData& target) = 0;
+
+ virtual void Encode(Mesh2DData& input, AEFileSystem::DataBuffer& target) = 0;
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Mesh/ObjHandler.cpp b/Source/modules/asura-core/Mesh/ObjHandler.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/ObjHandler.cpp
diff --git a/Source/modules/asura-core/Mesh/ObjHandler.h b/Source/modules/asura-core/Mesh/ObjHandler.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Mesh/ObjHandler.h
diff --git a/Source/modules/asura-core/Profiler/GPUProfiler.cpp b/Source/modules/asura-core/Profiler/GPUProfiler.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Profiler/GPUProfiler.cpp
diff --git a/Source/modules/asura-core/Profiler/GPUProfiler.h b/Source/modules/asura-core/Profiler/GPUProfiler.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Profiler/GPUProfiler.h
diff --git a/Source/modules/asura-core/Profiler/Stats.cpp b/Source/modules/asura-core/Profiler/Stats.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Profiler/Stats.cpp
diff --git a/Source/modules/asura-core/Profiler/Stats.h b/Source/modules/asura-core/Profiler/Stats.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Profiler/Stats.h
diff --git a/Source/modules/asura-core/Threads/Channel.cpp b/Source/modules/asura-core/Threads/Channel.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Threads/Channel.cpp
diff --git a/Source/modules/asura-core/Threads/Channel.h b/Source/modules/asura-core/Threads/Channel.h
new file mode 100644
index 0000000..901564f
--- /dev/null
+++ b/Source/modules/asura-core/Threads/Channel.h
@@ -0,0 +1,18 @@
+#ifndef _ASURA_THREAD_CHANNEL_H_
+#define _ASURA_THREAD_CHANNEL_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Classes.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Threads)
+
+class Channel
+{
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Threads/ThreadEx.cpp b/Source/modules/asura-core/Threads/ThreadEx.cpp
new file mode 100644
index 0000000..cec5ba7
--- /dev/null
+++ b/Source/modules/asura-core/Threads/ThreadEx.cpp
@@ -0,0 +1,20 @@
+#include <asura-base/Classes.h>
+
+#include "ThreadEx.h"
+
+namespace_begin(AsuraEngine)
+namespace_begin(Threads)
+
+int ThreadEx::Process()
+{
+
+ return 0;
+}
+
+void ThreadEx::RegisterModules()
+{
+
+}
+
+namespace_end
+namespace_end \ No newline at end of file
diff --git a/Source/modules/asura-core/Threads/ThreadEx.h b/Source/modules/asura-core/Threads/ThreadEx.h
new file mode 100644
index 0000000..ec597c5
--- /dev/null
+++ b/Source/modules/asura-core/Threads/ThreadEx.h
@@ -0,0 +1,45 @@
+#ifndef _ASURA_THREAD_EX_H_
+#define _ASURA_THREAD_EX_H_
+
+#include <asura-base/Scripting/Scripting.h>
+#include <asura-base/Threads/Thread.h>
+
+namespace_begin(AsuraEngine)
+namespace_begin(Threads)
+
+///
+/// ThreadExеͬͨ˶ͨݡ
+///
+class ThreadEx ASURA_FINAL
+ : public AEScripting::Portable<ThreadEx>
+ , public Threadable
+{
+public:
+
+ LUAX_DECL_FACTORY(ThreadEx);
+
+ ThreadEx();
+ ~ThreadEx();
+
+ int Process() override;
+
+private:
+
+ // ̵߳עAsuraͽӿڣעֻһֶ֮䴫ݡЩ͵Ķ
+ void RegisterModules();
+
+ ThreadImpl* m_Impl;
+
+ // ̴߳
+ Luax::LuaxVM* m_VM;
+
+luaxport:
+
+ LUAX_DECL_METHOD(_New);
+
+};
+
+namespace_end
+namespace_end
+
+#endif \ No newline at end of file
diff --git a/Source/modules/asura-core/Time/Timer.cpp b/Source/modules/asura-core/Time/Timer.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Time/Timer.cpp
diff --git a/Source/modules/asura-core/Time/Timer.h b/Source/modules/asura-core/Time/Timer.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/modules/asura-core/Time/Timer.h
diff --git a/Source/modules/asura-core/Window/Window.cpp b/Source/modules/asura-core/Window/Window.cpp
new file mode 100644
index 0000000..d75b9a7
--- /dev/null
+++ b/Source/modules/asura-core/Window/Window.cpp
@@ -0,0 +1,104 @@
+#include <asura-base/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..0f2850b
--- /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-base/Scripting/Scripting.h>
+#include <asura-base/Math/Vector2.hpp>
+#include <asura-base/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..23b2aed
--- /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-base/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