diff --git a/CMake/Dependencies.cmake b/CMake/Dependencies.cmake index f68c9db7e..0bb427fe3 100644 --- a/CMake/Dependencies.cmake +++ b/CMake/Dependencies.cmake @@ -79,6 +79,8 @@ elseif(MYGUI_RENDERSYSTEM EQUAL 6) find_package(DirectX11) macro_log_feature(DirectX_FOUND "DirectX11" "Support for the DirectX11 render system" "http://msdn.microsoft.com/en-us/directx/" TRUE "" "") endif() +elseif(MYGUI_RENDERSYSTEM EQUAL 9) + find_package(SDL2_image) #elseif for RENDERSYSTEM 7 is covered with RENDERSYSTEM 4 endif() diff --git a/CMake/Utils/MyGUIConfigTargets.cmake b/CMake/Utils/MyGUIConfigTargets.cmake index 7e279c986..81ecd8814 100644 --- a/CMake/Utils/MyGUIConfigTargets.cmake +++ b/CMake/Utils/MyGUIConfigTargets.cmake @@ -39,6 +39,8 @@ function(mygui_set_platform_name PLATFORM_ID) set(MYGUI_PLATFORM_NAME OpenGL3 PARENT_SCOPE) elseif(${PLATFORM_ID} EQUAL 8) set(MYGUI_PLATFORM_NAME OpenGLES PARENT_SCOPE) + elseif(${PLATFORM_ID} EQUAL 9) + set(MYGUI_PLATFORM_NAME SDL2 PARENT_SCOPE) endif() endfunction(mygui_set_platform_name) @@ -150,6 +152,14 @@ function(mygui_app PROJECTNAME SOLUTIONFOLDER) ${OPENGL_LIB_DIR} ${SDL2_IMAGE_LIB_DIR} ) + elseif(MYGUI_RENDERSYSTEM EQUAL 9) + add_definitions("-DMYGUI_SDL2_PLATFORM") + include_directories(SYSTEM + ${SDL2_IMAGE_INCLUDE_DIRS} + ) + link_directories( + ${SDL2_IMAGE_LIB_DIR} + ) endif() # setup demo target @@ -192,6 +202,8 @@ function(mygui_app PROJECTNAME SOLUTIONFOLDER) target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) elseif(MYGUI_RENDERSYSTEM EQUAL 8) target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) + elseif(MYGUI_RENDERSYSTEM EQUAL 9) + target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) endif() target_link_libraries(${PROJECTNAME} MyGUIEngine @@ -265,6 +277,8 @@ function(mygui_dll PROJECTNAME SOLUTIONFOLDER) ${OPENGL_INCLUDE_DIR} ) link_directories(${OPENGL_LIB_DIR}) + elseif(MYGUI_RENDERSYSTEM EQUAL 9) + add_definitions("-DMYGUI_SDL2_PLATFORM") endif() @@ -304,6 +318,8 @@ function(mygui_dll PROJECTNAME SOLUTIONFOLDER) target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) elseif(MYGUI_RENDERSYSTEM EQUAL 8) target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) + elseif(MYGUI_RENDERSYSTEM EQUAL 9) + target_link_libraries(${PROJECTNAME} ${SDL2_IMAGE_LIBRARIES}) endif() target_link_libraries(${PROJECTNAME} diff --git a/CMakeLists.txt b/CMakeLists.txt index 079feab3a..4c7a3efcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,9 @@ set(MYGUI_RENDERSYSTEM 3 CACHE STRING 5 - Direct3D 9 6 - Direct3D 11 7 - OpenGL 3.x - 8 - OpenGL ES 2.0 (Emscripten)" + 8 - OpenGL ES 2.0 (Emscripten) + 9 - SDL2 (>=2.0.18) +" ) if(MYGUI_RENDERSYSTEM EQUAL 4 OR MYGUI_RENDERSYSTEM EQUAL 7) diff --git a/Common/Base/PlatformBaseManager/SdlBaseManager.cpp b/Common/Base/PlatformBaseManager/SdlBaseManager.cpp index 527b387e8..7460edd98 100644 --- a/Common/Base/PlatformBaseManager/SdlBaseManager.cpp +++ b/Common/Base/PlatformBaseManager/SdlBaseManager.cpp @@ -12,7 +12,9 @@ namespace base void SdlBaseManager::_windowResized(int w, int h) { - resizeRender(w, h); + int fbWidth, fbHeight; + SDL_GL_GetDrawableSize(mSdlWindow, &fbWidth, &fbHeight); + resizeRender(fbWidth, fbHeight); if (mPlatformReady) MyGUI::RenderManager::getInstance().setViewSize(w, h); @@ -43,13 +45,16 @@ namespace base int left = (currDisp.w - width) / 2; int top = (currDisp.h - height) / 2; - mSdlWindow = SDL_CreateWindow("MyGUI Render Window", left, top, width, height, (mIsOpenGlWindow ? SDL_WINDOW_OPENGL : 0) | SDL_WINDOW_RESIZABLE); + mSdlWindow = SDL_CreateWindow("MyGUI Render Window", left, top, width, height, (mIsOpenGlWindow ? SDL_WINDOW_OPENGL : 0) | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (mSdlWindow == nullptr) { std::cerr << "Failed to create SDL window."; exit(1); } mWindowOn = true; + int realW, realH; + SDL_GL_GetDrawableSize(mSdlWindow, &realW, &realH); + mScale = (double)realW / (double)width; #if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32 // set icon @@ -73,7 +78,7 @@ namespace base ::SendMessageA((HWND)handle, WM_SETICON, 1, (LPARAM)hIconBig); #endif - if (!createRender(width, height, windowed)) + if (!createRender(realW, realH, windowed)) { return false; } @@ -107,6 +112,9 @@ namespace base { switch (mEvent.type) { + case SDL_QUIT: + mExit = true; + break; // keyboard events case SDL_KEYDOWN: mKeyCode = mEvent.key.keysym.sym; diff --git a/Common/Base/PlatformBaseManager/SdlBaseManager.h b/Common/Base/PlatformBaseManager/SdlBaseManager.h index c05ac6154..6e0a395f2 100644 --- a/Common/Base/PlatformBaseManager/SdlBaseManager.h +++ b/Common/Base/PlatformBaseManager/SdlBaseManager.h @@ -81,6 +81,8 @@ namespace base bool mWindowOn = false; SDL_Keycode mKeyCode; int mFpsCounter = 0; + + double mScale = 0; }; } diff --git a/Common/Base/SDL2/BaseManager.cpp b/Common/Base/SDL2/BaseManager.cpp new file mode 100644 index 000000000..0abf66242 --- /dev/null +++ b/Common/Base/SDL2/BaseManager.cpp @@ -0,0 +1,109 @@ +#include "Precompiled.h" +#include "BaseManager.h" + +#include + +namespace base +{ + bool BaseManager::createRender(int _width, int _height, bool _windowed) + { + mRenderer = SDL_CreateRenderer(mSdlWindow, 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC); + + if (mRenderer == nullptr) { + std::cerr << "Failed to initialize SDL_Renderer: " << SDL_GetError(); + exit(1); + } + + // TODO: Why do we need this? We need to understand why SubSkin::doRender() multiplies the size of the quad by 2 +// SDL_RenderSetScale(mRenderer, 0.5, 0.5); + + if (IMG_Init(~0) == 0) + { + std::cerr << "Failed to initialize SDL_image: " << IMG_GetError(); + exit(1); + } + return true; + } + + void BaseManager::destroyRender() + { + SDL_DestroyRenderer(mRenderer); + IMG_Quit(); + } + + void BaseManager::createGuiPlatform() + { + mPlatform = new MyGUI::SDL2Platform(); + setupResources(); + mPlatform->initialise(this, mRenderer); + } + + void BaseManager::destroyGuiPlatform() + { + if (mPlatform) + { + mPlatform->shutdown(); + delete mPlatform; + mPlatform = nullptr; + } + } + + void BaseManager::drawOneFrame() + { + SDL_SetRenderDrawColor(mRenderer, 10, 20, 30, 0xFF); + SDL_RenderClear(mRenderer); + + if (mPlatform) + mPlatform->getRenderManagerPtr()->drawOneFrame(); + + SDL_RenderPresent(mRenderer); + } + + void BaseManager::resizeRender(int _width, int _height) + { + // TODO: Maybe we need to resize the renderer? + printf("Resized\n"); + } + + void BaseManager::addResourceLocation(const std::string& _name, bool _recursive) + { + mPlatform->getDataManagerPtr()->addResourceLocation(_name, _recursive); + } + + + SDL_Texture* BaseManager::loadTexture(const std::string& _filename) + { + std::string fullname = MyGUI::SDL2DataManager::getInstance().getDataPath(_filename); + + SDL_Texture *texture = NULL; + SDL_Surface *surface = IMG_Load(fullname.c_str()); + + MYGUI_ASSERT(surface != nullptr, "Failed to load image: " + fullname); + + auto bpp = surface->format->BytesPerPixel; + auto newFormat = SDL_PIXELFORMAT_UNKNOWN; + switch (bpp) { + case 4: + newFormat = SDL_PIXELFORMAT_RGBA32; + break; + case 3: + newFormat = SDL_PIXELFORMAT_RGB24; + break; + } + surface = SDL_ConvertSurfaceFormat(surface, newFormat, 0); + + MYGUI_ASSERT(surface != nullptr, "Failed to convert image: " + fullname); + + texture = SDL_CreateTextureFromSurface(mRenderer, surface); + SDL_FreeSurface(surface); + + return texture; + } + + void BaseManager::saveImage(int _width, int _height, MyGUI::PixelFormat _format, void* _texture, const std::string& _filename) + { + SDL_Surface* surface = SDL_CreateRGBSurface(0, _width, _height, _format.getBytesPerPixel() * 8, 0, 0, 0, 0); + std::memcpy(surface->pixels, _texture, _width * _height * _format.getBytesPerPixel()); + IMG_SavePNG(surface, _filename.c_str()); + } +} diff --git a/Common/Base/SDL2/BaseManager.h b/Common/Base/SDL2/BaseManager.h new file mode 100644 index 000000000..1c08fca02 --- /dev/null +++ b/Common/Base/SDL2/BaseManager.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Base/PlatformBaseManager/SdlBaseManager.h" + +#include +#include + +namespace base +{ + + class BaseManager : + public SdlBaseManager, + public MyGUI::SDL2ImageLoader + { + public: + BaseManager() : SdlBaseManager(false) { } + bool createRender(int _width, int _height, bool _windowed) override; + void destroyRender() override; + void drawOneFrame() override; + void resizeRender(int _width, int _height) override; + void addResourceLocation(const std::string& _name, bool _recursive = false) override; + void createGuiPlatform() override; + void destroyGuiPlatform() override; + +// /*internal:*/ + SDL_Texture* loadTexture(const std::string& _filename) override; + void saveImage(int _width, int _height, MyGUI::PixelFormat _format, void* _texture, const std::string& _filename) override; + + private: + MyGUI::SDL2Platform* mPlatform = nullptr; + SDL_Renderer *mRenderer = nullptr; + }; + +} diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index db7d6610c..b25b2c1c4 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -77,6 +77,12 @@ elseif(MYGUI_RENDERSYSTEM EQUAL 8) ) link_directories(${OPENGL_LIB_DIR}) link_directories(${SDL2_IMAGE_LIB_DIR}) +elseif(MYGUI_RENDERSYSTEM EQUAL 9) + add_definitions("-DMYGUI_SDL2_PLATFORM") + include_directories(SYSTEM + ${SDL2_IMAGE_INCLUDE_DIRS} + ) + link_directories(${SDL2_IMAGE_LIB_DIR}) endif() include_directories(Input/SDL) diff --git a/Platforms/SDL2/SDL2Platform/CMakeLists.txt b/Platforms/SDL2/SDL2Platform/CMakeLists.txt new file mode 100644 index 000000000..4631c7b1b --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/CMakeLists.txt @@ -0,0 +1,22 @@ +set(PROJECTNAME MyGUI.SDL2Platform) + +include_directories( + include + ${MYGUI_SOURCE_DIR}/MyGUIEngine/include + ${MYGUI_SOURCE_DIR}/Common + ${SDL2_INCLUDE_DIRS} +) + +include(${PROJECTNAME}.list) + +add_library(${PROJECTNAME} ${HEADER_FILES} ${SOURCE_FILES}) + +add_dependencies(${PROJECTNAME} MyGUIEngine) + +target_link_libraries(${PROJECTNAME} MyGUIEngine ${SDL2_LIBRARIES}) + +# installation rules +install(FILES ${HEADER_FILES} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/MYGUI" +) +mygui_install_target(${PROJECTNAME} "") diff --git a/Platforms/SDL2/SDL2Platform/MyGUI.SDL2Platform.list b/Platforms/SDL2/SDL2Platform/MyGUI.SDL2Platform.list new file mode 100644 index 000000000..57b5ac485 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/MyGUI.SDL2Platform.list @@ -0,0 +1,28 @@ +set (HEADER_FILES + include/MyGUI_SDL2DataManager.h + include/MyGUI_SDL2Diagnostic.h + include/MyGUI_SDL2Platform.h + include/MyGUI_SDL2RenderManager.h + include/MyGUI_SDL2Texture.h + include/MyGUI_SDL2VertexBuffer.h +) +set (SOURCE_FILES + src/MyGUI_SDL2DataManager.cpp + src/MyGUI_SDL2RenderManager.cpp + src/MyGUI_SDL2Texture.cpp + src/MyGUI_SDL2VertexBuffer.cpp +) +SOURCE_GROUP("Header Files" FILES + include/MyGUI_SDL2DataManager.h + include/MyGUI_SDL2Diagnostic.h + include/MyGUI_SDL2Platform.h + include/MyGUI_SDL2RenderManager.h + include/MyGUI_SDL2Texture.h + include/MyGUI_SDL2VertexBuffer.h +) +SOURCE_GROUP("Source Files" FILES + src/MyGUI_SDL2DataManager.cpp + src/MyGUI_SDL2RenderManager.cpp + src/MyGUI_SDL2Texture.cpp + src/MyGUI_SDL2VertexBuffer.cpp +) diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2DataManager.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2DataManager.h new file mode 100644 index 000000000..635e79608 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2DataManager.h @@ -0,0 +1,69 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_DATA_MANAGER_H_ +#define MYGUI_SDL2_DATA_MANAGER_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_DataManager.h" + +#include +#include + +namespace MyGUI +{ + + class SDL2DataManager : + public DataManager + { + public: + SDL2DataManager(); + + void initialise(); + void shutdown(); + + static SDL2DataManager& getInstance() + { + return *getInstancePtr(); + } + static SDL2DataManager* getInstancePtr() + { + return static_cast(DataManager::getInstancePtr()); + } + + /** @see DataManager::getData(const std::string& _name) */ + IDataStream* getData(const std::string& _name) const override; + + /** @see DataManager::freeData */ + void freeData(IDataStream* _data) override; + + /** @see DataManager::isDataExist(const std::string& _name) */ + bool isDataExist(const std::string& _name) const override; + + /** @see DataManager::getDataListNames(const std::string& _pattern) */ + const VectorString& getDataListNames(const std::string& _pattern) const override; + + /** @see DataManager::getDataPath(const std::string& _name) */ + const std::string& getDataPath(const std::string& _name) const override; + + /*internal:*/ + void addResourceLocation(const std::string& _name, bool _recursive); + + private: + struct ArhivInfo + { + std::wstring name; + bool recursive; + }; + typedef std::vector VectorArhivInfo; + VectorArhivInfo mPaths; + + bool mIsInitialise; + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_DATA_MANAGER_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Diagnostic.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Diagnostic.h new file mode 100644 index 000000000..96bc05a5c --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Diagnostic.h @@ -0,0 +1,35 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_DIAGNOSTIC_H_ +#define MYGUI_SDL2_DIAGNOSTIC_H_ + +#include "MyGUI_Prerequest.h" + +#define MYGUI_PLATFORM_LOG_SECTION "Platform" +#define MYGUI_PLATFORM_LOG_FILENAME "MyGUI.log" +#define MYGUI_PLATFORM_LOG(level, text) MYGUI_LOGGING(MYGUI_PLATFORM_LOG_SECTION, level, text) + +#define MYGUI_PLATFORM_EXCEPT(dest) \ +do { \ + MYGUI_PLATFORM_LOG(Critical, dest); \ + std::ostringstream stream; \ + stream << dest << "\n"; \ + MYGUI_BASE_EXCEPT(stream.str().c_str(), "MyGUI"); \ +} while (false) + +#define MYGUI_PLATFORM_ASSERT(exp, dest) \ +do { \ + if ( ! (exp) ) \ + { \ + MYGUI_PLATFORM_LOG(Critical, dest); \ + std::ostringstream stream; \ + stream << dest << "\n"; \ + MYGUI_BASE_EXCEPT(stream.str().c_str(), "MyGUI"); \ + } \ +} while (false) + +#endif // MYGUI_SDL2_DIAGNOSTIC_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2ImageLoader.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2ImageLoader.h new file mode 100644 index 000000000..8926c6fd7 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2ImageLoader.h @@ -0,0 +1,35 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 + @module +*/ + +#ifndef MYGUI_SDL2_IMAGE_LOADER_H_ +#define MYGUI_SDL2_IMAGE_LOADER_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_RenderFormat.h" + +#include +#include + +namespace MyGUI +{ + class SDL2ImageLoader + { + public: + virtual ~SDL2ImageLoader() { } + + virtual SDL_Texture* loadTexture(const std::string& _filename) = 0; + virtual void saveImage( + int _width, + int _height, + MyGUI::PixelFormat _format, + void* _texture, + const std::string& _filename) = 0; + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_IMAGE_LOADER_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Platform.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Platform.h new file mode 100644 index 000000000..1ef9e9d08 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Platform.h @@ -0,0 +1,75 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_PLATFORM_H_ +#define MYGUI_SDL2_PLATFORM_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_SDL2RenderManager.h" +#include "MyGUI_SDL2DataManager.h" +#include "MyGUI_SDL2Diagnostic.h" +#include "MyGUI_LogManager.h" + +namespace MyGUI +{ + + class SDL2Platform + { + public: + SDL2Platform() : + mLogManager(nullptr), + mRenderManager(nullptr), + mDataManager(nullptr) + { + mLogManager = new LogManager(); + mRenderManager = new SDL2RenderManager(); + mDataManager = new SDL2DataManager(); + } + + ~SDL2Platform() + { + delete mRenderManager; + mRenderManager = nullptr; + delete mDataManager; + mDataManager = nullptr; + delete mLogManager; + mLogManager = nullptr; + } + + void initialise(SDL2ImageLoader *loader, SDL_Renderer *renderer, const std::string& _logName = MYGUI_PLATFORM_LOG_FILENAME) + { + if (!_logName.empty()) + LogManager::getInstance().createDefaultSource(_logName); + + mRenderManager->initialise(loader, renderer); + mDataManager->initialise(); + } + + void shutdown() + { + mRenderManager->shutdown(); + mDataManager->shutdown(); + } + + SDL2RenderManager* getRenderManagerPtr() + { + return mRenderManager; + } + + SDL2DataManager* getDataManagerPtr() + { + return mDataManager; + } + + private: + SDL2RenderManager* mRenderManager; + SDL2DataManager* mDataManager; + LogManager* mLogManager; + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_PLATFORM_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2RenderManager.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2RenderManager.h new file mode 100644 index 000000000..6df2517e1 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2RenderManager.h @@ -0,0 +1,109 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_RENDER_MANAGER_H_ +#define MYGUI_SDL2_RENDER_MANAGER_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_RenderFormat.h" +#include "MyGUI_RenderManager.h" + +#include +#include + +namespace MyGUI +{ + class SDL2ImageLoader; + + class SDL2RenderManager : + public RenderManager, + public IRenderTarget + { + public: + SDL2RenderManager(); + + void initialise(SDL2ImageLoader *loader, SDL_Renderer *renderer); + void shutdown(); + + static SDL2RenderManager& getInstance() + { + return *getInstancePtr(); + } + static SDL2RenderManager* getInstancePtr() + { + return static_cast(RenderManager::getInstancePtr()); + } + + /** @see RenderManager::getViewSize */ + const IntSize& getViewSize() const override + { + return mViewSize; + } + + /** @see RenderManager::getVertexFormat */ + VertexColourType getVertexFormat() const override + { + return VertexColourType::ColourARGB; + } + + /** @see RenderManager::createVertexBuffer */ + IVertexBuffer* createVertexBuffer() override; + /** @see RenderManager::destroyVertexBuffer */ + void destroyVertexBuffer(IVertexBuffer* _buffer) override; + + /** @see RenderManager::createTexture */ + ITexture* createTexture(const std::string& _name) override; + /** @see RenderManager::destroyTexture */ + void destroyTexture(ITexture* _texture) override; + /** @see RenderManager::getTexture */ + ITexture* getTexture(const std::string& _name) override; + + /** @see RenderManager::isFormatSupported */ + bool isFormatSupported(PixelFormat _format, TextureUsage _usage) override; + + /** @see IRenderTarget::begin */ + void begin() override; + /** @see IRenderTarget::end */ + void end() override; + + /** @see IRenderTarget::doRender */ + void doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count) override; + + /** @see IRenderTarget::getInfo */ + const RenderTargetInfo& getInfo() const override + { + return mInfo; + } + + /** @see RenderManager::setViewSize */ + void setViewSize(int _width, int _height) override; + + void registerShader( + const std::string& _shaderName, + const std::string& _vertexProgramFile, + const std::string& _fragmentProgramFile) override + { + } + + /*internal:*/ + void drawOneFrame(); + + private: + typedef std::map MapTexture; + MapTexture mTextures; + + IntSize mViewSize; + RenderTargetInfo mInfo; + + SDL2ImageLoader* mImageLoader; + SDL_Renderer *mRenderer; + + void destroyAllResources(); + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_RENDER_MANAGER_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Texture.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Texture.h new file mode 100644 index 000000000..998816fe8 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2Texture.h @@ -0,0 +1,83 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_TEXTURE_H_ +#define MYGUI_SDL2_TEXTURE_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_ITexture.h" +#include "MyGUI_RenderFormat.h" +#include "MyGUI_SDL2ImageLoader.h" + +#include + +namespace MyGUI +{ + + class SDL2RenderManager; + class SDL2RTTexture; + + class SDL2Texture : public ITexture + { + public: + SDL2Texture(const std::string& _name, SDL2ImageLoader* _loader, SDL2RenderManager *_manager, SDL_Renderer *renderer); + ~SDL2Texture() override; + + const std::string& getName() const override; + + void createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format) override; + void loadFromFile(const std::string& _filename) override; + void saveToFile(const std::string& _filename) override; + void setShader(const std::string& _shaderName) override; + + void destroy() override; + + int getWidth() const override; + int getHeight() const override; + + void* lock(TextureUsage _access) override; + void unlock() override; + bool isLocked() const override; + + PixelFormat getFormat() const override; + TextureUsage getUsage() const override; + size_t getNumElemBytes() const override; + + IRenderTarget* getRenderTarget() override; + + /*internal:*/ + SDL_Texture * getTexture() const { return mTexture; } + + void createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format, void* _data); + + private: + void _create(); + + private: + std::string mName; + int mWidth; + int mHeight; + SDL_PixelFormatEnum mPixelFormat; + int mInternalPixelFormat; + int mUsage; + int mAccess; + size_t mNumElemBytes; + size_t mDataSize; + unsigned int mPboID; + bool mLock; + void* mBuffer; + PixelFormat mOriginalFormat; + TextureUsage mOriginalUsage; + SDL2ImageLoader* mImageLoader; + SDL2RTTexture* mRenderTarget; + + SDL_Renderer *mRenderer; + SDL_Texture *mTexture; + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_TEXTURE_H_ diff --git a/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2VertexBuffer.h b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2VertexBuffer.h new file mode 100644 index 000000000..dade38d69 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/include/MyGUI_SDL2VertexBuffer.h @@ -0,0 +1,53 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#ifndef MYGUI_SDL2_VERTEX_BUFFER_H_ +#define MYGUI_SDL2_VERTEX_BUFFER_H_ + +#include "MyGUI_Prerequest.h" +#include "MyGUI_IVertexBuffer.h" + +#include +#include + +namespace MyGUI +{ + + class SDL2VertexBuffer : public IVertexBuffer + { + public: + SDL2VertexBuffer(); + ~SDL2VertexBuffer() override; + + void setVertexCount(size_t _count) override; + size_t getVertexCount() const override; + + Vertex* lock() override; + void unlock() override; + + /*internal:*/ + SDL_Vertex* getVertices() { + return mVertices.data(); + } + + private: + void create(); + void destroy(); + void resize(); + + private: + size_t mVertexCount; + size_t mNeedVertexCount; + size_t mSizeInBytes; + + Vertex *mInternalData; + + std::vector mVertices; + }; + +} // namespace MyGUI + +#endif // MYGUI_SDL2_VERTEX_BUFFER_H_ diff --git a/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2DataManager.cpp b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2DataManager.cpp new file mode 100644 index 000000000..9d8246df8 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2DataManager.cpp @@ -0,0 +1,129 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#include "MyGUI_SDL2DataManager.h" +#include "MyGUI_SDL2Diagnostic.h" +#include "MyGUI_DataFileStream.h" +#include "FileSystemInfo/FileSystemInfo.h" + +#include + +namespace MyGUI +{ + + SDL2DataManager::SDL2DataManager() + { + } + + void SDL2DataManager::initialise() + { + MYGUI_PLATFORM_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); + MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName()); + + MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized"); + + mIsInitialise = true; + } + + void SDL2DataManager::shutdown() + { + MYGUI_PLATFORM_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); + MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName()); + + MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown"); + mIsInitialise = false; + } + + IDataStream* SDL2DataManager::getData(const std::string& _name) const + { + std::string filepath = getDataPath(_name); + if (filepath.empty()) + return nullptr; + + std::ifstream* stream = new std::ifstream(); + stream->open(filepath.c_str(), std::ios_base::binary); + + if (!stream->is_open()) + { + delete stream; + return nullptr; + } + + auto *data = new DataFileStream(stream); + + return data; + } + + void SDL2DataManager::freeData(IDataStream* _data) + { + delete _data; + } + + bool SDL2DataManager::isDataExist(const std::string& _name) const + { + const VectorString& files = getDataListNames(_name); + return !files.empty(); + } + + const VectorString& SDL2DataManager::getDataListNames(const std::string& _pattern) const + { + static VectorString result; + common::VectorWString wresult; + result.clear(); + + for (VectorArhivInfo::const_iterator item = mPaths.begin(); item != mPaths.end(); ++item) + { + common::scanFolder(wresult, (*item).name, (*item).recursive, MyGUI::UString(_pattern).asWStr(), false); + } + + for (common::VectorWString::const_iterator item = wresult.begin(); item != wresult.end(); ++item) + { + result.push_back(MyGUI::UString(*item).asUTF8()); + } + + return result; + } + + const std::string& SDL2DataManager::getDataPath(const std::string& _name) const + { + static std::string path; + VectorString result; + common::VectorWString wresult; + path.clear(); + + for (VectorArhivInfo::const_iterator item = mPaths.begin(); item != mPaths.end(); ++item) + { + common::scanFolder(wresult, (*item).name, (*item).recursive, MyGUI::UString(_name).asWStr(), true); + } + + for (common::VectorWString::const_iterator item = wresult.begin(); item != wresult.end(); ++item) + { + result.push_back(MyGUI::UString(*item).asUTF8()); + } + + if (!result.empty()) + { + path = result[0]; + if (result.size() > 1) + { + MYGUI_PLATFORM_LOG(Warning, "There are several files with name '" << _name << "'. '" << path << "' was used."); + MYGUI_PLATFORM_LOG(Warning, "Other candidates are:"); + for (size_t index = 1; index < result.size(); index++) + MYGUI_PLATFORM_LOG(Warning, " - '" << result[index] << "'"); + } + } + + return path; + } + + void SDL2DataManager::addResourceLocation(const std::string& _name, bool _recursive) + { + ArhivInfo info; + info.name = MyGUI::UString(_name).asWStr(); + info.recursive = _recursive; + mPaths.push_back(info); + } +} // namespace MyGUI diff --git a/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2RenderManager.cpp b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2RenderManager.cpp new file mode 100644 index 000000000..aba7f755f --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2RenderManager.cpp @@ -0,0 +1,141 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#include "MyGUI_SDL2RenderManager.h" +#include "MyGUI_SDL2Diagnostic.h" +#include "MyGUI_Gui.h" +#include "MyGUI_Timer.h" +#include "MyGUI_SDL2Texture.h" +#include "MyGUI_SDL2VertexBuffer.h" + +#include +#if !SDL_VERSION_ATLEAST(2,0,17) +#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function +#endif + +namespace MyGUI +{ + + SDL2RenderManager::SDL2RenderManager() : mImageLoader(nullptr) + { + } + + void SDL2RenderManager::initialise(SDL2ImageLoader *loader, SDL_Renderer *renderer) + { + MYGUI_PLATFORM_LOG(Info, "* Initialise: " << getClassTypeName()); + + MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully initialized"); + + mImageLoader = loader; + mRenderer = renderer; + } + + void SDL2RenderManager::shutdown() + { + MYGUI_PLATFORM_LOG(Info, "* Shutdown: " << getClassTypeName()); + + MYGUI_PLATFORM_LOG(Info, getClassTypeName() << " successfully shutdown"); + + destroyAllResources(); + } + + IVertexBuffer* SDL2RenderManager::createVertexBuffer() + { + return new SDL2VertexBuffer(); + } + + void SDL2RenderManager::destroyVertexBuffer(IVertexBuffer* _buffer) + { + delete _buffer; + } + + void SDL2RenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count) + { + MYGUI_ASSERT(_texture != nullptr, "Rendering without texture is not supported"); + + auto* buffer = static_cast(_buffer); + auto* texture = static_cast(_texture); + + SDL_RenderGeometry(mRenderer, texture->getTexture(), buffer->getVertices(), _count, nullptr, 0); + } + + void SDL2RenderManager::drawOneFrame() + { + Gui* gui = Gui::getInstancePtr(); + if (gui == nullptr) + return; + + static Timer timer; + static unsigned long last_time = timer.getMilliseconds(); + unsigned long now_time = timer.getMilliseconds(); + unsigned long time = now_time - last_time; + + onFrameEvent(time / 1000.0f); + + last_time = now_time; + + begin(); + onRenderToTarget(this, false); + end(); + } + + void SDL2RenderManager::begin() + { + } + + void SDL2RenderManager::end() + { + } + + ITexture* SDL2RenderManager::createTexture(const std::string& _name) + { + MapTexture::const_iterator item = mTextures.find(_name); + MYGUI_PLATFORM_ASSERT(item == mTextures.end(), "Texture '" << _name << "' already exist"); + + SDL2Texture* texture = new SDL2Texture(_name, mImageLoader, this, mRenderer); + mTextures[_name] = texture; + return texture; + } + + void SDL2RenderManager::destroyTexture(ITexture* _texture) + { + if (_texture == nullptr) + return; + + MapTexture::iterator item = mTextures.find(_texture->getName()); + MYGUI_PLATFORM_ASSERT(item != mTextures.end(), "Texture '" << _texture->getName() << "' not found"); + + mTextures.erase(item); + delete _texture; + } + + ITexture* SDL2RenderManager::getTexture(const std::string& _name) + { + MapTexture::const_iterator item = mTextures.find(_name); + if (item == mTextures.end()) + return nullptr; + return item->second; + } + + bool SDL2RenderManager::isFormatSupported(PixelFormat _format, TextureUsage _usage) + { + return _format == PixelFormat::R8G8B8 || _format == PixelFormat::R8G8B8A8; + } + + void SDL2RenderManager::setViewSize(int _width, int _height) + { + mViewSize.set(_width, _height); + onResizeView(mViewSize); + } + + void SDL2RenderManager::destroyAllResources() { + for (MapTexture::const_iterator item = mTextures.begin(); item != mTextures.end(); ++item) { + delete item->second; + } + mTextures.clear(); + } + +} // namespace MyGUI diff --git a/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2Texture.cpp b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2Texture.cpp new file mode 100644 index 000000000..99c977f1f --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2Texture.cpp @@ -0,0 +1,291 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#include "MyGUI_SDL2Texture.h" +#include "MyGUI_SDL2RenderManager.h" +#include "MyGUI_SDL2Diagnostic.h" +#include "MyGUI_SDL2Platform.h" + +namespace MyGUI +{ + + SDL2Texture::SDL2Texture(const std::string& _name, SDL2ImageLoader* _loader, SDL2RenderManager *_manager, SDL_Renderer *renderer) : + mName(_name), + mWidth(0), + mHeight(0), + mPixelFormat(SDL_PIXELFORMAT_UNKNOWN), + mInternalPixelFormat(0), + mUsage(0), + mAccess(0), + mNumElemBytes(0), + mDataSize(0), + mPboID(0), + mLock(false), + mBuffer(nullptr), + mImageLoader(_loader), + mRenderTarget(nullptr), + mRenderer(renderer), + mTexture(nullptr) + { + } + + SDL2Texture::~SDL2Texture() + { + destroy(); + } + + const std::string& SDL2Texture::getName() const + { + return mName; + } + + void SDL2Texture::createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format) + { + createManual(_width, _height, _usage, _format, nullptr); + } + + void SDL2Texture::createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format, void* _data) + { + MYGUI_PLATFORM_ASSERT((_data == nullptr && mTexture) || !mTexture, "Texture already exist"); + + if (!mTexture) { + mInternalPixelFormat = 0; + mPixelFormat = SDL_PIXELFORMAT_UNKNOWN; + mNumElemBytes = 0; + if (_format == PixelFormat::R8G8B8) { + mPixelFormat = SDL_PIXELFORMAT_BGR24; + mNumElemBytes = 3; + } else if (_format == PixelFormat::R8G8B8A8) { + mPixelFormat = SDL_PIXELFORMAT_BGRA32; + mNumElemBytes = 4; + } else { + MYGUI_PLATFORM_EXCEPT("Format not supported"); + } + + mWidth = _width; + mHeight = _height; + mDataSize = _width * _height * mNumElemBytes; + //MYGUI_PLATFORM_ASSERT(mUsage, "usage format not support"); + + mOriginalFormat = _format; + mOriginalUsage = _usage; + + int access = 0; + if (_usage.isValue(TextureUsage::RenderTarget)) { + access = SDL_TEXTUREACCESS_TARGET; + } else if (_usage.isValue(TextureUsage::Stream)) { + access = SDL_TEXTUREACCESS_STREAMING; + } else if (_usage.isValue(TextureUsage::Static)) { + access = SDL_TEXTUREACCESS_STATIC; + } + + mTexture = SDL_CreateTexture(mRenderer, mPixelFormat, access, _width, _height); + + char* pixels = nullptr; + int pitch; + if (access == SDL_TEXTUREACCESS_STREAMING) { + SDL_LockTexture(mTexture, nullptr, (void **) &pixels, &pitch); + // FIXME: This is actually incorrect, pitch can be > width + memcpy(pixels, _data, pitch * _height); + SDL_UnlockTexture(mTexture); + } else { + SDL_UpdateTexture(mTexture, nullptr, _data, _width * mNumElemBytes); + } + } + + SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND); + SDL_SetTextureScaleMode(mTexture, SDL_ScaleModeBest); + } + + void SDL2Texture::destroy() + { + if (mRenderTarget != nullptr) + { + delete mRenderTarget; + mRenderTarget = nullptr; + } + + if (mTexture != nullptr) + { + SDL_DestroyTexture(mTexture); + mTexture = nullptr; + } + + mWidth = 0; + mHeight = 0; + mLock = false; + mPixelFormat = SDL_PIXELFORMAT_UNKNOWN; + mDataSize = 0; + mUsage = 0; + mBuffer = nullptr; + mInternalPixelFormat = 0; + mAccess = 0; + mNumElemBytes = 0; + mOriginalFormat = PixelFormat::Unknow; + mOriginalUsage = TextureUsage::Default; + } + + void* SDL2Texture::lock(TextureUsage _access) + { + MYGUI_PLATFORM_ASSERT(mTexture, "Texture is not created"); + + if (_access == TextureUsage::Read) + { + mBuffer = nullptr; + // FIXME: This actually doesn't work, because the texture needs to be streaming for this to work, and because this will not necessarily return the actual texture data. The only way is keeping a copy of the texture data around, which is wasteful, so I haven't implemented that yet... + SDL_LockTexture(mTexture, nullptr, &mBuffer, nullptr); + + mLock = true; + + return mBuffer; + } + + if (mAccess == TextureUsage::Stream) { + mBuffer = nullptr; + SDL_LockTexture(mTexture, nullptr, &mBuffer, nullptr); + mLock = true; + } else { + mBuffer = new char[mDataSize]; + } + return mBuffer; + } + + void SDL2Texture::unlock() + { + if (mLock) + { + SDL_UnlockTexture(mTexture); + + return; + } + + auto result = SDL_UpdateTexture(mTexture, nullptr, mBuffer, mWidth * mNumElemBytes); + if (result != 0) { + MYGUI_PLATFORM_EXCEPT("Error updating texture: " << SDL_GetError()); + } + delete[] mBuffer; + +// if (!SDL2RenderManager::getInstance().isPixelBufferObjectSupported()) +// { +// //Fallback if PBO's are not supported +// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, mPixelFormat, GL_UNSIGNED_BYTE, mBuffer); +// delete[] (char*)mBuffer; +// } +// else +// { +// // release the mapped buffer +// glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); +// +// // copy pixels from PBO to texture object +// // Use offset instead of ponter. +// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mWidth, mHeight, mPixelFormat, GL_UNSIGNED_BYTE, nullptr); +// +// // it is good idea to release PBOs with ID 0 after use. +// // Once bound with 0, all pixel operations are back to normal ways. +// glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); +// } +// +// glBindTexture(GL_TEXTURE_2D, 0); +// mBuffer = nullptr; +// mLock = false; + } + + void SDL2Texture::loadFromFile(const std::string& _filename) + { + destroy(); + + if (mImageLoader) + { + mTexture = mImageLoader->loadTexture(_filename); + if (mTexture) + { + uint32_t format; + int access; + SDL_QueryTexture(mTexture, &format, &access, &mWidth, &mHeight); + PixelFormat pixelFormat; + switch (format) { + case SDL_PIXELFORMAT_RGBA8888: + case SDL_PIXELFORMAT_BGRA8888: + case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_ARGB8888: + mNumElemBytes = 4; + pixelFormat = PixelFormat::R8G8B8A8; + break; + case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_BGR888: + mNumElemBytes = 3; + pixelFormat = PixelFormat::R8G8B8; + break; + default: + MYGUI_PLATFORM_EXCEPT("Unsupported texture format '" << SDL_GetPixelFormatName(format) << "'"); + } + mPixelFormat = static_cast(format); + + mDataSize = mWidth * mHeight * mNumElemBytes; + + createManual(mWidth, mHeight, TextureUsage::Static | TextureUsage::Write, pixelFormat); + } + } + } + + void SDL2Texture::saveToFile(const std::string& _filename) + { + if (mImageLoader) + { + void* data = lock(TextureUsage::Read); + mImageLoader->saveImage(mWidth, mHeight, mOriginalFormat, data, _filename); + unlock(); + } + } + + void SDL2Texture::setShader(const std::string& _shaderName) + { + MYGUI_PLATFORM_LOG(Warning, "SDL2Texture::setShader is not implemented (for shader '" << _shaderName << "')"); + } + + IRenderTarget* SDL2Texture::getRenderTarget() + { + MYGUI_PLATFORM_LOG(Warning, "SDL2Texture::getRenderTarget is not implemented"); + // TODO +// if (mRenderTarget == nullptr) +// mRenderTarget = new SDL2RTTexture(mTextureId); +// +// return mRenderTarget; + + return nullptr; + } + + int SDL2Texture::getWidth() const + { + return mWidth; + } + + int SDL2Texture::getHeight() const + { + return mHeight; + } + + bool SDL2Texture::isLocked() const + { + return mLock; + } + + PixelFormat SDL2Texture::getFormat() const + { + return mOriginalFormat; + } + + TextureUsage SDL2Texture::getUsage() const + { + return mOriginalUsage; + } + + size_t SDL2Texture::getNumElemBytes() const + { + return mNumElemBytes; + } + +} // namespace MyGUI diff --git a/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2VertexBuffer.cpp b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2VertexBuffer.cpp new file mode 100644 index 000000000..5a6126843 --- /dev/null +++ b/Platforms/SDL2/SDL2Platform/src/MyGUI_SDL2VertexBuffer.cpp @@ -0,0 +1,107 @@ +/*! + @file + @author A. Eduardo Garcia Hdez + @date 03/2022 +*/ + +#include "MyGUI_SDL2VertexBuffer.h" +#include "MyGUI_SDL2Diagnostic.h" + +namespace MyGUI +{ + + const size_t VERTEX_BUFFER_REALLOCK_STEP = 5 * VertexQuad::VertexCount; + + SDL2VertexBuffer::SDL2VertexBuffer() : + mVertexCount(0), + mNeedVertexCount(0), + mSizeInBytes(0), + mInternalData(nullptr) + { + } + + SDL2VertexBuffer::~SDL2VertexBuffer() + { + destroy(); + } + + void SDL2VertexBuffer::setVertexCount(size_t _count) + { + mNeedVertexCount = _count; + } + + size_t SDL2VertexBuffer::getVertexCount() const + { + return mNeedVertexCount; + } + + Vertex* SDL2VertexBuffer::lock() + { + if (mNeedVertexCount > mVertexCount || mVertexCount == 0) + resize(); + + MYGUI_PLATFORM_ASSERT(mInternalData, "Vertex buffer in not created"); + +// // Use glMapBuffer +// glBindBuffer(GL_ARRAY_BUFFER, mBufferID); +// +// // Discard the buffer +// glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, nullptr, GL_STREAM_DRAW); +// +// Vertex* pBuffer = reinterpret_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); + +// MYGUI_PLATFORM_ASSERT(pBuffer, "Error lock vertex buffer"); + +// glBindBuffer(GL_ARRAY_BUFFER, 0); + + return mInternalData; + } + + inline uint32_t fromBGRA(uint32_t color) { + return ((color & 0x000000FF) << 16) | + ((color & 0x00FF0000) >> 16) | + (color & 0xFF00FF00); + } + + void SDL2VertexBuffer::unlock() + { + MYGUI_PLATFORM_ASSERT(mInternalData, "Vertex buffer in not created"); + + for (int j = 0; j < mVertexCount; ++j) { + auto &vertex = mVertices[j]; + auto &otherVertex = mInternalData[j]; + vertex.position = {otherVertex.x, -otherVertex.y}; + *(uint32_t*)&vertex.color = fromBGRA(otherVertex.colour); + vertex.tex_coord = {otherVertex.u, otherVertex.v}; + } + +// MYGUI_PLATFORM_ASSERT(result, "Error unlock vertex buffer"); + } + + void SDL2VertexBuffer::create() + { + MYGUI_PLATFORM_ASSERT(!mInternalData, "Vertex buffer already exist"); + + mSizeInBytes = mVertexCount * sizeof(Vertex); + mInternalData = new Vertex[mVertexCount]; + mVertices.resize(mVertexCount); + } + + void SDL2VertexBuffer::destroy() + { + if (mInternalData != nullptr) + { + delete[] mInternalData; + mInternalData = nullptr; + } + mVertices.resize(0); + } + + void SDL2VertexBuffer::resize() + { + mVertexCount = mNeedVertexCount + VERTEX_BUFFER_REALLOCK_STEP; + destroy(); + create(); + } + +} // namespace MyGUI