在UIScrollView中平滑缩放 - 如何在OpenGL ES 1.1中实现?

时间:2011-06-03 12:15:08

标签: objective-c uiscrollview zooming

我有两个UIScrollView,应该滚动并同步重绘。 此外,我有EAGLView视图(在其他视图上),其中绘制了这两个UIScrollView的内容。 EAGLView视图具有UIScrollView视图数组,并为每个视图激活绘图功能。

[self BeginRedrawWindow];
for (unsigned int nView = 0; nView < nCountViews; nView++)
{
curView = &(views[nView]);
rcViewFrame = [curView->m_pDrawView GetFrameRect];
rcClipRect = CGRectMake(rcViewFrame.origin.x - rcOwnFrame.origin.x, 
rcViewFrame.origin.y - rcOwnFrame.origin.y, 
rcViewFrame.size.width, 
rcViewFrame.size.height);
curView->m_DrawContext.BeginDrawing(rcClipRect.origin.x, rcClipRect.origin.y); //just reset some params
curView->m_DrawContext.SetClipRect(&rcClipRect);
[curView->m_pDrawView DrawInToDeviceContext:&(curView->m_DrawContext)];
}
[self EndRedrawWindow];

,其中

- (void)BeginRedrawWindow
{
glViewport(0, 0, m_nBackingWidth, m_nBackingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0.0f, (GLfloat)m_nBackingWidth, 0.0f, (GLfloat)m_nBackingHeight, 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Clears the view with black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:m_context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_viewFramebuffer);
glClear(GL_COLOR_BUFFER_BIT);
//correct matrix pos
glTranslatef(0, (CGFloat)m_nBackingHeight, 0);
}

- (void)EndRedrawWindow
{
ImgSize curImgSize = _skinMgr.GetCurrentImgSize();
glBindTexture(GL_TEXTURE_2D, m_cellsTextureArr[curImgSize]);
// Enable use of the texture
glEnable(GL_TEXTURE_2D);
// Set a blending function to use
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Enable blending
glEnable(GL_BLEND);
GLDrawItem* curView;
for (unsigned int nView = 0; nView < nCountViews; nView++)
{
curView = &(views[nView]);
[self ApplyContextData:&(curView->m_DrawContext)];
}

glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_viewRenderbuffer);
[m_context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (void)ApplyContextData:(GLDrawContext*)ctx
{
CGRect clipRect;
BOOL bEnableClipRect = ctx->GetClipRect(&clipRect);
//set clip rect
if (bEnableClipRect)
{
glEnable(GL_SCISSOR_TEST);
glScissor(clipRect.origin.x, m_nBackingHeight - clipRect.origin.y - clipRect.size.height, clipRect.size.width, clipRect.size.height);
}
const unsigned int nCountItems = ctx->GetCountCells();
if (nCountItems > 0)
{
const GLfloat* verticesBack = ctx->GetVertices_Back();
const GLfloat* texcoordsBack = ctx->GetTexcoords_Back();
glVertexPointer(2, GL_FLOAT, 0, verticesBack);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texcoordsBack);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, POINTS_PER_CELL * nCountItems);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
//disable clip rect
if (bEnableClipRect)
{
glDisable(GL_SCISSOR_TEST);
}
}

UIScrollView的绘图功能大致如下所示:

//go throuth lines
for (int nCellY = firstDrawCell.y; nCellY < m_nCountRows; nCellY++)
{
//go throuth cell by x axe
for (int nCellX = firstDrawCell.x; nCellX < m_nCountCols; nCellX++)
{
CCell* pCurCell = m_pPuzzleBoard->GetCell(eMainCells, nCellX, nCellY);
bool bSelected = false;
//
if (m_bPressedOnCell)
{
if ((m_PressedCell.x == nCellX) || (m_PressedCell.y == nCellY))
bSelected = true;
}
ImgCellType cellType = _skinMgr.GetCellTypeFromState(pCurCell->m_eState, bSelected);
pDrawCtx->AddNewCell(cellType, curDrawPoint.x, curDrawPoint.y);
//for separator
if (((nCellX + 1) < m_nCountCols) && ((nCellX + 1) % m_GridStep.cx == 0))
{
curDrawPoint.x += m_nGridSize;
}
curDrawPoint.x += m_cellSize.width;
//
if (curDrawPoint.x >= rect.size.width)
break;
} 
//for separator
if (((nCellY + 1) < m_nCountRows) && ((nCellY + 1) % m_GridStep.cy == 0))
{
curDrawPoint.y += m_nGridSize;
}
curDrawPoint.y += m_cellSize.height;
curDrawPoint.x = firstDrawCellPoint.x;
//
if (curDrawPoint.y >= rect.size.height)
break;
}

