updated cocos2d-x/angle template files to version 0edf96a2f54a43d068244a86aaf9133c1bf71fe5

This commit is contained in:
Dale Stammen 2015-10-16 15:36:34 -07:00
parent ce88dbdee4
commit fdebb373b1
17 changed files with 672 additions and 773 deletions

View File

@ -62,8 +62,8 @@ void OpenGLES::Initialize()
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
@ -78,7 +78,7 @@ void OpenGLES::Initialize()
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -89,7 +89,7 @@ void OpenGLES::Initialize()
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -112,14 +112,7 @@ void OpenGLES::Initialize()
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
// //
// Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize.
// Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+.
// We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like
// real Windows Phone devices.
// If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef.
//
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
@ -128,9 +121,8 @@ void OpenGLES::Initialize()
} }
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
#endif
{ {
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -139,7 +131,7 @@ void OpenGLES::Initialize()
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
{ {
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -188,12 +180,17 @@ void OpenGLES::Reset()
Initialize(); Initialize();
} }
EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize) EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize, const float* resolutionScale)
{ {
if (!panel) if (!panel)
{ {
throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid"); throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid");
} }
if (renderSurfaceSize != nullptr && resolutionScale != nullptr)
{
throw Exception::CreateException(E_INVALIDARG, L"A size and a scale can't both be specified");
}
EGLSurface surface = EGL_NO_SURFACE; EGLSurface surface = EGL_NO_SURFACE;
@ -207,12 +204,18 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
// Create a PropertySet and initialize with the EGLNativeWindowType. // Create a PropertySet and initialize with the EGLNativeWindowType.
PropertySet^ surfaceCreationProperties = ref new PropertySet(); PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new Platform::String(EGLNativeWindowTypeProperty), panel); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel);
// If a render surface size is specified, add it to the surface creation properties // If a render surface size is specified, add it to the surface creation properties
if (renderSurfaceSize != nullptr) if (renderSurfaceSize != nullptr)
{ {
surfaceCreationProperties->Insert(ref new Platform::String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize));
}
// If a resolution scale is specified, add it to the surface creation properties
if (resolutionScale != nullptr)
{
surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(*resolutionScale));
} }
surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes); surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
@ -224,6 +227,12 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
return surface; return surface;
} }
void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height)
{
eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
void OpenGLES::DestroySurface(const EGLSurface surface) void OpenGLES::DestroySurface(const EGLSurface surface)
{ {
if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE)

View File

@ -20,7 +20,6 @@
// OpenGL ES includes // OpenGL ES includes
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
// EGL includes // EGL includes
#include <EGL/egl.h> #include <EGL/egl.h>
@ -34,7 +33,8 @@ public:
OpenGLES(); OpenGLES();
~OpenGLES(); ~OpenGLES();
EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize); EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize, const float* renderResolutionScale);
void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, EGLint *height);
void DestroySurface(const EGLSurface surface); void DestroySurface(const EGLSurface surface);
void MakeCurrent(const EGLSurface surface); void MakeCurrent(const EGLSurface surface);
EGLBoolean SwapBuffers(const EGLSurface surface); EGLBoolean SwapBuffers(const EGLSurface surface);

View File

