Opengl在Android上正确转换反馈

时间:2017-01-13 11:46:59

标签: java android opengl-es transform-feedback

我一直在努力创建一个关于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
    
  5. 现在,我的问题是:

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

1 个答案:

答案 0 :(得分: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是不够的。