如何在OpenGL ES 2.0中模拟累积缓冲区(跟踪粒子效果)

因此,我一直在尝试使用OpenGL ES 2.0创建尾随的粒子效果(请参见此处)。不幸的是,使之成为可能的OpenGL命令(累积缓冲区)似乎在OpenGL ES中不可用。这意味着必须走很长的路。

主题描述了执行此操作的一种可能方法。但是,我对如何将内容存储在缓冲区中以及合并缓冲区感到非常困惑。因此,我的想法是执行以下操作。

  1. 使用写入纹理的缓冲区将当前帧绘制到纹理中
  2. 将先前的帧(但已褪色)绘制到另一个缓冲区中。
  3. 将步骤1放在步骤2的上面。
  4. 保存显示的任何内容以供下一帧使用。

到目前为止,我的理解是缓冲区以与纹理相同的方式存储像素数据,只是缓冲区可以更轻松地绘制为使用着色器。

因此,想法可能是渲染到缓冲区,然后将其移动到纹理中。

我发现这样做的一种理论是

回想起来,您应该创建两个FBO(每个FBO都有自己的纹理)。使用默认的帧缓冲区是不可靠的(不能保证在帧之间保留内容)。

绑定第一个FBO后,将其清除,然后正常渲染场景。渲染场景后,使用纹理作为源并将其渲染到第二个FBO中进行混合(永远不会清除第二个FBO)。这将导致第二个FBO包含新场景和之前场景的混合。最后,第二个FBO应该直接渲染到窗口(可以通过渲染带纹理的四边形,类似于之前的操作,或使用glBlitFramebuffer来完成)。

本质上,第一个FBO代替默认帧缓冲区,而第二个FBO代替累积缓冲区。

总之:

初始化:

对于每个FBO:-glGenTextures-glBindTexture-glTexImage2D-glBindFrameBuffer-glFramebufferTexture2D

每帧:

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo1)glClear glDraw * //场景

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo2)glBindTexture(tex1)glEnable(GL_BLEND)glBlendFunc glDraw * //全屏四边形

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,0)glBindFrameBuffer(GL_READ_FRAMEBUFFER,fbo2)glBlitFramebuffer

不幸的是,它没有足够的代码(尤其是初始化让我起步)。

但是我已经尝试过了,到目前为止,我得到的只是一个令人失望的空白屏幕。我真的不知道我在做什么,所以这段代码可能是错误的。

var fbo1:GLuint = 0
var fbo2:GLuint = 0
var tex1:GLuint = 0

Init()
{
    //...Loading shaders  OpenGL etc.   
    //FBO 1
        glGenFramebuffers(1, &fbo1)
        glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo1)

        //Create texture for shader output
        glGenTextures(1, &tex1)
        glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
        glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)

        glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
        //FBO 2
        glGenFramebuffers(1, &fbo2)
        glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo2)

        //Create texture for shader output
        glGenTextures(1, &tex1)
        glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
        glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)

        glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
}

func drawFullScreenTex()
{
        glUseProgram(texShader)
        let rect:[GLint] = [0, 0, GLint(width), GLint(height)]
        glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
        //Texture is allready
        glTexParameteriv(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_CROP_RECT_OES), rect)
        glDrawTexiOES(0, 0, 0, width, height)
 }

fun draw()
{
    //Prep
        glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo1)
        glClearColor(0, 0.1, 0, 1.0)
        glClear(GLbitfield(GL_COLOR_BUFFER_BIT))

        //1
        glUseProgram(pointShader);
        passTheStuff() //Just passes in uniforms
        drawParticles(glGetUniformLocation(pointShader, "color"), size_loc: glGetUniformLocation(pointShader, "pointSize")) //Draws particles


        //2
        glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo2)
        drawFullScreenTex()


        //3
        glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), 0)
        glBindFramebuffer(GLenum(GL_READ_FRAMEBUFFER), fbo2)
        glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_NEAREST))

}

顺便说一句,这是我发现有用的一些资源。

  1. 网站1
  2. 网站2
  3. 网站3
  4. 网站4

我的主要问题是:有人可以为此写出代码。我想我了解其中涉及的理论,但是我花了很多时间徒劳地尝试应用它。

如果您想要一个开始的地方,我这里有一个Xcode项目,它绘制点,并且有一个蓝色的项目在这里周期性地在屏幕上移动,并且无效的代码也在其中。

注意:如果您要编写代码,则可以使用任何语言c ++,java,swift,objective-c,都可以。只要是用于OpenGL-ES

苍鹭

glGenTextures(1, &tex1)使用相同的变量tex1调用两次。这将覆盖变量。以后调用时glBindTexture(GLenum(GL_TEXTURE_2D), tex1),它不会绑定与fbo1对应的纹理,而是绑定fbo2的纹理。每个fbo需要不同的纹理。

作为参考,以下是我的工作程序的示例,该程序使用多个FBO并渲染为纹理。

GLuint fbo[n];
GLuint tex[n];

init() {
    glGenFramebuffers(n, fbo);
    glGenTextures(n, tex);

    for (int i = 0; i < n; ++i) {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);

        glBindTexture(GL_TEXTURE_2D, tex[i]);
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[i], 0);
    }
}

render() {

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[0]);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw scene into buffer 0

    glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT);

    glBindTexture(cbo[0]);

    //Draw full screen tex


    ...


    glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, 0);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT);

    glBindTexture(cbo[n - 1]);
    // Draw to screen

    return;
}

