Merge pull request #2279 from sjchao/master

fixed #2030: Fixing a display bug when a scrollView nested in another scrollView. The parent's scissor rect need to be considered, when setting the scissor rect in the subScrollView.
This commit is contained in:
James Chen 2013-04-07 23:55:55 -07:00
commit d3eed7fd1f
4 changed files with 66 additions and 17 deletions

View File

@ -154,17 +154,33 @@ void CCEGLViewProtocol::setScissorInPoints(float x , float y , float w , float h
(GLsizei)(h * m_fScaleY)); (GLsizei)(h * m_fScaleY));
} }
void CCEGLViewProtocol::setViewName(const char* pszViewName) bool CCEGLViewProtocol::isScissorEnabled()
{ {
if (pszViewName != NULL && strlen(pszViewName) > 0) return glIsEnabled(GL_SCISSOR_TEST);
{ }
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
} CCRect CCEGLViewProtocol::getScissorRect()
} {
GLfloat params[4];
const char* CCEGLViewProtocol::getViewName() glGetFloatv(GL_SCISSOR_BOX, params);
{ float x = (params[0] - m_obViewPortRect.origin.x) / m_fScaleX;
return m_szViewName; float y = (params[1] - m_obViewPortRect.origin.y) / m_fScaleY;
float w = params[2] / m_fScaleX;
float h = params[3] / m_fScaleY;
return CCRectMake(x, y, w, h);
}
void CCEGLViewProtocol::setViewName(const char* pszViewName)
{
if (pszViewName != NULL && strlen(pszViewName) > 0)
{
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
}
}
const char* CCEGLViewProtocol::getViewName()
{
return m_szViewName;
} }
void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[]) void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[])

View File

@ -98,6 +98,16 @@ public:
*/ */
virtual void setScissorInPoints(float x , float y , float w , float h); virtual void setScissorInPoints(float x , float y , float w , float h);
/**
* Get whether GL_SCISSOR_TEST is enable
*/
virtual bool isScissorEnabled();
/**
* Get the current scissor rectangle
*/
virtual CCRect getScissorRect();
virtual void setViewName(const char* pszViewName); virtual void setViewName(const char* pszViewName);
const char* getViewName(); const char* getViewName();

View File

@ -492,11 +492,24 @@ void CCScrollView::beforeDraw()
{ {
if (m_bClippingToBounds) if (m_bClippingToBounds)
{ {
CCRect frame = getViewRect(); m_bScissorRestored = false;
CCRect frame = getViewRect();
glEnable(GL_SCISSOR_TEST); if (CCEGLView::sharedOpenGLView()->isScissorEnabled()) {
m_bScissorRestored = true;
CCEGLView::sharedOpenGLView()->setScissorInPoints(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); m_tParentScissorRect = CCEGLView::sharedOpenGLView()->getScissorRect();
//set the intersection of m_tParentScissorRect and frame as the new scissor rect
if (frame.intersectsRect(m_tParentScissorRect)) {
float x = MAX(frame.origin.x, m_tParentScissorRect.origin.x);
float y = MAX(frame.origin.y, m_tParentScissorRect.origin.y);
float xx = MIN(frame.origin.x+frame.size.width, m_tParentScissorRect.origin.x+m_tParentScissorRect.size.width);
float yy = MIN(frame.origin.y+frame.size.height, m_tParentScissorRect.origin.y+m_tParentScissorRect.size.height);
CCEGLView::sharedOpenGLView()->setScissorInPoints(x, y, xx-x, yy-y);
}
}
else {
glEnable(GL_SCISSOR_TEST);
CCEGLView::sharedOpenGLView()->setScissorInPoints(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
}
} }
} }
@ -508,7 +521,12 @@ void CCScrollView::afterDraw()
{ {
if (m_bClippingToBounds) if (m_bClippingToBounds)
{ {
glDisable(GL_SCISSOR_TEST); if (m_bScissorRestored) {//restore the parent's scissor rect
CCEGLView::sharedOpenGLView()->setScissorInPoints(m_tParentScissorRect.origin.x, m_tParentScissorRect.origin.y, m_tParentScissorRect.size.width, m_tParentScissorRect.size.height);
}
else {
glDisable(GL_SCISSOR_TEST);
}
} }
} }

View File

@ -317,6 +317,11 @@ protected:
* max and min scale * max and min scale
*/ */
float m_fMinScale, m_fMaxScale; float m_fMinScale, m_fMaxScale;
/**
* scissor rect for parent, just for restoring GL_SCISSOR_BOX
*/
CCRect m_tParentScissorRect;
bool m_bScissorRestored;
}; };
// end of GUI group // end of GUI group