@ -24,7 +24,6 @@ using namespace cocos2d;
using namespace Platform; using namespace Platform;
using namespace Concurrency; using namespace Concurrency;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display; using namespace Windows::Graphics::Display;
using namespace Windows::System::Threading; using namespace Windows::System::Threading;
using namespace Windows::UI::Core; using namespace Windows::UI::Core;
@ -50,8 +49,6 @@ OpenGLESPage::OpenGLESPage() :
OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
mOpenGLES(openGLES), mOpenGLES(openGLES),
mRenderSurface(EGL_NO_SURFACE), mRenderSurface(EGL_NO_SURFACE),
mCustomRenderSurfaceSize(0,0),
mUseCustomRenderSurfaceSize(false),
mCoreInput(nullptr), mCoreInput(nullptr),
mDpi(0.0f), mDpi(0.0f),
mDeviceLost(false), mDeviceLost(false),
@ -72,8 +69,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived); window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived);
swapChainPanel->SizeChanged +=
ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &OpenGLESPage::OnSwapChainPanelSizeChanged);
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
@ -85,8 +80,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
this->Loaded += this->Loaded +=
ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded); ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded);
mSwapChainPanelSize = { swapChainPanel->RenderSize.Width, swapChainPanel->RenderSize.Height };
#if _MSC_VER >= 1900 #if _MSC_VER >= 1900
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar")) if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{ {
@ -158,166 +151,26 @@ void OpenGLESPage::OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::Rou
mVisible = true; mVisible = true;
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif
void OpenGLESPage::OnSwapChainPanelSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
// Size change events occur outside of the render thread. A lock is required when updating
// the swapchainpanel size
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mSwapChainPanelSize = { e->NewSize.Width, e->NewSize.Height };
}
void OpenGLESPage::GetSwapChainPanelSize(GLsizei* width, GLsizei* height)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
// If a custom render surface size is specified, return its size instead of
// the swapchain panel size.
if (mUseCustomRenderSurfaceSize)
{
*width = static_cast<GLsizei>(mCustomRenderSurfaceSize.Width);
*height = static_cast<GLsizei>(mCustomRenderSurfaceSize.Height);
}
else
{
*width = static_cast<GLsizei>(mSwapChainPanelSize.Width);
*height = static_cast<GLsizei>(mSwapChainPanelSize.Height);
}
}
void OpenGLESPage::CreateRenderSurface() void OpenGLESPage::CreateRenderSurface()
{ {
if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE) if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE)
{ {
// // The app can configure the the SwapChainPanel which may boost performance.
// A Custom render surface size can be specified by uncommenting the following lines. // By default, this template uses the default configuration.
// The render surface will be automatically scaled to fit the entire window. Using a mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, nullptr);
// smaller sized render surface can result in a performance gain.
//
//mCustomRenderSurfaceSize = Size(800, 600);
//mUseCustomRenderSurfaceSize = true;
mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, mUseCustomRenderSurfaceSize ? &mCustomRenderSurfaceSize : nullptr); // You can configure the SwapChainPanel to render at a lower resolution and be scaled up to
// the swapchain panel size. This scaling is often free on mobile hardware.
//
// One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
// Size customRenderSurfaceSize = Size(800, 600);
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, &customRenderSurfaceSize, nullptr);
//
// Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
// e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
// float customResolutionScale = 0.5f;
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, &customResolutionScale);
//
} }
} }
@ -375,7 +228,7 @@ void OpenGLESPage::StartRenderLoop()
GLsizei panelWidth = 0; GLsizei panelWidth = 0;
GLsizei panelHeight = 0; GLsizei panelHeight = 0;
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
if (mRenderer.get() == nullptr) if (mRenderer.get() == nullptr)
{ {
@ -412,7 +265,7 @@ void OpenGLESPage::StartRenderLoop()
} }
} }
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation); mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation);
// Recreate input dispatch // Recreate input dispatch
@ -425,7 +278,7 @@ void OpenGLESPage::StartRenderLoop()
if (mRenderer->AppShouldExit()) if (mRenderer->AppShouldExit())
{ {
// run on main UI thread // run on main UI thread
swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([this]() swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
{ {
TerminateApp(); TerminateApp();
})); }));
@ -491,4 +344,125 @@ void OpenGLESPage::StopRenderLoop()
mSleepCondition.notify_one(); mSleepCondition.notify_one();
mRenderLoopWorker = nullptr; mRenderLoopWorker = nullptr;
} }
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif

View File

@ -41,11 +41,9 @@ namespace CocosAppWinRT
private: private:
void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnSwapChainPanelSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif #endif
void GetSwapChainPanelSize(GLsizei* width, GLsizei* height);
void CreateRenderSurface(); void CreateRenderSurface();
void DestroyRenderSurface(); void DestroyRenderSurface();
void RecoverFromLostDevice(); void RecoverFromLostDevice();
@ -58,12 +56,6 @@ namespace CocosAppWinRT
OpenGLES* mOpenGLES; OpenGLES* mOpenGLES;
std::shared_ptr<Cocos2dRenderer> mRenderer; std::shared_ptr<Cocos2dRenderer> mRenderer;
Windows::Foundation::Size mSwapChainPanelSize;
Concurrency::critical_section mSwapChainPanelSizeCriticalSection;
Windows::Foundation::Size mCustomRenderSurfaceSize;
bool mUseCustomRenderSurfaceSize;
EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page
Concurrency::critical_section mRenderSurfaceCriticalSection; Concurrency::critical_section mRenderSurfaceCriticalSection;
Windows::Foundation::IAsyncAction^ mRenderLoopWorker; Windows::Foundation::IAsyncAction^ mRenderLoopWorker;

View File

@ -37,7 +37,6 @@ THE SOFTWARE.
#include "GLES2/gl2.h" #include "GLES2/gl2.h"
#include "GLES2/gl2ext.h" #include "GLES2/gl2ext.h"
#include "GLES3/gl3.h" #include "GLES3/gl3.h"
#include "GLES3/gl3ext.h"
#define glMapBuffer glMapBufferOES #define glMapBuffer glMapBufferOES

View File

