2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
|
|
|
|
2022-10-01 16:24:52 +08:00
|
|
|
https://axmolengine.github.io/
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
|
2023-06-11 13:08:08 +08:00
|
|
|
#include "platform/ios/EAGLView-ios.h"
|
|
|
|
#include "platform/ios/DirectorCaller-ios.h"
|
|
|
|
#include "platform/ios/GLViewImpl-ios.h"
|
|
|
|
#include "base/Touch.h"
|
|
|
|
#include "base/Director.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_BEGIN
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void* GLViewImpl::_pixelFormat = kEAGLColorFormatRGB565;
|
|
|
|
int GLViewImpl::_depthFormat = GL_DEPTH_COMPONENT16;
|
2019-11-23 20:27:39 +08:00
|
|
|
int GLViewImpl::_multisamplingCount = 0;
|
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
GLViewImpl* GLViewImpl::createWithEAGLView(void* eaglView)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto ret = new GLViewImpl;
|
2022-09-05 14:13:52 +08:00
|
|
|
if (ret->initWithEAGLView(eaglView))
|
2021-12-31 12:12:40 +08:00
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(ret);
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
GLViewImpl* GLViewImpl::create(std::string_view viewName)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto ret = new GLViewImpl;
|
2021-12-31 12:12:40 +08:00
|
|
|
if (ret->initWithFullScreen(viewName))
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(ret);
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
GLViewImpl* GLViewImpl::createWithRect(std::string_view viewName, const Rect& rect, float frameZoomFactor)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto ret = new GLViewImpl;
|
2021-12-31 12:12:40 +08:00
|
|
|
if (ret->initWithRect(viewName, rect, frameZoomFactor))
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(ret);
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
GLViewImpl* GLViewImpl::createWithFullScreen(std::string_view viewName)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
auto ret = new GLViewImpl();
|
2021-12-31 12:12:40 +08:00
|
|
|
if (ret->initWithFullScreen(viewName))
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(ret);
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLViewImpl::convertAttrs()
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
if (_glContextAttrs.redBits == 8 && _glContextAttrs.greenBits == 8 && _glContextAttrs.blueBits == 8 &&
|
|
|
|
_glContextAttrs.alphaBits == 8)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_pixelFormat = kEAGLColorFormatRGBA8;
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
else if (_glContextAttrs.redBits == 5 && _glContextAttrs.greenBits == 6 && _glContextAttrs.blueBits == 5 &&
|
|
|
|
_glContextAttrs.alphaBits == 0)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_pixelFormat = kEAGLColorFormatRGB565;
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(0, "Unsupported render buffer pixel format. Using default");
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
if (_glContextAttrs.depthBits == 24 && _glContextAttrs.stencilBits == 8)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_depthFormat = GL_DEPTH24_STENCIL8_OES;
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
else if (_glContextAttrs.depthBits == 0 && _glContextAttrs.stencilBits == 0)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_depthFormat = 0;
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(0, "Unsupported format for depth and stencil buffers. Using default");
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
_multisamplingCount = _glContextAttrs.multisamplingCount;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
GLViewImpl::GLViewImpl() {}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
GLViewImpl::~GLViewImpl()
|
|
|
|
{
|
2023-08-25 16:49:08 +08:00
|
|
|
// EAGLView *glView = (EAGLView*) _eaglView;
|
2022-09-05 14:13:52 +08:00
|
|
|
//[glView release];
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
bool GLViewImpl::initWithEAGLView(void* eaglView)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-09-05 14:13:52 +08:00
|
|
|
_eaglView = eaglView;
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* glView = (EAGLView*)_eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
_screenSize.width = _designResolutionSize.width = [glView getWidth];
|
|
|
|
_screenSize.height = _designResolutionSize.height = [glView getHeight];
|
|
|
|
// _scaleX = _scaleY = [glView contentScaleFactor];
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
bool GLViewImpl::initWithRect(std::string_view viewName, const Rect& rect, float frameZoomFactor)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
CGRect r = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
|
|
|
|
convertAttrs();
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = [EAGLView viewWithFrame:r
|
2021-12-31 12:12:40 +08:00
|
|
|
pixelFormat:(NSString*)_pixelFormat
|
|
|
|
depthFormat:_depthFormat
|
|
|
|
preserveBackbuffer:NO
|
|
|
|
sharegroup:nil
|
|
|
|
multiSampling:NO
|
|
|
|
numberOfSamples:0];
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Not available on tvOS
|
2022-07-16 10:43:05 +08:00
|
|
|
#if !defined(AX_TARGET_OS_TVOS)
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView setMultipleTouchEnabled:YES];
|
2019-11-23 20:27:39 +08:00
|
|
|
#endif
|
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
_screenSize.width = _designResolutionSize.width = [eaglView getWidth];
|
|
|
|
_screenSize.height = _designResolutionSize.height = [eaglView getHeight];
|
|
|
|
// _scaleX = _scaleY = [eaglView contentScaleFactor];
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
_eaglView = eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
bool GLViewImpl::initWithFullScreen(std::string_view viewName)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
CGRect rect = [[UIScreen mainScreen] bounds];
|
|
|
|
Rect r;
|
2021-12-31 12:12:40 +08:00
|
|
|
r.origin.x = rect.origin.x;
|
|
|
|
r.origin.y = rect.origin.y;
|
|
|
|
r.size.width = rect.size.width;
|
2019-11-23 20:27:39 +08:00
|
|
|
r.size.height = rect.size.height;
|
|
|
|
|
|
|
|
return initWithRect(viewName, r, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GLViewImpl::isOpenGLReady()
|
|
|
|
{
|
2022-09-05 14:13:52 +08:00
|
|
|
return _eaglView != nullptr;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GLViewImpl::setContentScaleFactor(float contentScaleFactor)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_ASSERT(_resolutionPolicy == ResolutionPolicy::UNKNOWN); // cannot enable retina mode
|
2019-11-23 20:27:39 +08:00
|
|
|
_scaleX = _scaleY = contentScaleFactor;
|
|
|
|
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView setNeedsLayout];
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
float GLViewImpl::getContentScaleFactor() const
|
|
|
|
{
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
float scaleFactor = [eaglView contentScaleFactor];
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
// AXASSERT(scaleFactor == _scaleX == _scaleY, "Logic error in GLView::getContentScaleFactor");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
return scaleFactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLViewImpl::end()
|
|
|
|
{
|
|
|
|
[CCDirectorCaller destroy];
|
|
|
|
|
|
|
|
// destroy EAGLView
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView removeFromSuperview];
|
|
|
|
//[eaglView release];
|
2019-11-23 20:27:39 +08:00
|
|
|
release();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLViewImpl::swapBuffers()
|
|
|
|
{
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView swapBuffers];
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLViewImpl::setIMEKeyboardState(bool open)
|
|
|
|
{
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
if (open)
|
|
|
|
{
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView showKeyboard];
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-05 14:13:52 +08:00
|
|
|
[eaglView hideKeyboard];
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Rect GLViewImpl::getSafeAreaRect() const
|
|
|
|
{
|
2023-08-25 16:49:08 +08:00
|
|
|
EAGLView* eaglView = (EAGLView*)_eaglView;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
|
|
|
|
float version = [[UIDevice currentDevice].systemVersion floatValue];
|
|
|
|
if (version >= 11.0f)
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
# pragma clang diagnostic push
|
|
|
|
# pragma clang diagnostic ignored "-Wpartial-availability"
|
2022-09-05 14:13:52 +08:00
|
|
|
UIEdgeInsets safeAreaInsets = eaglView.safeAreaInsets;
|
2021-12-31 12:12:40 +08:00
|
|
|
# pragma clang diagnostic pop
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Multiply contentScaleFactor since safeAreaInsets return points.
|
2022-09-05 14:13:52 +08:00
|
|
|
safeAreaInsets.left *= eaglView.contentScaleFactor;
|
|
|
|
safeAreaInsets.right *= eaglView.contentScaleFactor;
|
|
|
|
safeAreaInsets.top *= eaglView.contentScaleFactor;
|
|
|
|
safeAreaInsets.bottom *= eaglView.contentScaleFactor;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Get leftBottom and rightTop point in UI coordinates
|
|
|
|
Vec2 leftBottom = Vec2(safeAreaInsets.left, _screenSize.height - safeAreaInsets.bottom);
|
2021-12-31 12:12:40 +08:00
|
|
|
Vec2 rightTop = Vec2(_screenSize.width - safeAreaInsets.right, safeAreaInsets.top);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Convert a point from UI coordinates to which in design resolution coordinate.
|
|
|
|
leftBottom.x = (leftBottom.x - _viewPortRect.origin.x) / _scaleX,
|
|
|
|
leftBottom.y = (leftBottom.y - _viewPortRect.origin.y) / _scaleY;
|
2021-12-31 12:12:40 +08:00
|
|
|
rightTop.x = (rightTop.x - _viewPortRect.origin.x) / _scaleX,
|
|
|
|
rightTop.y = (rightTop.y - _viewPortRect.origin.y) / _scaleY;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Adjust points to make them inside design resolution
|
|
|
|
leftBottom.x = MAX(leftBottom.x, 0);
|
|
|
|
leftBottom.y = MIN(leftBottom.y, _designResolutionSize.height);
|
2021-12-31 12:12:40 +08:00
|
|
|
rightTop.x = MIN(rightTop.x, _designResolutionSize.width);
|
|
|
|
rightTop.y = MAX(rightTop.y, 0);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
// Convert to GL coordinates
|
|
|
|
leftBottom = Director::getInstance()->convertToGL(leftBottom);
|
2021-12-31 12:12:40 +08:00
|
|
|
rightTop = Director::getInstance()->convertToGL(rightTop);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
return Rect(leftBottom.x, leftBottom.y, rightTop.x - leftBottom.x, rightTop.y - leftBottom.y);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// If running on iOS devices lower than 11.0, return visiable rect instead.
|
|
|
|
return GLView::getSafeAreaRect();
|
|
|
|
}
|
|
|
|
|
2023-05-31 20:42:39 +08:00
|
|
|
void GLViewImpl::queueOperation(void (*op)(void*), void* param)
|
|
|
|
{
|
|
|
|
[[NSOperationQueue mainQueue] addOperationWithBlock:^(void){
|
|
|
|
op(param);
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_END
|