gpt4 book ai didi

macos - 如何在共享上下文中渲染到 FBO?

转载 作者:行者123 更新时间:2023-12-04 17:10:32 26 4
gpt4 key购买 nike

我有一个应用程序需要执行以下操作:

  • 将纹理从磁盘加载到 GL 纹理
  • 在其上运行图像过滤器(通过 FBO 将其渲染到另一个纹理上)
  • 在屏幕上显示生成的纹理

  • 我有那么多工作。

    接下来,我希望能够将第 2 步移至单独的共享 GL 上下文。

    在初始化时,我创建了一个共享上下文:
    rootContext = CGLGetCurrentContext();
    CGLPixelFormatObj pf = CGLGetPixelFormat(rootContext);
    CGLCreateContext(pf, rootContext, &childContext);

    ...然后使其成为最新并在其上设置帧缓冲区...
    CGLSetCurrentContext(childContext);
    glGenTextures(1, &childTexture);
    glBindTexture(GL_TEXTURE_2D, childTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glGenFramebuffers(1, &childFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, childFramebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, childTexture, 0);

    然后,当需要渲染每一帧时,我制作 childContext当前并呈现给它:
    CGLSetCurrentContext(childContext);
    glBindFramebuffer(GL_FRAMEBUFFER, childFramebuffer);
    glUseProgram(childProgram);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, inputTexture);
    glUniform1i(childTextureUniform, 0);

    glBindBuffer(GL_ARRAY_BUFFER, childQuadPositionBuffer);
    glVertexAttribPointer(childPositionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0);
    glEnableVertexAttribArray(childPositionAttribute);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, childQuadElementBuffer);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
    glDisableVertexAttribArray(childPositionAttribute);

    glUseProgram(0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    ...然后我制作 rootContext当前并将 FBO 的纹理渲染到屏幕:
    CGLSetCurrentContext(rootContext);
    glUseProgram(rootProgram);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, childTexture); // This texture was created and populated on childContext.
    glUniform1i(rootTextureUniform, 0);

    glBindBuffer(GL_ARRAY_BUFFER, rootQuadPositionBuffer);
    glVertexAttribPointer(rootPositionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0);
    glEnableVertexAttribArray(rootPositionAttribute);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rootQuadElementBuffer);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
    glDisableVertexAttribArray(rootPositionAttribute);

    glUseProgram(0);

    这完美运行 如果我注释掉 CGLSetCurrentContext(childContext);来电 .

    但是,如果我切换到共享上下文以渲染到 FBO,我会在屏幕上看到出现故障的垃圾,好像什么都没有渲染到 childTexture :

    glitchy garbage rendered onscreen when using shared contexts

    ...这真的很酷,但我会在这里寻求一种更现实主义的美学。

    关于在使用共享上下文时如何使其工作的任何想法?

    我已经试过了
  • 检查 CGLError s 创建共享上下文时——没有错误;它已成功创建。
  • 检查glGetError() — 没有错误。
  • 检查glCheckFramebufferStatus() — 它是 GL_FRAMEBUFFER_COMPLETE .
  • 调用glBindTexture(GL_TEXTURE_2D, 0);在每个 glDisableVertexAttribArray() 之后正如@datenwolf 所建议的那样打电话。不用找了。

  • 完整的源代码

    我创建了 2 个简单的测试应用程序,它们都表现出相同的问题:
  • http://softpixel.com/~smokris/FBOTest-Cocoa.zip — 使用 Cocoa 设置 GL 窗口
  • http://softpixel.com/~smokris/FBOTest-Qt.zip — 使用 Qt 设置 GL 窗口
  • 最佳答案

    帧缓冲区对象 (FBO) 不能在上下文之间共享。 Only data carrying objects (textures, buffer objects, etc) are shared .抽象对象,即仅绑定(bind)其他对象并管理状态的对象(帧缓冲区对象,顶点数组对象)不是。
    因此绑定(bind)您在其他上下文中创建的 FBO 不起作用。但是您可以在辅助上下文中创建一个 FBO,并将主要上下文中的纹理对象绑定(bind)为颜色附件就好了。
    更新
    如果 FBO 目标纹理在主要上下文中绑定(bind)为纹理源,则可能会出现另一个问题,同时它也应该用作渲染目标。实际上,对于 OpenGL 规范对这种情况的说法,我并不确定^1(我可能不得不深入研究规范,大概是我们的一半左右),但我猜驱动程序可能会认为这是一种情况,即FBO 不能以纹理为目标。所以我建议你使用互斥锁或信号量来同步主线程中纹理的绑定(bind)/解除绑定(bind)与辅助线程中FBO的绑定(bind)。

    1 :编辑OpenGL规范说,可以在光栅化操作中获取片段的纹理层不能同时用作FBO渲染目标;但是他们自己的 OpenGL 规范的措辞并没有明确考虑共享上下文。但我很确定,受共享上下文的约束并有可能随时获取资源,满足了这个约束。在我自己的项目中,如果我在这种情况下实现这样的东西,我会自动实现双缓冲或三缓冲方案,并渲染到缓冲区 (n+1)%M从缓冲区获取数据时 n%M .

    关于macos - 如何在共享上下文中渲染到 FBO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16782279/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com