如何动态操作纹理内容? [英] How to manipulate texture content on the fly?

查看:122
本文介绍了如何动态操作纹理内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用我正在制作的iPad应用程序,我们正在考虑的一个可能功能是允许用户触摸图像并对其进行变形。

I have an iPad app I am working on and one possible feature that we are contemplating is to allow the user to touch an image and deform it.

基本上是图像就像一幅画,当用户将手指拖过图像时,图像会变形,触摸的像素将沿着图像拖动。很抱歉,如果这很难理解,但最重要的是我们想要在用户与之交互时动态编辑纹理的内容。

Basically the image would be like a painting and when the user drags their fingers across the image, the image will deform and the pixels that are touched will be "dragged" along the image. Sorry if this is hard to understand, but the bottom line is that we want to edit the content of the texture on the fly as the user interacts with it.

是否有对这样的事情有效的技术?
我试图弄清楚需要做什么以及操作会有多重。

Is there an effective technique for something like this? I am trying to get a grasp of what would need to be done and how heavy an operation it would be.

现在我唯一能想到的就是是基于触摸的位置搜索纹理的内容并复制像素数据,并在手指移动时对现有像素数据进行某种混合。然后定期用glTexImage2D重新加载纹理以获得此效果。

Right now the only thing I can think of is to search through the content of the texture based on where was touched and copy the pixel data and do some kind of blend on the existing pixel data as the finger moves. Then reloading the texture with glTexImage2D periodically to get this effect.

推荐答案

至少有两种根本不同的方法:

There are at least two fundamentally different approaches:

1。更新像素(我认为这就是你在问题中的意思)

1. Update pixels (i assume this is what you mean in the question)

更改纹理中像素的最有效方法是渲染到 - 纹理可以通过 FBO 在OpenGL / OpenGL ES中完成。在桌面OpenGL上,您可以使用像素缓冲对象( PBO )直接在GPU上操作像素数据(但OpenGL ES不支持这还没有。

The most effective technique to change the pixels in the texture is called Render-to-Texture and can be done in OpenGL/OpenGL ES via FBOs. On desktop OpenGL you can use pixel buffer objects (PBOs) to manipulate pixel data directly on GPU (but OpenGL ES does not support this yet).

在未扩展的OpenGL上,您可以更改系统内存中的像素,然后使用glTexImage2D / glTexSubImage2D更新纹理 - 但这是效率低下的最后解决方案,应该避免使用如果可能的话。 glTexSubImage2D 通常要快得多,因为它只更新现有纹理内的像素,而glTexImage2D创建全新的纹理(可以改变纹理的大小和像素格式)。另一方面,glTexSubImage2D只允许更新纹理的一部分。

On unextended OpenGL you can change the pixels in system memory and then update texture with glTexImage2D/glTexSubImage2D - but this is inefficient last resort solution and should be avoided if possible. glTexSubImage2D is usually much faster since it only updates pixel inside the existing texture, while glTexImage2D creates entirely new texture (as a benefit you can change the size and pixel format of the texture). On the other side, glTexSubImage2D allows to update only parts of the texture.

你说你想让它与OpenGL ES一起使用,所以我建议你做以下几点步骤:

You say that you want it to work with OpenGL ES, so I would propose to do the following steps:


  • 用glTexSubImage2D()替换glTexImage2D() - 如果你获得了足够的性能,就让它成为现实;

  • 使用FBO和着色器实现渲染到纹理 - 它将需要
    更多的工作来重写代码,但是会提供更好的
    性能。

对于FBO,代码可能如下所示:

For FBOs the code can look like this:

// 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 );

请记住,并非所有像素格式都可以渲染到。 RGB / RGBA通常很好。

Keep in mind that not all pixel formats can be rendered to. RGB/RGBA are usually fine.

2。更新几何

您还可以更改纹理所映射的对象的几何。应该对几何体进行足够的细分以允许平滑的交互并防止出现伪影。几何变形可以通过不同的方法完成:参数曲面,NURBS,补丁。

You can also change the geometry of the object your texture is mapped on. The geometry should be tesselated enough to allow smooth interaction and prevent artifacts to appear. The deformation of geometry can be done via different methods: parametric surfaces, NURBS, patches.

这篇关于如何动态操作纹理内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