setDesignResolutionSize 사용시 CCListView와 CCScrollView 버그 해결

지난 포스팅에서 cocos2d-x 플랫폼별 해상도와 리소스 관련된 내용을 다뤘는데요, 이것과 관련한 버그가 존재하네요.
eglView.setFrameSize(800, 480);
eglView.setDesignResolutionSize(480, 320);
일단 제 폰이 800 x 480이라 2배 뻥튀기 하기위해 위와 같이 설정했구요 아래 스샷을 보시죠.

< 비정상 >


< 정상 >


어떠신가요? 스샷만 보더라도 뭔가.. 잘 못 되었다라는 것을 알수 있겠죠? 저와 같은 문제에 빠진 분들이 있더군요. 대충 소스를 보니 setDesignResolutionSize를 통해 CCEGLView의 ScreenScaleFactor는 1.0이 아닌 값으로 변경이 되어지는데 반해 CCDirector에 있는 ContentScaleFactor은 1.0 그대로 여서 아래의 소스에서 문제가 발생합니다.


void CCListView::visit(void)
{
    if (!m_pListViewParent)
    {
        CCRect rectSelf;
        float factor = CC_CONTENT_SCALE_FACTOR();
        rectSelf.origin = convertToWorldSpace(CCPoint(0,0));
        rectSelf.origin.x *= factor;
        rectSelf.origin.y *= factor;
        rectSelf.size = this->getContentSize();
        rectSelf.size.width *= factor;
        rectSelf.size.height *= factor;
        glScissor((GLsizei)rectSelf.origin.x, (GLsizei)rectSelf.origin.y, (GLsizei)rectSelf.size.width , (GLsizei)rectSelf.size.height);
        glEnable(GL_SCISSOR_TEST);
    }
    CCLayerColor::visit();
    if (!m_pListViewParent)
    {
        glDisable(GL_SCISSOR_TEST);
    }
}
일단 디버깅중 factor에다 ScreenScaleFactor와 같은 값을 넣어주면 정상적으로 되더군요. 하지만 이건 이부분이 문제다라는 것을 찾았다는데 의미만 있을뿐이죠. 정식으로 해결하고자 구글링 통해 해결 방법을 찾았는데요. 먼저 링크부터

http://www.cocos2d-x.org/boards/6/topics/12396
http://www.cocos2d-x.org/boards/18/topics/14464


rectSelf.origin.x *= factor;
rectSelf.origin.y *= factor;
rectSelf.size.width *= factor;
rectSelf.size.height *= factor;

glScissor((GLsizei)rectSelf.origin.x, (GLsizei)rectSelf.origin.y, (GLsizei)rectSelf.size.width , (GLsizei)rectSelf.size.height);
위 소스부분을 주석처리하고 glScissor 대신


CCEGLView::sharedOpenGLView().setScissorInPoints((GLsizei)rectSelf.origin.x, (GLsizei)rectSelf.origin.y, (GLsizei)rectSelf.size.width , (GLsizei)rectSelf.size.height);
이렇게 CCEGLView에 대체하니까 잘 되는군요.

CCScrollView의 경우에는

void CCScrollView::beforeDraw()
{
    if (m_bClippingToBounds) 
    {
  // TODO: This scrollview should respect parents' positions
  CCPoint screenPos = this->convertToWorldSpace(this->getParent()->getPosition());

        glEnable(GL_SCISSOR_TEST);
        float s = this->getScale();

        CCDirector *director = CCDirector::sharedDirector();
        s *= director->getContentScaleFactor();

        glScissor((GLint)screenPos.x, (GLint)screenPos.y, (GLsizei)(m_tViewSize.width*s), (GLsizei)(m_tViewSize.height*s));
    }
}
이 부분을 수정해야 합니다. 마찬가지로 glScissor부분을 주석하고

CCEGLView::sharedOpenGLView().setScissorInPoints((GLsizei)screenPos.x, (GLsizei)screenPos.y, (GLsizei)m_tViewSize.width , (GLsizei)m_tViewSize.height);
이렇게 추가하시고 제일 윗 부분에

#include "CCEGLView.h"
해줍니다.

더 확인을 해보니 CCScrollView는

pDirector->enableRetinaDisplay(true);
만 해줘도 문제가 발생했긴 하더군요. 아무래도 size관련된 factor를 가지고 처리하는 부분이 아직 버그가 있는 듯 싶네요. 특히나 위와 같이 수정을 해줘도 위쪽과 오른쪽 스크롤 부분에 버그가 있네요. CCScrollView 아직 문제가...

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.