@ -62,8 +62,8 @@ void OpenGLES::Initialize()
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
@ -78,7 +78,7 @@ void OpenGLES::Initialize()
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -89,7 +89,7 @@ void OpenGLES::Initialize()
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -112,14 +112,7 @@ void OpenGLES::Initialize()
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
// //
// Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize.
// Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+.
// We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like
// real Windows Phone devices.
// If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef.
//
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
@ -128,9 +121,8 @@ void OpenGLES::Initialize()
} }
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
#endif
{ {
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -139,7 +131,7 @@ void OpenGLES::Initialize()
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
{ {
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -188,12 +180,17 @@ void OpenGLES::Reset()
Initialize(); Initialize();
} }
EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize) EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize, const float* resolutionScale)
{ {
if (!panel) if (!panel)
{ {
throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid"); throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid");
} }
if (renderSurfaceSize != nullptr && resolutionScale != nullptr)
{
throw Exception::CreateException(E_INVALIDARG, L"A size and a scale can't both be specified");
}
EGLSurface surface = EGL_NO_SURFACE; EGLSurface surface = EGL_NO_SURFACE;
@ -207,12 +204,18 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
// Create a PropertySet and initialize with the EGLNativeWindowType. // Create a PropertySet and initialize with the EGLNativeWindowType.
PropertySet^ surfaceCreationProperties = ref new PropertySet(); PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new Platform::String(EGLNativeWindowTypeProperty), panel); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel);
// If a render surface size is specified, add it to the surface creation properties // If a render surface size is specified, add it to the surface creation properties
if (renderSurfaceSize != nullptr) if (renderSurfaceSize != nullptr)
{ {
surfaceCreationProperties->Insert(ref new Platform::String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize));
}
// If a resolution scale is specified, add it to the surface creation properties
if (resolutionScale != nullptr)
{
surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(*resolutionScale));
} }
surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes); surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
@ -224,6 +227,12 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
return surface; return surface;
} }
void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height)
{
eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
void OpenGLES::DestroySurface(const EGLSurface surface) void OpenGLES::DestroySurface(const EGLSurface surface)
{ {
if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE)

View File

@ -20,7 +20,6 @@
// OpenGL ES includes // OpenGL ES includes
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
// EGL includes // EGL includes
#include <EGL/egl.h> #include <EGL/egl.h>
@ -34,7 +33,8 @@ public:
OpenGLES(); OpenGLES();
~OpenGLES(); ~OpenGLES();
EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize); EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize, const float* renderResolutionScale);
void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, EGLint *height);
void DestroySurface(const EGLSurface surface); void DestroySurface(const EGLSurface surface);
void MakeCurrent(const EGLSurface surface); void MakeCurrent(const EGLSurface surface);
EGLBoolean SwapBuffers(const EGLSurface surface); EGLBoolean SwapBuffers(const EGLSurface surface);

View File

@ -24,7 +24,6 @@ using namespace cocos2d;
using namespace Platform; using namespace Platform;
using namespace Concurrency; using namespace Concurrency;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display; using namespace Windows::Graphics::Display;
using namespace Windows::System::Threading; using namespace Windows::System::Threading;
using namespace Windows::UI::Core; using namespace Windows::UI::Core;
@ -50,8 +49,6 @@ OpenGLESPage::OpenGLESPage() :
OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
mOpenGLES(openGLES), mOpenGLES(openGLES),
mRenderSurface(EGL_NO_SURFACE), mRenderSurface(EGL_NO_SURFACE),
mCustomRenderSurfaceSize(0,0),
mUseCustomRenderSurfaceSize(false),
mCoreInput(nullptr), mCoreInput(nullptr),
mDpi(0.0f), mDpi(0.0f),
mDeviceLost(false), mDeviceLost(false),
@ -72,8 +69,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived); window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived);
swapChainPanel->SizeChanged +=
ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &OpenGLESPage::OnSwapChainPanelSizeChanged);
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
@ -85,8 +80,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
this->Loaded += this->Loaded +=
ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded); ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded);
mSwapChainPanelSize = { swapChainPanel->RenderSize.Width, swapChainPanel->RenderSize.Height };
#if _MSC_VER >= 1900 #if _MSC_VER >= 1900
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar")) if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{ {
@ -158,166 +151,26 @@ void OpenGLESPage::OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::Rou
mVisible = true; mVisible = true;
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif
void OpenGLESPage::OnSwapChainPanelSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
// Size change events occur outside of the render thread. A lock is required when updating
// the swapchainpanel size
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mSwapChainPanelSize = { e->NewSize.Width, e->NewSize.Height };
}
void OpenGLESPage::GetSwapChainPanelSize(GLsizei* width, GLsizei* height)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
// If a custom render surface size is specified, return its size instead of
// the swapchain panel size.
if (mUseCustomRenderSurfaceSize)
{
*width = static_cast<GLsizei>(mCustomRenderSurfaceSize.Width);
*height = static_cast<GLsizei>(mCustomRenderSurfaceSize.Height);
}
else
{
*width = static_cast<GLsizei>(mSwapChainPanelSize.Width);
*height = static_cast<GLsizei>(mSwapChainPanelSize.Height);
}
}
void OpenGLESPage::CreateRenderSurface() void OpenGLESPage::CreateRenderSurface()
{ {
if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE) if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE)
{ {
// // The app can configure the the SwapChainPanel which may boost performance.
// A Custom render surface size can be specified by uncommenting the following lines. // By default, this template uses the default configuration.
// The render surface will be automatically scaled to fit the entire window. Using a mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, nullptr);
// smaller sized render surface can result in a performance gain.
//
//mCustomRenderSurfaceSize = Size(800, 600);
//mUseCustomRenderSurfaceSize = true;
mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, mUseCustomRenderSurfaceSize ? &mCustomRenderSurfaceSize : nullptr); // You can configure the SwapChainPanel to render at a lower resolution and be scaled up to
// the swapchain panel size. This scaling is often free on mobile hardware.
//
// One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
// Size customRenderSurfaceSize = Size(800, 600);
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, &customRenderSurfaceSize, nullptr);
//
// Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
// e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
// float customResolutionScale = 0.5f;
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, &customResolutionScale);
//
} }
} }
@ -375,7 +228,7 @@ void OpenGLESPage::StartRenderLoop()
GLsizei panelWidth = 0; GLsizei panelWidth = 0;
GLsizei panelHeight = 0; GLsizei panelHeight = 0;
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
if (mRenderer.get() == nullptr) if (mRenderer.get() == nullptr)
{ {
@ -412,7 +265,7 @@ void OpenGLESPage::StartRenderLoop()
} }
} }
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation); mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation);
// Recreate input dispatch // Recreate input dispatch
@ -425,7 +278,7 @@ void OpenGLESPage::StartRenderLoop()
if (mRenderer->AppShouldExit()) if (mRenderer->AppShouldExit())
{ {
// run on main UI thread // run on main UI thread
swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([this]() swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
{ {
TerminateApp(); TerminateApp();
})); }));
@ -491,4 +344,125 @@ void OpenGLESPage::StopRenderLoop()
mSleepCondition.notify_one(); mSleepCondition.notify_one();
mRenderLoopWorker = nullptr; mRenderLoopWorker = nullptr;
} }
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif

