diff --git a/cocos/platform/CCImage.cpp b/cocos/platform/CCImage.cpp index 18f99e5f7c..6eab37e61d 100644 --- a/cocos/platform/CCImage.cpp +++ b/cocos/platform/CCImage.cpp @@ -471,7 +471,7 @@ Image::~Image() { if(_unpack) { - for (unsigned int i = 0; i < _numberOfMipmaps; ++i) + for (int i = 0; i < _numberOfMipmaps; ++i) CC_SAFE_DELETE_ARRAY(_mipmaps[i].address); } else @@ -1727,14 +1727,17 @@ bool Image::initWithTGAData(tImageTGA* tgaData) if (ret) { - const unsigned char tgaSuffix[] = ".tga"; - for(int i = 0; i < 4; ++i) + if (_filePath.length() > 0) { - if (tolower(_filePath[_filePath.length() - i - 1]) != tgaSuffix[3 - i]) + const unsigned char tgaSuffix [] = ".tga"; + for (int i = 0; i < 4; ++i) { - CCLOG("Image WARNING: the image file suffix is not tga, but parsed as a tga image file. FILE: %s", _filePath.c_str()); - break; - }; + if (tolower(_filePath[_filePath.length() - i - 1]) != tgaSuffix[3 - i]) + { + CCLOG("Image WARNING: the image file suffix is not tga, but parsed as a tga image file. FILE: %s", _filePath.c_str()); + break; + }; + } } } else diff --git a/cocos/platform/CCPlatformMacros.h b/cocos/platform/CCPlatformMacros.h index 455f7c0cf2..0f0afdfe9c 100644 --- a/cocos/platform/CCPlatformMacros.h +++ b/cocos/platform/CCPlatformMacros.h @@ -82,7 +82,7 @@ to be different from other platforms unless there's a good reason. It's new in cocos2d-x since v0.99.5 */ -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) #define CC_ENABLE_CACHE_TEXTURE_DATA 1 #else #define CC_ENABLE_CACHE_TEXTURE_DATA 0 diff --git a/cocos/platform/win8.1-universal/Cocos2dRenderer.cpp b/cocos/platform/win8.1-universal/Cocos2dRenderer.cpp index e25f12576e..1557e6dd08 100644 --- a/cocos/platform/win8.1-universal/Cocos2dRenderer.cpp +++ b/cocos/platform/win8.1-universal/Cocos2dRenderer.cpp @@ -21,6 +21,7 @@ #include "CCGLViewImpl-winrt.h" #include "CCApplication.h" #include "cocos2d.h" +#include "renderer/CCTextureCache.h" // These are used by the shader compilation methods. #include @@ -44,14 +45,6 @@ Cocos2dRenderer::Cocos2dRenderer(int width, int height, float dpi, CoreDispatche , m_panel(panel) { m_app = new AppDelegate(); - auto director = cocos2d::Director::getInstance(); - - GLViewImpl* glview = GLViewImpl::create("Test Cpp"); - glview->setDispatcher(dispatcher); - glview->setPanel(panel); - glview->Create(static_cast(width), static_cast(height), dpi, DisplayOrientations::Landscape); - director->setOpenGLView(glview); - CCApplication::getInstance()->run(); } Cocos2dRenderer::~Cocos2dRenderer() @@ -59,7 +52,58 @@ Cocos2dRenderer::~Cocos2dRenderer() delete m_app; } -// Draws a basic triangle +void Cocos2dRenderer::Resume() +{ + auto director = cocos2d::Director::getInstance(); + auto glview = director->getOpenGLView(); + + if (!glview) + { + GLViewImpl* glview = GLViewImpl::create("Test Cpp"); + glview->setDispatcher(m_dispatcher.Get()); + glview->setPanel(m_panel.Get()); + glview->Create(static_cast(m_width), static_cast(m_height), m_dpi, DisplayOrientations::Landscape); + director->setOpenGLView(glview); + CCApplication::getInstance()->run(); + } + else + { + Application::getInstance()->applicationWillEnterForeground(); + } +} + +void Cocos2dRenderer::Pause() +{ + if (Director::getInstance()->getOpenGLView()) { + Application::getInstance()->applicationDidEnterBackground(); + //cocos2d::EventCustom backgroundEvent(EVENT_COME_TO_BACKGROUND); + //cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&backgroundEvent); + } +} + +void Cocos2dRenderer::DeviceLost() +{ + Pause(); + + auto director = cocos2d::Director::getInstance(); + if (director->getOpenGLView()) { + cocos2d::GL::invalidateStateCache(); + cocos2d::GLProgramCache::getInstance()->reloadDefaultGLPrograms(); + cocos2d::DrawPrimitives::init(); + cocos2d::VolatileTextureMgr::reloadAllTextures(); + + cocos2d::EventCustom recreatedEvent(EVENT_RENDERER_RECREATED); + director->getEventDispatcher()->dispatchEvent(&recreatedEvent); + director->setGLDefaultValues(); + + Application::getInstance()->applicationWillEnterForeground(); + cocos2d::EventCustom foregroundEvent(EVENT_COME_TO_FOREGROUND); + cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&foregroundEvent); + } +} + + + void Cocos2dRenderer::Draw(GLsizei width, GLsizei height, float dpi) { if (width != m_width || height != m_height) diff --git a/cocos/platform/win8.1-universal/Cocos2dRenderer.h b/cocos/platform/win8.1-universal/Cocos2dRenderer.h index b8d63d60b1..dc7696ff70 100644 --- a/cocos/platform/win8.1-universal/Cocos2dRenderer.h +++ b/cocos/platform/win8.1-universal/Cocos2dRenderer.h @@ -34,7 +34,10 @@ namespace cocos2d void Draw(GLsizei width, GLsizei height, float dpi); void QueuePointerEvent(PointerEventType type, Windows::UI::Core::PointerEventArgs^ args); void QueueKeyBoardEvent(Cocos2dKeyEvent type, Windows::UI::Core::KeyEventArgs^ e); - + void Pause(); + void Resume(); + void DeviceLost(); + private: int m_width; diff --git a/cocos/platform/win8.1-universal/OpenGLESPage.xaml.cpp b/cocos/platform/win8.1-universal/OpenGLESPage.xaml.cpp index 71f3c692e9..a3dd3d7bba 100644 --- a/cocos/platform/win8.1-universal/OpenGLESPage.xaml.cpp +++ b/cocos/platform/win8.1-universal/OpenGLESPage.xaml.cpp @@ -48,7 +48,8 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : mCustomRenderSurfaceSize(0,0), mUseCustomRenderSurfaceSize(false), m_coreInput(nullptr), - m_dpi(0.0f) + m_dpi(0.0f), + m_deviceLost(false) { InitializeComponent(); @@ -209,7 +210,6 @@ void OpenGLESPage::RecoverFromLostDevice() { critical_section::scoped_lock lock(mRenderSurfaceCriticalSection); - DestroyRenderSurface(); mOpenGLES->Reset(); CreateRenderSurface(); @@ -249,9 +249,19 @@ void OpenGLESPage::StartRenderLoop() m_renderer = std::make_shared(panelWidth, panelHeight, m_dpi, dispatcher, swapChainPanel); } - while (action->Status == Windows::Foundation::AsyncStatus::Started) + if (m_deviceLost) + { + m_deviceLost = false; + m_renderer->DeviceLost(); + } + else + { + m_renderer->Resume(); + } + + + while (action->Status == Windows::Foundation::AsyncStatus::Started && !m_deviceLost) { - GetSwapChainPanelSize(&panelWidth, &panelHeight); m_renderer.get()->Draw(panelWidth, panelHeight, m_dpi); @@ -259,9 +269,10 @@ void OpenGLESPage::StartRenderLoop() // If the call fails, then we must reinitialize EGL and the GL resources. if (mOpenGLES->SwapBuffers(mRenderSurface) != GL_TRUE) { + m_deviceLost = true; + // XAML objects like the SwapChainPanel must only be manipulated on the UI thread. swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([=]() - //swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([=]() { RecoverFromLostDevice(); }, CallbackContext::Any)); @@ -282,4 +293,9 @@ void OpenGLESPage::StopRenderLoop() mRenderLoopWorker->Cancel(); mRenderLoopWorker = nullptr; } + + if (m_renderer) + { + m_renderer->Pause(); + } } \ No newline at end of file diff --git a/cocos/platform/win8.1-universal/OpenGLESPage.xaml.h b/cocos/platform/win8.1-universal/OpenGLESPage.xaml.h index 9b65e475b3..0f30cce0fb 100644 --- a/cocos/platform/win8.1-universal/OpenGLESPage.xaml.h +++ b/cocos/platform/win8.1-universal/OpenGLESPage.xaml.h @@ -69,5 +69,7 @@ namespace cocos2d void OnPointerReleased(Platform::Object^ sender, Windows::UI::Core::PointerEventArgs^ e); float m_dpi; + bool m_deviceLost; + }; } diff --git a/cocos/platform/winrt/CCApplication.cpp b/cocos/platform/winrt/CCApplication.cpp index caa182f877..addcb471a9 100644 --- a/cocos/platform/winrt/CCApplication.cpp +++ b/cocos/platform/winrt/CCApplication.cpp @@ -25,6 +25,9 @@ THE SOFTWARE. #include "platform/CCPlatformConfig.h" #if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT #include "platform/winrt/CCGLViewImpl-winrt.h" +using namespace Windows::UI::Core; +using namespace Windows::Foundation; + #else #include "platform/wp8/CCGLViewImpl-wp8.h" #endif @@ -98,19 +101,32 @@ Application* Application::getInstance() const char * Application::getCurrentLanguageCode() { - static std::string code = ""; + static std::string code = "en"; - wchar_t localeName[LOCALE_NAME_MAX_LENGTH] = {0}; - if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH)) - { - wchar_t* primary = wcstok(localeName, L"-"); - code = CCUnicodeToUtf8(primary); - } - else - { - code = "en"; +#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT + auto languages = Windows::System::UserProfile::GlobalizationPreferences::Languages; + code = PlatformStringToString(languages->GetAt(0)); +#else + ULONG numLanguages = 0; + DWORD cchLanguagesBuffer = 0; + BOOL result = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, NULL, &cchLanguagesBuffer); + + if (result) { + WCHAR* pwszLanguagesBuffer = new WCHAR[cchLanguagesBuffer]; + result = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, pwszLanguagesBuffer, &cchLanguagesBuffer); + if (result) { + + code = CCUnicodeToUtf8(pwszLanguagesBuffer); + } + + if (pwszLanguagesBuffer) + { + delete pwszLanguagesBuffer; + } } + +#endif return code.c_str(); } @@ -121,51 +137,51 @@ LanguageType Application::getCurrentLanguage() const char* code = getCurrentLanguageCode(); - if (strcmp(code, "zh") == 0) + if (strncmp(code, "zh", 2) == 0) { ret = LanguageType::CHINESE; } - else if (strcmp(code, "ja") == 0) + else if (strncmp(code, "ja", 2) == 0) { ret = LanguageType::JAPANESE; } - else if (strcmp(code, "fr") == 0) + else if (strncmp(code, "fr", 2) == 0) { ret = LanguageType::FRENCH; } - else if (strcmp(code, "it") == 0) + else if (strncmp(code, "it", 2) == 0) { ret = LanguageType::ITALIAN; } - else if (strcmp(code, "de") == 0) + else if (strncmp(code, "de", 2) == 0) { ret = LanguageType::GERMAN; } - else if (strcmp(code, "es") == 0) + else if (strncmp(code, "es", 2) == 0) { ret = LanguageType::SPANISH; } - else if (strcmp(code, "nl") == 0) + else if (strncmp(code, "nl", 2) == 0) { ret = LanguageType::DUTCH; } - else if (strcmp(code, "ru") == 0) + else if (strncmp(code, "ru", 2) == 0) { ret = LanguageType::RUSSIAN; } - else if (strcmp(code, "hu") == 0) + else if (strncmp(code, "hu", 2) == 0) { ret = LanguageType::HUNGARIAN; } - else if (strcmp(code, "pt") == 0) + else if (strncmp(code, "pt", 2) == 0) { ret = LanguageType::PORTUGUESE; } - else if (strcmp(code, "ko") == 0) + else if (strncmp(code, "ko", 2) == 0) { ret = LanguageType::KOREAN; } - else if (strcmp(code, "ar") == 0) + else if (strncmp(code, "ar", 2) == 0) { ret = LanguageType::ARABIC; } @@ -180,6 +196,14 @@ Application::Platform Application::getTargetPlatform() bool Application::openURL(const std::string &url) { +#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT + auto dispatcher = cocos2d::GLViewImpl::sharedOpenGLView()->getDispatcher(); + dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([url]() { + auto uri = ref new Windows::Foundation::Uri(PlatformStringFromString(url)); + concurrency::task launchUriOperation(Windows::System::Launcher::LaunchUriAsync(uri)); + })); + return true; +#else if (m_openURLDelegate) { m_openURLDelegate(PlatformStringFromString(url)); @@ -189,6 +213,7 @@ bool Application::openURL(const std::string &url) { return false; } +#endif } void Application::setResourceRootPath(const std::string& rootResDir) diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index 2006e72a9d..3ecf820113 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -279,7 +279,7 @@ GLProgramState::GLProgramState() , _vertexAttribsFlags(0) , _glprogram(nullptr) { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) /** listen the event that renderer was recreated on Android/WP8 */ CCLOG("create rendererRecreatedListener for GLProgramState"); _backToForegroundlistener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { _uniformAttributeValueDirty = true; }); @@ -289,7 +289,7 @@ GLProgramState::GLProgramState() GLProgramState::~GLProgramState() { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundlistener); #endif diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index d741504a32..6c0a637f8a 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -218,7 +218,7 @@ protected: uint32_t _vertexAttribsFlags; GLProgram *_glprogram; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) EventListenerCustom* _backToForegroundlistener; #endif }; diff --git a/cocos/renderer/CCMeshCommand.cpp b/cocos/renderer/CCMeshCommand.cpp index 96d43291cc..b29f286d6f 100644 --- a/cocos/renderer/CCMeshCommand.cpp +++ b/cocos/renderer/CCMeshCommand.cpp @@ -92,7 +92,7 @@ MeshCommand::MeshCommand() , _lightMask(-1) { _type = RenderCommand::Type::MESH_COMMAND; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) // listen the event that renderer was recreated on Android/WP8 _rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCommand::listenRendererRecreated, this)); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_rendererRecreatedListener, -1); @@ -154,7 +154,7 @@ void MeshCommand::setDisplayColor(const Vec4& color) MeshCommand::~MeshCommand() { releaseVAO(); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener); #endif } @@ -506,7 +506,7 @@ void MeshCommand::resetLightUniformValues() s_spotLightUniformRangeInverseValues.assign(maxSpotLight, 0.0f); } -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) void MeshCommand::listenRendererRecreated(EventCustom* event) { _vao = 0; diff --git a/cocos/renderer/CCMeshCommand.h b/cocos/renderer/CCMeshCommand.h index abdceae309..27e4816eb5 100644 --- a/cocos/renderer/CCMeshCommand.h +++ b/cocos/renderer/CCMeshCommand.h @@ -75,7 +75,7 @@ public: uint32_t getMaterialID() const { return _materialID; } -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) void listenRendererRecreated(EventCustom* event); #endif @@ -129,7 +129,7 @@ protected: unsigned int _lightMask; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) EventListenerCustom* _rendererRecreatedListener; #endif }; diff --git a/cocos/renderer/CCVertexIndexBuffer.cpp b/cocos/renderer/CCVertexIndexBuffer.cpp index c387398f38..ca3d53a2b2 100644 --- a/cocos/renderer/CCVertexIndexBuffer.cpp +++ b/cocos/renderer/CCVertexIndexBuffer.cpp @@ -30,13 +30,13 @@ NS_CC_BEGIN -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) bool VertexBuffer::_enableShadowCopy = true; #else bool VertexBuffer::_enableShadowCopy = false; #endif -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) bool IndexBuffer::_enableShadowCopy = true; #else bool IndexBuffer::_enableShadowCopy = false; @@ -62,7 +62,7 @@ VertexBuffer::VertexBuffer() , _vertexNumber(0) { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) auto callBack = [this](EventCustom* event) { this->recreateVBO(); @@ -80,7 +80,7 @@ VertexBuffer::~VertexBuffer() glDeleteBuffers(1, &_vbo); _vbo = 0; } -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_recreateVBOEventListener); #endif } @@ -189,7 +189,7 @@ IndexBuffer::IndexBuffer() , _indexNumber(0) , _recreateVBOEventListener(nullptr) { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) auto callBack = [this](EventCustom* event) { this->recreateVBO(); @@ -206,7 +206,7 @@ IndexBuffer::~IndexBuffer() glDeleteBuffers(1, &_vbo); _vbo = 0; } -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_recreateVBOEventListener); #endif } diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.cpp b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.cpp index e25f12576e..1557e6dd08 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.cpp +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.cpp @@ -21,6 +21,7 @@ #include "CCGLViewImpl-winrt.h" #include "CCApplication.h" #include "cocos2d.h" +#include "renderer/CCTextureCache.h" // These are used by the shader compilation methods. #include @@ -44,14 +45,6 @@ Cocos2dRenderer::Cocos2dRenderer(int width, int height, float dpi, CoreDispatche , m_panel(panel) { m_app = new AppDelegate(); - auto director = cocos2d::Director::getInstance(); - - GLViewImpl* glview = GLViewImpl::create("Test Cpp"); - glview->setDispatcher(dispatcher); - glview->setPanel(panel); - glview->Create(static_cast(width), static_cast(height), dpi, DisplayOrientations::Landscape); - director->setOpenGLView(glview); - CCApplication::getInstance()->run(); } Cocos2dRenderer::~Cocos2dRenderer() @@ -59,7 +52,58 @@ Cocos2dRenderer::~Cocos2dRenderer() delete m_app; } -// Draws a basic triangle +void Cocos2dRenderer::Resume() +{ + auto director = cocos2d::Director::getInstance(); + auto glview = director->getOpenGLView(); + + if (!glview) + { + GLViewImpl* glview = GLViewImpl::create("Test Cpp"); + glview->setDispatcher(m_dispatcher.Get()); + glview->setPanel(m_panel.Get()); + glview->Create(static_cast(m_width), static_cast(m_height), m_dpi, DisplayOrientations::Landscape); + director->setOpenGLView(glview); + CCApplication::getInstance()->run(); + } + else + { + Application::getInstance()->applicationWillEnterForeground(); + } +} + +void Cocos2dRenderer::Pause() +{ + if (Director::getInstance()->getOpenGLView()) { + Application::getInstance()->applicationDidEnterBackground(); + //cocos2d::EventCustom backgroundEvent(EVENT_COME_TO_BACKGROUND); + //cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&backgroundEvent); + } +} + +void Cocos2dRenderer::DeviceLost() +{ + Pause(); + + auto director = cocos2d::Director::getInstance(); + if (director->getOpenGLView()) { + cocos2d::GL::invalidateStateCache(); + cocos2d::GLProgramCache::getInstance()->reloadDefaultGLPrograms(); + cocos2d::DrawPrimitives::init(); + cocos2d::VolatileTextureMgr::reloadAllTextures(); + + cocos2d::EventCustom recreatedEvent(EVENT_RENDERER_RECREATED); + director->getEventDispatcher()->dispatchEvent(&recreatedEvent); + director->setGLDefaultValues(); + + Application::getInstance()->applicationWillEnterForeground(); + cocos2d::EventCustom foregroundEvent(EVENT_COME_TO_FOREGROUND); + cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&foregroundEvent); + } +} + + + void Cocos2dRenderer::Draw(GLsizei width, GLsizei height, float dpi) { if (width != m_width || height != m_height) diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.h b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.h index b8d63d60b1..dc7696ff70 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.h +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/Cocos2dRenderer.h @@ -34,7 +34,10 @@ namespace cocos2d void Draw(GLsizei width, GLsizei height, float dpi); void QueuePointerEvent(PointerEventType type, Windows::UI::Core::PointerEventArgs^ args); void QueueKeyBoardEvent(Cocos2dKeyEvent type, Windows::UI::Core::KeyEventArgs^ e); - + void Pause(); + void Resume(); + void DeviceLost(); + private: int m_width; diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.cpp b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.cpp index 71f3c692e9..a3dd3d7bba 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.cpp +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.cpp @@ -48,7 +48,8 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : mCustomRenderSurfaceSize(0,0), mUseCustomRenderSurfaceSize(false), m_coreInput(nullptr), - m_dpi(0.0f) + m_dpi(0.0f), + m_deviceLost(false) { InitializeComponent(); @@ -209,7 +210,6 @@ void OpenGLESPage::RecoverFromLostDevice() { critical_section::scoped_lock lock(mRenderSurfaceCriticalSection); - DestroyRenderSurface(); mOpenGLES->Reset(); CreateRenderSurface(); @@ -249,9 +249,19 @@ void OpenGLESPage::StartRenderLoop() m_renderer = std::make_shared(panelWidth, panelHeight, m_dpi, dispatcher, swapChainPanel); } - while (action->Status == Windows::Foundation::AsyncStatus::Started) + if (m_deviceLost) + { + m_deviceLost = false; + m_renderer->DeviceLost(); + } + else + { + m_renderer->Resume(); + } + + + while (action->Status == Windows::Foundation::AsyncStatus::Started && !m_deviceLost) { - GetSwapChainPanelSize(&panelWidth, &panelHeight); m_renderer.get()->Draw(panelWidth, panelHeight, m_dpi); @@ -259,9 +269,10 @@ void OpenGLESPage::StartRenderLoop() // If the call fails, then we must reinitialize EGL and the GL resources. if (mOpenGLES->SwapBuffers(mRenderSurface) != GL_TRUE) { + m_deviceLost = true; + // XAML objects like the SwapChainPanel must only be manipulated on the UI thread. swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([=]() - //swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([=]() { RecoverFromLostDevice(); }, CallbackContext::Any)); @@ -282,4 +293,9 @@ void OpenGLESPage::StopRenderLoop() mRenderLoopWorker->Cancel(); mRenderLoopWorker = nullptr; } + + if (m_renderer) + { + m_renderer->Pause(); + } } \ No newline at end of file diff --git a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.h b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.h index 9b65e475b3..0f30cce0fb 100644 --- a/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.h +++ b/templates/cpp-template-default/proj.win8.1-universal/App.Shared/OpenGLESPage.xaml.h @@ -69,5 +69,7 @@ namespace cocos2d void OnPointerReleased(Platform::Object^ sender, Windows::UI::Core::PointerEventArgs^ e); float m_dpi; + bool m_deviceLost; + }; } diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp index d1b3e324b4..85f53bcfb6 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp @@ -259,13 +259,14 @@ bool ShaderMandelbrot::init() { if (ShaderTestDemo::init()) { +#if CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_WP8 auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Mandelbrot.fsh"); auto s = Director::getInstance()->getWinSize(); sn->setPosition(Vec2(s.width/2, s.height/2)); addChild(sn); - +#endif return true; } @@ -292,13 +293,14 @@ bool ShaderJulia::init() { if (ShaderTestDemo::init()) { +#if CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_WP8 auto sn = ShaderNode::shaderNodeWithVertex("", "Shaders/example_Julia.fsh"); auto s = Director::getInstance()->getWinSize(); sn->setPosition(Vec2(s.width/2, s.height/2)); addChild(sn); - +#endif return true; } @@ -562,6 +564,7 @@ bool ShaderBlur::init() { if( ShaderTestDemo::init() ) { +#if CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_WP8 _blurSprite = SpriteBlur::create("Images/grossini.png"); auto sprite = Sprite::create("Images/grossini.png"); auto s = Director::getInstance()->getWinSize(); @@ -572,7 +575,7 @@ bool ShaderBlur::init() addChild(sprite); createSliderCtls(); - +#endif return true; } diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp index 30c62d2eac..e87220cc79 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp @@ -209,7 +209,7 @@ bool Effect::initGLProgramState(const std::string &fragmentFilename) auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath); auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str()); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) _fragSource = fragSource; #endif @@ -222,7 +222,7 @@ bool Effect::initGLProgramState(const std::string &fragmentFilename) Effect::Effect() : _glprogramstate(nullptr) { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) _backgroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { @@ -240,7 +240,7 @@ Effect::Effect() Effect::~Effect() { CC_SAFE_RELEASE_NULL(_glprogramstate); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_backgroundListener); #endif } diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h index 162ab11a44..52c867628a 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.h @@ -40,7 +40,7 @@ protected: Effect(); virtual ~Effect(); GLProgramState *_glprogramstate; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) std::string _fragSource; EventListenerCustom* _backgroundListener; #endif diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 0dd338e502..23d1b0ee9b 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -536,7 +536,7 @@ Effect3DOutline::Effect3DOutline() , _outlineColor(1, 1, 1) , _sprite(nullptr) { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) _backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { @@ -553,7 +553,7 @@ Effect3DOutline::Effect3DOutline() Effect3DOutline::~Effect3DOutline() { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener); #endif } diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h index 80e471a45b..6a59891bb6 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h @@ -120,7 +120,7 @@ protected: float _outlineWidth; //weak reference EffectSprite3D* _sprite; -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) EventListenerCustom* _backToForegroundListener; #endif