1

我一直在努力在 android 上创建一个有效的转换反馈。到目前为止,我得到的最接近的问题与这个被否决的问题类似:https ://stackoverflow.com/questions/41066101/transform-feedback-altering-render-result

我要创建的内容:

从顶点缓冲区对象渲染为变换反馈。然后使用最终的绘图着色器从变换反馈的缓冲区进行渲染。

我如何理解整个概念:

我了解程序与变量链接的方式(我遵循了这个例子:https ://gist.github.com/hpp/d2d26adc5987002eb520 )在Android上,你必须提供一个“虚拟”片段着色器,否则程序链接将失败而没有消息。

拥有链接程序后,这些是步骤:(代码在java中)

  1. 创建一个 VBO 来读取数据

    int[] vbo = new int[1];
    glGenBuffers(1, vbo, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, bufferLength, data, GL_STATIC_READ);
    
  2. 创建变换反馈缓冲区

    int[] tbo = new int[1];
    glGenBuffers(1, tbo, 0);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferLength, null, GL_DYNAMIC_COPY);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]);
    
  3. 每次我想进行计算时,我都会这样称呼:

    glUseProgram(calculationShaderProgram);
    // For all input variables:
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(...
    
    // To bind the transform feedback buffer as the destination
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfo[0]);
    
    glEnable(GL_RASTERIZER_DISCARD);
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, vertexCount);
    glEndTransformFeedback();
    glDisable(GL_RASTERIZER_DISCARD);
    
    glFinish(); // I know this is slow to call, but for simplicity's sake
    
  4. 之后,我应该能够绘制缓冲区的内容:

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo[0]);
    
    glUseProgram(drawShaderProgram);
    // For all input variables:
    glEnableVertexAttribArray(inputAttrib);
    glVertexAttribPointer(...
    
    // Set uniforms ...
    glDrawArrays(GL_POINTS, 0, vertexCount); // There is no glDrawTransformFeedback on android
    

现在,我的问题是:

  • 在这个过程中是否存在固有的错误?
  • 即使我什么都没画,计算部分是否会弄乱我的设备屏幕?(它显示由android更新的随机颜色或图标,如电池和网络)
  • 使用与 GL_TRANSFORM_FEEDBACK_BUFFER 相同的顶点数组对象是否与使用 GL_ARRAY_BUFFER 相同?
4

1 回答 1

2

花了一些时间,但这是解决方案。我将把它留在这里,因为在任何可用的 OpenGL 相关书籍中都没有正确解释这些部分。

  1. 从变换反馈缓冲区(上面的步骤 4)绘制时,它是否用作变换反馈缓冲区都没有关系,您必须将其绑定为 GL_ARRAY_BUFFER,就像从顶点缓冲区对象绘制一样。

    glBindBuffer(GL_ARRAY_BUFFER, tbo[0]);
    
  2. 使用默认帧缓冲区时,

    glBindFrameBuffer(GL_FRAMEBUFFER, 0);
    

    或者根本没有设置,你不能使用

    glEnable(GL_RASTERIZER_DISCARD);
    // Draw to Transform feedback
    // ...
    glDisable(GL_RASTERIZER_DISCARD);
    

    (在步骤 3 中)无需先调用

    glClear(GL_COLOR_BUFFER_BIT);
    

    否则你会看到随机图案作为背景。在每个绘制周期之前执行一次 glClear 是不够的。

于 2017-01-14T09:39:35.710 回答