View File

@ -41,11 +41,9 @@ namespace CocosAppWinRT
private: private:
void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnSwapChainPanelSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif #endif
void GetSwapChainPanelSize(GLsizei* width, GLsizei* height);
void CreateRenderSurface(); void CreateRenderSurface();
void DestroyRenderSurface(); void DestroyRenderSurface();
void RecoverFromLostDevice(); void RecoverFromLostDevice();
@ -58,12 +56,6 @@ namespace CocosAppWinRT
OpenGLES* mOpenGLES; OpenGLES* mOpenGLES;
std::shared_ptr<Cocos2dRenderer> mRenderer; std::shared_ptr<Cocos2dRenderer> mRenderer;
Windows::Foundation::Size mSwapChainPanelSize;
Concurrency::critical_section mSwapChainPanelSizeCriticalSection;
Windows::Foundation::Size mCustomRenderSurfaceSize;
bool mUseCustomRenderSurfaceSize;
EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page
Concurrency::critical_section mRenderSurfaceCriticalSection; Concurrency::critical_section mRenderSurfaceCriticalSection;
Windows::Foundation::IAsyncAction^ mRenderLoopWorker; Windows::Foundation::IAsyncAction^ mRenderLoopWorker;

View File

@ -62,8 +62,8 @@ void OpenGLES::Initialize()
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
@ -78,7 +78,7 @@ void OpenGLES::Initialize()
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -89,7 +89,7 @@ void OpenGLES::Initialize()
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -112,14 +112,7 @@ void OpenGLES::Initialize()
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
// //
// Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize.
// Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+.
// We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like
// real Windows Phone devices.
// If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef.
//
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
@ -128,9 +121,8 @@ void OpenGLES::Initialize()
} }
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
#endif
{ {
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -139,7 +131,7 @@ void OpenGLES::Initialize()
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
{ {
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -188,12 +180,17 @@ void OpenGLES::Reset()
Initialize(); Initialize();
} }
EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize) EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize, const float* resolutionScale)
{ {
if (!panel) if (!panel)
{ {
throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid"); throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid");
} }
if (renderSurfaceSize != nullptr && resolutionScale != nullptr)
{
throw Exception::CreateException(E_INVALIDARG, L"A size and a scale can't both be specified");
}
EGLSurface surface = EGL_NO_SURFACE; EGLSurface surface = EGL_NO_SURFACE;
@ -207,12 +204,18 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
// Create a PropertySet and initialize with the EGLNativeWindowType. // Create a PropertySet and initialize with the EGLNativeWindowType.
PropertySet^ surfaceCreationProperties = ref new PropertySet(); PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new Platform::String(EGLNativeWindowTypeProperty), panel); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel);
// If a render surface size is specified, add it to the surface creation properties // If a render surface size is specified, add it to the surface creation properties
if (renderSurfaceSize != nullptr) if (renderSurfaceSize != nullptr)
{ {
surfaceCreationProperties->Insert(ref new Platform::String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize));
}
// If a resolution scale is specified, add it to the surface creation properties
if (resolutionScale != nullptr)
{
surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(*resolutionScale));
} }
surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes); surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
@ -224,6 +227,12 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
return surface; return surface;
} }
void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height)
{
eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
void OpenGLES::DestroySurface(const EGLSurface surface) void OpenGLES::DestroySurface(const EGLSurface surface)
{ {
if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE)

View File

@ -20,7 +20,6 @@
// OpenGL ES includes // OpenGL ES includes
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
// EGL includes // EGL includes
#include <EGL/egl.h> #include <EGL/egl.h>
@ -34,7 +33,8 @@ public:
OpenGLES(); OpenGLES();
~OpenGLES(); ~OpenGLES();
EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize); EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize, const float* renderResolutionScale);
void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, EGLint *height);
void DestroySurface(const EGLSurface surface); void DestroySurface(const EGLSurface surface);
void MakeCurrent(const EGLSurface surface); void MakeCurrent(const EGLSurface surface);
EGLBoolean SwapBuffers(const EGLSurface surface); EGLBoolean SwapBuffers(const EGLSurface surface);

