fun*_*onk 22 textures opengl-es ipad ios
我有一个我正在研究的iPad应用程序,我们正在考虑的一个可能的功能是允许用户触摸图像并使其变形.
基本上,图像就像一幅画,当用户将手指拖过图像时,图像会变形,触摸的像素将沿着图像"拖动".很抱歉,如果这很难理解,但最重要的是我们想要在用户与之交互时动态编辑纹理的内容.
对于这样的事情,有没有一种有效的技术?我试图弄清楚需要做什么以及操作会有多重.
现在我唯一能想到的就是根据触摸的位置搜索纹理内容并复制像素数据,并在手指移动时对现有像素数据进行某种混合.然后定期用glTexImage2D重新加载纹理以获得此效果.
Ser*_* K. 32
至少有两种根本不同的方法:
1.更新像素(我假设这是你在问题中的意思)
更改纹理中像素的最有效技术称为Render-to-Texture,可以通过FBO在OpenGL/OpenGL ES中完成.在桌面OpenGL上,您可以使用像素缓冲对象(PBO)直接在GPU上操作像素数据(但OpenGL ES尚不支持此功能).
在未扩展的OpenGL上,您可以更改系统内存中的像素,然后使用glTexImage2D/glTexSubImage2D更新纹理 - 但这是效率低下的最后解决方案,应尽可能避免使用.glTexSubImage2D通常要快得多,因为它只更新现有纹理内的像素,而glTexImage2D创建全新的纹理(作为一个好处,你可以改变纹理的大小和像素格式).另一方面,glTexSubImage2D只允许更新纹理的一部分.
您说您希望它与OpenGL ES一起使用,因此我建议您执行以下步骤:
对于FBO,代码可能如下所示:
// setup FBO
glGenFramebuffers( 1, &FFrameBuffer );
glBindFramebuffer( GL_FRAMEBUFFER, FFrameBuffer );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, YourTextureID, 0 );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
// render to FBO
glBindFramebuffer( GL_FRAMEBUFFER, FFrameBuffer );
glViewport( 0, 0, YourTextureWidth, YourTextureHeight );
your rendering code goes here - it will draw directly into the texture
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
// cleanup
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glDeleteFramebuffers( 1, &FFrameBuffer );
Run Code Online (Sandbox Code Playgroud)
请记住,并非所有像素格式都可以呈现.RGB/RGBA通常很好.
2.更新几何体
您还可以更改纹理映射到的对象的几何.应该对几何体进行足够的细分以允许平滑的交互并防止出现伪影.几何变形可以通过不同的方法完成:参数曲面,NURBS,补丁.
我尝试了两种可能可以解决您的问题的方法。这些方法非常不同,所以我想您的具体使用案例将决定哪一种是合适的(如果有的话)。
首先,我用几何体完成了图像变形。也就是说,将我的纹理映射到细分网格,然后将该网格与另一个贝塞尔控制点网格重叠。然后,用户将移动这些控制点,从而以平滑的方式使渲染的几何体的顶点变形。
第二种方法更类似于您在问题中概述的方法。创建纹理时保留该数据,以便您可以直接在那里操作像素。然后调用类似的东西
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
Run Code Online (Sandbox Code Playgroud)
每次你画画的时候。这可能效率非常低,因为它可能涉及每帧重新上传所有纹理数据,我很想听听是否有更好的方法来做到这一点 - 比如直接操作 GPU 上的纹理数据。就我而言,虽然性能足够。
我希望这会有所帮助,尽管它的细节很少。