OSX black window content while resize and how to win it

OSX black window content while resize and how to win it
0.0 0

#1

If you target your game to OSX and you choose to make window resizable, you will encounter, as am i, with huge problem: window content is absolutely black while you hold down left mouse button, while resize window. After release of lmb, window content reappear again. So, i spend a whole hour to solve this mistery, and want to share a solution:
somewhere in your AppDelegate.h:

static void refreshCallback(GLFWwindow* window);

then in AppDelegate.cpp:

void AppDelegate::refreshCallback(GLFWwindow* window) {
    
    Director * director = Director::getInstance();
    if (nullptr != director->getOpenGLView()) {
        director->mainLoop();
    }
}

bool AppDelegate::applicationDidFinishLaunching() {
...
glview = GLViewImpl::createWithRect("MyWindow", cocos2d::Rect(0, 0, myWidth, myHeight), 1.0, true);
GLFWwindow *rawWindow = reinterpret_cast<GLViewImpl*>(glview)->getWindow();
glfwSetWindowRefreshCallback(rawWindow, &refreshCallback);
...

It is almost done. A small final change need to be done in CCDirector.cpp:

void Director::drawScene()
{
    // calculate "global" dt
    calculateDeltaTime();
    
/* this piece of code need to be skipped
    if (_openGLView)
    {
        _openGLView->pollEvents();
    }
*/

You may protect changes by define instead of brute commenting:

#if (CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
    if (_openGLView)
    {
        _openGLView->pollEvents();
    }
#endif

but, i dont know if resize problem exist on other desktop platforms. In any case, i really thik, _openGLView->pollEvents(); should not be called inside Director::drawScene() at all. Director::drawScene() called from Director::mainLoop(), which is called from MacOS specific implementation of CCAplication - CCAplication-mac.mm:

int Application::run()
{
...
while (!glview->windowShouldClose())
    {
        lastTime = getCurrentMillSecond();
        director->mainLoop();
        glview->pollEvents();

        curTime = getCurrentMillSecond();
        if (curTime - lastTime < _animationInterval)
        {
            usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime)*1000));
        }
    }

it is typical window run cycle, which is implement poll events with glview->pollEvents();, so another events poll inside Director::drawScene() is unnecessary.


#2

Wouldn’t it be useful to create a PR, so it will be included in the framework in the future?