View File

@ -24,7 +24,6 @@ using namespace cocos2d;
using namespace Platform; using namespace Platform;
using namespace Concurrency; using namespace Concurrency;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display; using namespace Windows::Graphics::Display;
using namespace Windows::System::Threading; using namespace Windows::System::Threading;
using namespace Windows::UI::Core; using namespace Windows::UI::Core;
@ -50,8 +49,6 @@ OpenGLESPage::OpenGLESPage() :
OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
mOpenGLES(openGLES), mOpenGLES(openGLES),
mRenderSurface(EGL_NO_SURFACE), mRenderSurface(EGL_NO_SURFACE),
mCustomRenderSurfaceSize(0,0),
mUseCustomRenderSurfaceSize(false),
mCoreInput(nullptr), mCoreInput(nullptr),
mDpi(0.0f), mDpi(0.0f),
mDeviceLost(false), mDeviceLost(false),
@ -72,8 +69,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived); window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived);
swapChainPanel->SizeChanged +=
ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &OpenGLESPage::OnSwapChainPanelSizeChanged);
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
@ -85,8 +80,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
this->Loaded += this->Loaded +=
ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded); ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded);
mSwapChainPanelSize = { swapChainPanel->RenderSize.Width, swapChainPanel->RenderSize.Height };
#if _MSC_VER >= 1900 #if _MSC_VER >= 1900
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar")) if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{ {
@ -158,166 +151,26 @@ void OpenGLESPage::OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::Rou
mVisible = true; mVisible = true;
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif
void OpenGLESPage::OnSwapChainPanelSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
// Size change events occur outside of the render thread. A lock is required when updating
// the swapchainpanel size
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mSwapChainPanelSize = { e->NewSize.Width, e->NewSize.Height };
}
void OpenGLESPage::GetSwapChainPanelSize(GLsizei* width, GLsizei* height)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
// If a custom render surface size is specified, return its size instead of
// the swapchain panel size.
if (mUseCustomRenderSurfaceSize)
{
*width = static_cast<GLsizei>(mCustomRenderSurfaceSize.Width);
*height = static_cast<GLsizei>(mCustomRenderSurfaceSize.Height);
}
else
{
*width = static_cast<GLsizei>(mSwapChainPanelSize.Width);
*height = static_cast<GLsizei>(mSwapChainPanelSize.Height);
}
}
void OpenGLESPage::CreateRenderSurface() void OpenGLESPage::CreateRenderSurface()
{ {
if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE) if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE)
{ {
// // The app can configure the the SwapChainPanel which may boost performance.
// A Custom render surface size can be specified by uncommenting the following lines. // By default, this template uses the default configuration.
// The render surface will be automatically scaled to fit the entire window. Using a mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, nullptr);
// smaller sized render surface can result in a performance gain.
//
//mCustomRenderSurfaceSize = Size(800, 600);
//mUseCustomRenderSurfaceSize = true;
mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, mUseCustomRenderSurfaceSize ? &mCustomRenderSurfaceSize : nullptr); // You can configure the SwapChainPanel to render at a lower resolution and be scaled up to
// the swapchain panel size. This scaling is often free on mobile hardware.
//
// One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
// Size customRenderSurfaceSize = Size(800, 600);
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, &customRenderSurfaceSize, nullptr);
//
// Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
// e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
// float customResolutionScale = 0.5f;
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, &customResolutionScale);
//
} }
} }
@ -375,7 +228,7 @@ void OpenGLESPage::StartRenderLoop()
GLsizei panelWidth = 0; GLsizei panelWidth = 0;
GLsizei panelHeight = 0; GLsizei panelHeight = 0;
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
if (mRenderer.get() == nullptr) if (mRenderer.get() == nullptr)
{ {
@ -412,7 +265,7 @@ void OpenGLESPage::StartRenderLoop()
} }
} }
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation); mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation);
// Recreate input dispatch // Recreate input dispatch
@ -425,7 +278,7 @@ void OpenGLESPage::StartRenderLoop()
if (mRenderer->AppShouldExit()) if (mRenderer->AppShouldExit())
{ {
// run on main UI thread // run on main UI thread
swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([this]() swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
{ {
TerminateApp(); TerminateApp();
})); }));
@ -491,4 +344,125 @@ void OpenGLESPage::StopRenderLoop()
mSleepCondition.notify_one(); mSleepCondition.notify_one();
mRenderLoopWorker = nullptr; mRenderLoopWorker = nullptr;
} }
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif

