如何在OpenGL Image Viewer中跟踪“突出显示”

时间:2019-07-11 04:02:14

标签: android opengl-es

我正在尝试为OpenGL图像查看器实现一种“突出显示”功能的方法。我的想法是,我希望用户能够点击图像以突出显示一个区域,到目前为止,效果很好。我面临的问题是用户再次点击时。我想将两个高光都保留在放置它们的图像上。在第二次点击到达的时刻,第一个突出显示消失。

这是我当前的片段着色器:

precision mediump float;
uniform vec4 vColor;
varying vec2 v_TexCoordinate;
uniform sampler2D u_Image;
uniform float u_touchX;
uniform float u_touchY;

void main() {

    float radius = 0.1;
    float a = v_TexCoordinate.x - u_touchX;
    float b = v_TexCoordinate.y - u_touchY;
    float d = sqrt(abs(a*a + b*b));

    if(d < radius){
        gl_FragColor = texture2D(u_Image, v_TexCoordinate) + vColor;
    }else{
        gl_FragColor = texture2D(u_Image, v_TexCoordinate);
    }
}

很简单,我传入图像,突出显示颜色以及用户点击屏幕的位置的x和y。如果片段在该点的一定距离内,则添加高光。到目前为止效果很好。

显然,一旦该触摸点移动,原始的高光就消失了。

我的目标是使此功能尽可能在GPU端运行。

到目前为止,我有一些想法,但是我希望比我更聪明的人可以向我展示一种更好的方法。

  1. 我最不喜欢的策略是跟踪CPU端的XY接触点,并每帧向下传递更新的列表。这里明显的缺陷是,触摸列表可能很快就变得很大,因此屠宰性能很快。我希望用户能够根据需要突出显示整个图像,而这种解决方案似乎并不实际。
  2. 跟踪CPU上图像中每个像素的状态。我想我可以通过创建一个位图(或者代表每个像素的2D bool数组)来实现图像的确切尺寸,并跟踪哪个片段被“突出显示”。然后,将整个数组作为一个统一数组向下传递,并将每个v_TexCoordinate与数组中的相应值进行比较。我也不喜欢这个想法(尽管它比#1更好),因为它又需要每帧将大量数据移入GPU。在旧的android设备上,这很容易成为一个初学者。
  3. 我遇到了类似问题的答案here。询问者想操纵纹理数据,答案建议在使用FBO时使用“渲染到纹理”方法。我有点主意,但我真的不明白这将如何解决记住以前的“亮点”的问题。也许我很傻,想念这个答案可能告诉我的东西,但... \ _(ツ)_ /¯

必须有一个更好的方法,但是我目前空虚,希望有人可以指出正确的方向。

1 个答案:

答案 0 :(得分:2)

如果突出显示只是添加的,则创建第二个纹理并将突出显示区域渲染到其中。只需在基础层上进行添加剂混合即可渲染。尝试在GLSL中创建突出显示区域的数据库可能要容易得多。