BOOL GLDrawContext:: AddNewCell(ImgCellType cellType, float posX, float posY)
{
ImgElDimensionsF cellDimensions = _skinMgr.GL_GetCurrerntCellDimensions(cellType);
ImgTextureInfoF imgCellInfo = m_pCellTextureInfo[cellType];
if (m_nCurAddCrossCell >= m_nMaxCountCrossCell)
return FALSE;
const int idx = m_nCurAddCrossCell * ELEMENTS_PER_CELL;
//*-------
//|  3--4
//|  |  |
//|  1--2
//*
/* 1X */
m_spriteVerticesCross[idx + 0] = posX;
/* 1Y */
m_spriteVerticesCross[idx + 1] =  -posY - cellDimensions.fHeight;
/* 2X */
m_spriteVerticesCross[idx + 2] = posX + cellDimensions.fWidth;
/* 2Y */
m_spriteVerticesCross[idx + 3] = -posY - cellDimensions.fHeight;
/* 3X */
m_spriteVerticesCross[idx + 4] = posX;
/* 3Y */
m_spriteVerticesCross[idx + 5] = -posY;
/* 2X */
m_spriteVerticesCross[idx + 6] = posX + cellDimensions.fWidth;
/* 2Y */
m_spriteVerticesCross[idx + 7] = -posY - cellDimensions.fHeight;
/* 3X */
m_spriteVerticesCross[idx + 8] = posX;
/* 3Y */
m_spriteVerticesCross[idx + 9] = -posY;
/* 4X */
m_spriteVerticesCross[idx + 10] = posX + cellDimensions.fWidth;
/* 4Y */
m_spriteVerticesCross[idx + 11] = -posY;
//1--2
//|  |
//3--4
//
/* 1X */
m_spriteTexcoordsCross[idx + 0] = imgCellInfo.fX;
/* 1Y */
m_spriteTexcoordsCross[idx + 1] = imgCellInfo.fY + imgCellInfo.fHeight;
/* 2X */
m_spriteTexcoordsCross[idx + 2] = imgCellInfo.fX + imgCellInfo.fWidth;
/* 2Y */
m_spriteTexcoordsCross[idx + 3] = imgCellInfo.fY + imgCellInfo.fHeight;
/* 3X */
m_spriteTexcoordsCross[idx + 4] = imgCellInfo.fX;
/* 3Y */
m_spriteTexcoordsCross[idx + 5] = imgCellInfo.fY;
/* 2X */
m_spriteTexcoordsCross[idx + 6] = imgCellInfo.fX + imgCellInfo.fWidth;
/* 2Y */
m_spriteTexcoordsCross[idx + 7] = imgCellInfo.fY + imgCellInfo.fHeight;
/* 3X */
m_spriteTexcoordsCross[idx + 8] = imgCellInfo.fX;
/* 3Y */
m_spriteTexcoordsCross[idx + 9] = imgCellInfo.fY; 
/* 4X */
m_spriteTexcoordsCross[idx + 10] = imgCellInfo.fX + imgCellInfo.fWidth;
/* 4Y */
m_spriteTexcoordsCross[idx + 11] = imgCellInfo.fY;
//
return TRUE;
}

每个UIScrollView的内容由单元格(如棋盘)组成。有四个单元格数组,每个数组包含指定大小的单元格。在缩放时,选择具有最佳绘图尺寸的销售,并使用OpenGL 1.1绘制。所有四个纹理的初始化在绘图窗口初始化时开始。 内容的缩放发生在这些窗口中。通过添加计算的新距离(通过手指传递(分开或收敛))乘以常系数来形成缩放值:

fNewZoom += fDistance * fCoef;

fdistance可以在减少时具有负值。 消息处理时调用重绘的绘图功能:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

不是逐渐变焦,而是急剧变焦。以某种方式画画很慢(大约6-7 fps)。我该怎么做正确的缩放?如何优化绘图,例如Crosswords for iPhone/iPad程序中的绘图?用OpenGL 1.1绘制500 - 600个小方块真的是非常耗费资源的工作吗?我究竟做错了什么?请帮我解决这个问题。

0 个答案:

没有答案