View File

@ -41,11 +41,9 @@ namespace CocosAppWinRT
private: private:
void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnSwapChainPanelSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif #endif
void GetSwapChainPanelSize(GLsizei* width, GLsizei* height);
void CreateRenderSurface(); void CreateRenderSurface();
void DestroyRenderSurface(); void DestroyRenderSurface();
void RecoverFromLostDevice(); void RecoverFromLostDevice();
@ -58,12 +56,6 @@ namespace CocosAppWinRT
OpenGLES* mOpenGLES; OpenGLES* mOpenGLES;
std::shared_ptr<Cocos2dRenderer> mRenderer; std::shared_ptr<Cocos2dRenderer> mRenderer;
Windows::Foundation::Size mSwapChainPanelSize;
Concurrency::critical_section mSwapChainPanelSizeCriticalSection;
Windows::Foundation::Size mCustomRenderSurfaceSize;
bool mUseCustomRenderSurfaceSize;
EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page
Concurrency::critical_section mRenderSurfaceCriticalSection; Concurrency::critical_section mRenderSurfaceCriticalSection;
Windows::Foundation::IAsyncAction^ mRenderLoopWorker; Windows::Foundation::IAsyncAction^ mRenderLoopWorker;

View File

@ -62,8 +62,8 @@ void OpenGLES::Initialize()
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices. // EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it. // Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call // EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended. // the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement. // Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
@ -78,7 +78,7 @@ void OpenGLES::Initialize()
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -89,7 +89,7 @@ void OpenGLES::Initialize()
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes. // They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
EGL_NONE, EGL_NONE,
}; };
@ -112,14 +112,7 @@ void OpenGLES::Initialize()
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again // 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer. // using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
// //
// Note: On Windows Phone, we #ifdef out the first set of calls to eglPlatformDisplayEXT and eglInitialize.
// Windows Phones devices only support D3D11 Feature Level 9_3, but the Windows Phone emulator supports 11_0+.
// We use this #ifdef to limit the Phone emulator to Feature Level 9_3, making it behave more like
// real Windows Phone devices.
// If you wish to test Feature Level 10_0+ in the Windows Phone emulator then you should remove this #ifdef.
//
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details. // This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
@ -128,9 +121,8 @@ void OpenGLES::Initialize()
} }
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
#endif
{ {
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on Windows Phone, or certain Windows tablets). // This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -139,7 +131,7 @@ void OpenGLES::Initialize()
if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE) if (eglInitialize(mEglDisplay, NULL, NULL) == EGL_FALSE)
{ {
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU (e.g. on Surface RT). // This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes); mEglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
if (mEglDisplay == EGL_NO_DISPLAY) if (mEglDisplay == EGL_NO_DISPLAY)
{ {
@ -188,12 +180,17 @@ void OpenGLES::Reset()
Initialize(); Initialize();
} }
EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize) EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurfaceSize, const float* resolutionScale)
{ {
if (!panel) if (!panel)
{ {
throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid"); throw Exception::CreateException(E_INVALIDARG, L"SwapChainPanel parameter is invalid");
} }
if (renderSurfaceSize != nullptr && resolutionScale != nullptr)
{
throw Exception::CreateException(E_INVALIDARG, L"A size and a scale can't both be specified");
}
EGLSurface surface = EGL_NO_SURFACE; EGLSurface surface = EGL_NO_SURFACE;
@ -207,12 +204,18 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
// Create a PropertySet and initialize with the EGLNativeWindowType. // Create a PropertySet and initialize with the EGLNativeWindowType.
PropertySet^ surfaceCreationProperties = ref new PropertySet(); PropertySet^ surfaceCreationProperties = ref new PropertySet();
surfaceCreationProperties->Insert(ref new Platform::String(EGLNativeWindowTypeProperty), panel); surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), panel);
// If a render surface size is specified, add it to the surface creation properties // If a render surface size is specified, add it to the surface creation properties
if (renderSurfaceSize != nullptr) if (renderSurfaceSize != nullptr)
{ {
surfaceCreationProperties->Insert(ref new Platform::String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize)); surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(*renderSurfaceSize));
}
// If a resolution scale is specified, add it to the surface creation properties
if (resolutionScale != nullptr)
{
surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(*resolutionScale));
} }
surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes); surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
@ -224,6 +227,12 @@ EGLSurface OpenGLES::CreateSurface(SwapChainPanel^ panel, const Size* renderSurf
return surface; return surface;
} }
void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint* width, EGLint* height)
{
eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
}
void OpenGLES::DestroySurface(const EGLSurface surface) void OpenGLES::DestroySurface(const EGLSurface surface)
{ {
if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE)

View File

@ -20,7 +20,6 @@
// OpenGL ES includes // OpenGL ES includes
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
// EGL includes // EGL includes
#include <EGL/egl.h> #include <EGL/egl.h>
@ -34,7 +33,8 @@ public:
OpenGLES(); OpenGLES();
~OpenGLES(); ~OpenGLES();
EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize); EGLSurface CreateSurface(Windows::UI::Xaml::Controls::SwapChainPanel^ panel, const Windows::Foundation::Size* renderSurfaceSize, const float* renderResolutionScale);
void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, EGLint *height);
void DestroySurface(const EGLSurface surface); void DestroySurface(const EGLSurface surface);
void MakeCurrent(const EGLSurface surface); void MakeCurrent(const EGLSurface surface);
EGLBoolean SwapBuffers(const EGLSurface surface); EGLBoolean SwapBuffers(const EGLSurface surface);

