我最近在绘画应用程序中实现缩放功能时遇到了一些问题。请允许我首先向您提供一些背景信息。
首先,我开始修改Apple的glPaint演示应用程序。我认为这是一个很好的来源,因为它向您展示了如何设置EAGLView等...
现在,我接下来要做的是实现缩放功能。在做了一些研究之后,我尝试了两种不同的方法。
1)使用glOrthof
2)更改我的EAGLView的帧大小。
虽然这两种方式都让我可以完美地放大/缩小,但是当我在放大时实际绘画时,我遇到了不同的问题。
当我使用(1)时,我必须渲染这样的视图:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(left, right, bottom, top, -1.0f, 1.0f); //those values have been previously calculated
glDisable(GL_BLEND);
//I'm using Apple's Texture2D class here to render an image
[_textures[kTexture_MyImage] drawInRect:[self bounds]];
glEnable(GL_BLEND);
[self swapBuffers];
现在,让我们假设我放大了一点,然后我画画,之后,我想再缩小。为了使其工作,我需要确保“kTexture_MyImage”始终包含最新的更改。为此,我需要在完成更改后捕获屏幕内容并将其与原始图像合并。这里的问题是,当我放大时,我的屏幕只显示图像的一部分(放大),我还没有找到适当的方法来解决这个问题。
我试图计算屏幕的哪个部分被放大,然后进行捕捉。之后,我会将此部分调整为原始大小,并使用另一种方法将其粘贴到正确位置的原始图像中。
现在,我可以更详细地了解我是如何实现这一目标的,但它确实非常复杂,我想,必须有一个更简单的方法。已经有几个应用程序,完美的,我想要实现的,所以它一定是可能的。
就方法(2)而言,我可以避免上述大部分内容,因为我只改变了EAGLView窗口的大小。然而,在绘画时,笔画离开了预期的位置。我可能需要在绘制时考虑缩放级别,并以不同的方式重新计算CGPoints。
但是,如果你过去做过类似的事情或者可以给我一个提示,我如何实现放大我的绘画应用程序,我真的很感激。
提前致谢。
答案 0 :(得分:1)
是的,这绝对是可能的。
在绘制程序时,您应该保留一个链接列表或对象树来绘制,以便于插入/删除。当用户停止绘画(即touchesEnded)时,您将对象添加到包含场景的数据结构中。
当用户缩放时,您需要根据当前视口,投影和模型视图变换调整要绘制的对象的坐标。在您的情况下,您不会更改视口或模型视图变换,因此您只需要考虑投影变换。您还可以使用模型视图矩阵上的平移和缩放来实现缩放,但为了简单起见,我将忽略这种情况,因为它涉及反转变换。
好消息是您正在使用正交投影,因此当没有缩放生效时,世界坐标对应于窗口坐标。您的案例中的“世界”是一个简单的画布,可能与窗口坐标中设备的大小相对应。
在将对象添加到场景数据结构之前,使用当前投影变换(即glOrthof()调用的参数)将所有坐标转换为世界坐标(即全画布坐标)。如果您将模型中的所有内容保留在相同的坐标空间中,您将保持理智。
要转换坐标,假设您无法在glOrtho()调用中缩小过去的整个设备尺寸,则必须按照缩放的正交尺寸与未弯曲的正交尺寸的比例缩小它们然后偏置它们通过缩放的正交底部,左边的值和原始的未矫正的正交值之间的差异。