一些注意事项。为了使其正常工作,我必须添加纹理参数。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

这是因为在我的系统上,它们默认为GL_NEAREST_MIPMAP_LINEAR。这对于FBO纹理不起作用,因为没有生成mipmap。将它们设置为您喜欢的任何东西。

另外,请确保您启用了

glEnable(GL_TEXTURE_2D)

我希望这将有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在OpenGL ES 2中正确缩放

来自分类Dev

如何在OpenGL ES 2中处理多个对象

来自分类Dev

如何在OpenGL ES 1.1中处理索引缓冲区

来自分类Dev

如何在openGL ES 2.0中执行2次传递以获得模糊效果

来自分类Dev

如何将遮罩滤镜应用于OpenGL ES 2中的当前帧缓冲区

来自分类Dev

如何在opengl es 2.0中的2D游戏中设置深度范围?

来自分类Dev

如何在OpenGL ES 2中使用顶点数组对象

来自分类Dev

如何在 OpenGL 中重新定位绑定到帧缓冲区的 2D 纹理?

来自分类Dev

Android OpenGL ES 2:如何在主活动中将OpenGL活动用作片段

来自分类Dev

Android OpenGL ES 2:如何在主活动中将OpenGL活动用作片段

来自分类Dev

如何在Android的OpenGL ES中渲染深度纹理

来自分类Dev

如何在OpenGL ES 2.0中管理多个纹理?

来自分类Dev

如何在Common Lisp中编写opengl ES 2.0 / 3.0?

来自分类Dev

如何在iOS OpenGL ES 2.0中画星

来自分类Dev

如何在 Android 的 OpenGL ES 2.0 中检查上传的纹理?

来自分类Dev

在opengl es 2中如何释放纹理(ios硬崩溃)

来自分类Dev

如何在SDL2中显示OpenGL纹理

来自分类Dev

如何使用OpenGL ES的顶点和索引缓冲区填充结构权

来自分类Dev

OpenGL ES2.0将8位图像加载到模板缓冲区中

来自分类Dev

在适用于iOS的OpenGl ES 2.0中写入单通道像素缓冲区

来自分类Dev

glClear上的“无效帧缓冲区操作”-在OpenGL ES3中使用sRGB

来自分类Dev

OpenGL ES2.0将8位图像加载到模板缓冲区中

来自分类Dev

使用顶点缓冲区对象的最低OpenGL ES版本

来自分类Dev

OpenGL ES 3.0上的sRGB帧缓冲区

来自分类Dev

OpenGL ES上深度缓冲区的精度

来自分类Dev

增量更新OpenGL ES的屏幕缓冲区

来自分类Dev

OpenGL ES2.0 glReadPixels()从渲染缓冲区通过帧缓冲区读取数据

来自分类Dev

顶点缓冲区的渲染数组OenGL ES2

来自分类Dev

在OpenGL ES 2.0中,将FBO与纹理深度缓冲区一起使用时,深度纹理缓冲区不起作用

Related 相关文章

  1. 1

    如何在OpenGL ES 2中正确缩放

  2. 2

    如何在OpenGL ES 2中处理多个对象

  3. 3

    如何在OpenGL ES 1.1中处理索引缓冲区

  4. 4

    如何在openGL ES 2.0中执行2次传递以获得模糊效果

  5. 5

    如何将遮罩滤镜应用于OpenGL ES 2中的当前帧缓冲区

  6. 6

    如何在opengl es 2.0中的2D游戏中设置深度范围?

  7. 7

    如何在OpenGL ES 2中使用顶点数组对象

  8. 8

    如何在 OpenGL 中重新定位绑定到帧缓冲区的 2D 纹理?

  9. 9

    Android OpenGL ES 2:如何在主活动中将OpenGL活动用作片段

  10. 10

    Android OpenGL ES 2:如何在主活动中将OpenGL活动用作片段

  11. 11

    如何在Android的OpenGL ES中渲染深度纹理

  12. 12

    如何在OpenGL ES 2.0中管理多个纹理?

  13. 13

    如何在Common Lisp中编写opengl ES 2.0 / 3.0?

  14. 14

    如何在iOS OpenGL ES 2.0中画星

  15. 15

    如何在 Android 的 OpenGL ES 2.0 中检查上传的纹理?

  16. 16

    在opengl es 2中如何释放纹理(ios硬崩溃)

  17. 17

    如何在SDL2中显示OpenGL纹理

  18. 18

    如何使用OpenGL ES的顶点和索引缓冲区填充结构权

  19. 19

    OpenGL ES2.0将8位图像加载到模板缓冲区中

  20. 20

    在适用于iOS的OpenGl ES 2.0中写入单通道像素缓冲区

  21. 21

    glClear上的“无效帧缓冲区操作”-在OpenGL ES3中使用sRGB

  22. 22

    OpenGL ES2.0将8位图像加载到模板缓冲区中

  23. 23

    使用顶点缓冲区对象的最低OpenGL ES版本

  24. 24

    OpenGL ES 3.0上的sRGB帧缓冲区

  25. 25

    OpenGL ES上深度缓冲区的精度

  26. 26

    增量更新OpenGL ES的屏幕缓冲区

  27. 27

    OpenGL ES2.0 glReadPixels()从渲染缓冲区通过帧缓冲区读取数据

  28. 28

    顶点缓冲区的渲染数组OenGL ES2

  29. 29

    在OpenGL ES 2.0中,将FBO与纹理深度缓冲区一起使用时,深度纹理缓冲区不起作用

热门标签

归档