View File

@ -24,7 +24,6 @@ using namespace cocos2d;
using namespace Platform; using namespace Platform;
using namespace Concurrency; using namespace Concurrency;
using namespace Windows::Foundation; using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display; using namespace Windows::Graphics::Display;
using namespace Windows::System::Threading; using namespace Windows::System::Threading;
using namespace Windows::UI::Core; using namespace Windows::UI::Core;
@ -50,8 +49,6 @@ OpenGLESPage::OpenGLESPage() :
OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) : OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
mOpenGLES(openGLES), mOpenGLES(openGLES),
mRenderSurface(EGL_NO_SURFACE), mRenderSurface(EGL_NO_SURFACE),
mCustomRenderSurfaceSize(0,0),
mUseCustomRenderSurfaceSize(false),
mCoreInput(nullptr), mCoreInput(nullptr),
mDpi(0.0f), mDpi(0.0f),
mDeviceLost(false), mDeviceLost(false),
@ -72,8 +69,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived); window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &OpenGLESPage::OnCharacterReceived);
swapChainPanel->SizeChanged +=
ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &OpenGLESPage::OnSwapChainPanelSizeChanged);
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
@ -85,8 +80,6 @@ OpenGLESPage::OpenGLESPage(OpenGLES* openGLES) :
this->Loaded += this->Loaded +=
ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded); ref new Windows::UI::Xaml::RoutedEventHandler(this, &OpenGLESPage::OnPageLoaded);
mSwapChainPanelSize = { swapChainPanel->RenderSize.Width, swapChainPanel->RenderSize.Height };
#if _MSC_VER >= 1900 #if _MSC_VER >= 1900
if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar")) if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.UI.ViewManagement.StatusBar"))
{ {
@ -158,166 +151,26 @@ void OpenGLESPage::OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::Rou
mVisible = true; mVisible = true;
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif
void OpenGLESPage::OnSwapChainPanelSizeChanged(Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
// Size change events occur outside of the render thread. A lock is required when updating
// the swapchainpanel size
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
mSwapChainPanelSize = { e->NewSize.Width, e->NewSize.Height };
}
void OpenGLESPage::GetSwapChainPanelSize(GLsizei* width, GLsizei* height)
{
critical_section::scoped_lock lock(mSwapChainPanelSizeCriticalSection);
// If a custom render surface size is specified, return its size instead of
// the swapchain panel size.
if (mUseCustomRenderSurfaceSize)
{
*width = static_cast<GLsizei>(mCustomRenderSurfaceSize.Width);
*height = static_cast<GLsizei>(mCustomRenderSurfaceSize.Height);
}
else
{
*width = static_cast<GLsizei>(mSwapChainPanelSize.Width);
*height = static_cast<GLsizei>(mSwapChainPanelSize.Height);
}
}
void OpenGLESPage::CreateRenderSurface() void OpenGLESPage::CreateRenderSurface()
{ {
if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE) if (mOpenGLES && mRenderSurface == EGL_NO_SURFACE)
{ {
// // The app can configure the the SwapChainPanel which may boost performance.
// A Custom render surface size can be specified by uncommenting the following lines. // By default, this template uses the default configuration.
// The render surface will be automatically scaled to fit the entire window. Using a mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, nullptr);
// smaller sized render surface can result in a performance gain.
//
//mCustomRenderSurfaceSize = Size(800, 600);
//mUseCustomRenderSurfaceSize = true;
mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, mUseCustomRenderSurfaceSize ? &mCustomRenderSurfaceSize : nullptr); // You can configure the SwapChainPanel to render at a lower resolution and be scaled up to
// the swapchain panel size. This scaling is often free on mobile hardware.
//
// One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
// Size customRenderSurfaceSize = Size(800, 600);
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, &customRenderSurfaceSize, nullptr);
//
// Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
// e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
// float customResolutionScale = 0.5f;
// mRenderSurface = mOpenGLES->CreateSurface(swapChainPanel, nullptr, &customResolutionScale);
//
} }
} }
@ -375,7 +228,7 @@ void OpenGLESPage::StartRenderLoop()
GLsizei panelWidth = 0; GLsizei panelWidth = 0;
GLsizei panelHeight = 0; GLsizei panelHeight = 0;
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
if (mRenderer.get() == nullptr) if (mRenderer.get() == nullptr)
{ {
@ -412,7 +265,7 @@ void OpenGLESPage::StartRenderLoop()
} }
} }
GetSwapChainPanelSize(&panelWidth, &panelHeight); mOpenGLES->GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight);
mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation); mRenderer.get()->Draw(panelWidth, panelHeight, mDpi, mOrientation);
// Recreate input dispatch // Recreate input dispatch
@ -425,7 +278,7 @@ void OpenGLESPage::StartRenderLoop()
if (mRenderer->AppShouldExit()) if (mRenderer->AppShouldExit())
{ {
// run on main UI thread // run on main UI thread
swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new DispatchedHandler([this]() swapChainPanel->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
{ {
TerminateApp(); TerminateApp();
})); }));
@ -491,4 +344,125 @@ void OpenGLESPage::StopRenderLoop()
mSleepCondition.notify_one(); mSleepCondition.notify_one();
mRenderLoopWorker = nullptr; mRenderLoopWorker = nullptr;
} }
} }
void OpenGLESPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MousePressed : PointerEventType::PointerPressed, e);
}
}
void OpenGLESPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseMoved : PointerEventType::PointerMoved, e);
}
}
void OpenGLESPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer)
{
mRenderer->QueuePointerEvent(isMouseEvent ? PointerEventType::MouseReleased : PointerEventType::PointerReleased, e);
}
}
void OpenGLESPage::OnPointerWheelChanged(Object^ sender, PointerEventArgs^ e)
{
bool isMouseEvent = e->CurrentPoint->PointerDevice->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse;
if (mRenderer && isMouseEvent)
{
mRenderer->QueuePointerEvent(PointerEventType::MouseWheelChanged, e);
}
}
void OpenGLESPage::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ e)
{
if (!e->KeyStatus.WasKeyDown)
{
//log("OpenGLESPage::OnKeyPressed %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyPressed, e);
}
}
}
void OpenGLESPage::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ e)
{
#if 0
if (!e->KeyStatus.WasKeyDown)
{
log("OpenGLESPage::OnCharacterReceived %d", e->KeyCode);
}
#endif
}
void OpenGLESPage::OnKeyReleased(CoreWindow^ sender, KeyEventArgs^ e)
{
//log("OpenGLESPage::OnKeyReleased %d", e->VirtualKey);
if (mRenderer)
{
mRenderer->QueueKeyboardEvent(WinRTKeyboardEventType::KeyReleased, e);
}
}
void OpenGLESPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
{
mOrientation = sender->CurrentOrientation;
}
void OpenGLESPage::SetVisibility(bool isVisible)
{
if (isVisible && mRenderSurface != EGL_NO_SURFACE)
{
std::unique_lock<std::mutex> locker(mSleepMutex);
mVisible = true;
mSleepCondition.notify_one();
}
else
{
mVisible = false;
}
}
void OpenGLESPage::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (args->Visible && mRenderSurface != EGL_NO_SURFACE)
{
SetVisibility(true);
}
else
{
SetVisibility(false);
}
}
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
/*
We set args->Handled = true to prevent the app from quitting when the back button is pressed.
This is because this back button event happens on the XAML UI thread and not the cocos2d-x UI thread.
We need to give the game developer a chance to decide to exit the app depending on where they
are in their game. They can receive the back button event by listening for the
EventKeyboard::KeyCode::KEY_ESCAPE event.
The default behavior is to exit the app if the EventKeyboard::KeyCode::KEY_ESCAPE event
is not handled by the game.
*/
void OpenGLESPage::OnBackButtonPressed(Object^ sender, BackPressedEventArgs^ args)
{
if (mRenderer)
{
mRenderer->QueueBackButtonEvent();
args->Handled = true;
}
}
#endif

