最近在做Cocos Creator小游戏和iOS原生交互的项目,在Cocos和原生互相跳转时碰到一个问题,从Cocos小游戏跳转到原生直播页面播放直播视频后,直播页面点击返回跳转回Cocos游戏时发现游戏画面停止,并且点击无反应,Xcode的log一直打印如下错误。
OpenGL error 0x0500 in -[CCEAGLView swapBuffers] 445
上面的log字面意思应该就是OpenGL渲染相关的错误。在Cocos源码中找到了CCEAGLView类和swapBuffers方法,该方法是用来交换前后缓冲区的,我们继续查找源码,哪个地方调用了这个方法,在CCApplication-ios类中,我们找到doCaller方法,在这个方法里会进行OpenGL渲染相关的操作,渲染完成后执行swapBuffers将缓冲区的buffer推到CCEAGLView并显示,由上,我们大概推测出直播SDK在播放直播流时,会把游戏渲染的CCEAGLView推到后台导致渲染不上去报错,从而画面出现静止无反应或者黑屏,所以我们需要在进入直播页面时手动暂停引擎渲染,修改cocos源码,首先,我们在MainLoop中增加一个暂停的属性和暂停渲染方法,恢复渲染方法,修改后的MainLoop类如下
@interface MainLoop : NSObject
{
id _displayLink;
int _fps;
float _systemVersion;
BOOL _isAppActive;
BOOL _isPaused;
cocos2d::Device::Rotation _lastRotation;
cocos2d::Application* _application;
std::shared_ptr<cocos2d::Scheduler> _scheduler;
}
-(void) startMainLoop;
-(void) stopMainLoop;
-(void) pauseMainLoop;
-(void) resumeMainLoop;
-(void) doCaller: (id) sender;
-(void) setPreferredFPS:(int)fps;
-(void) firstStart:(id) view;
@end
同时,在doCaller方法中,增加条件,代码如下
-(void) doCaller: (id) sender
{
static std::chrono::steady_clock::time_point prevTime;
static std::chrono::steady_clock::time_point now;
static float dt = 0.f;
if (_isAppActive && !_isPaused)
{
xxxxxxxx
}
}
新增暂停渲染和恢复渲染方法
-(void) pauseMainLoop
{
_isPaused = true;
}
-(void) resumeMainLoop
{
_isPaused = false;
}
在CCApplication.h文件中的Application类里,新增两个方法
void pause();
void resume();
在CCApplication-ios.mm文件中的Application类中增加上面两个方法的实现
void Application::pause()
{
if (_delegate)
[(MainLoop*)_delegate performSelector:@selector(pauseMainLoop) withObject:nil afterDelay:0];
}
void Application::resume()
{
if (_delegate)
[(MainLoop*)_delegate performSelector:@selector(resumeMainLoop) withObject:nil afterDelay:0];
}
然后我们只需在跳转到原生页面时执行以下代码即可暂停渲染
app->pause();
在退出原生页面执行以下代码即可恢复渲染
app->resume();