View File

@ -41,11 +41,9 @@ namespace CocosAppWinRT
private: private:
void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); void OnPageLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnSwapChainPanelSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900 #if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || _MSC_VER >= 1900
void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif #endif
void GetSwapChainPanelSize(GLsizei* width, GLsizei* height);
void CreateRenderSurface(); void CreateRenderSurface();
void DestroyRenderSurface(); void DestroyRenderSurface();
void RecoverFromLostDevice(); void RecoverFromLostDevice();
@ -58,12 +56,6 @@ namespace CocosAppWinRT
OpenGLES* mOpenGLES; OpenGLES* mOpenGLES;
std::shared_ptr<Cocos2dRenderer> mRenderer; std::shared_ptr<Cocos2dRenderer> mRenderer;
Windows::Foundation::Size mSwapChainPanelSize;
Concurrency::critical_section mSwapChainPanelSizeCriticalSection;
Windows::Foundation::Size mCustomRenderSurfaceSize;
bool mUseCustomRenderSurfaceSize;
EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page EGLSurface mRenderSurface; // This surface is associated with a swapChainPanel on the page
Concurrency::critical_section mRenderSurfaceCriticalSection; Concurrency::critical_section mRenderSurfaceCriticalSection;
Windows::Foundation::IAsyncAction^ mRenderLoopWorker; Windows::Foundation::IAsyncAction^ mRenderLoopWorker;