OpenGL 实现多通道

2024-03-03

我在移植一些已成功实现的代码时遇到问题着色玩具 https://www.shadertoy.com/view/XdyfWK对于桌面 OpenGL,问题是我需要创建一个 FrameBufferObject FBO,以便我可以进行离屏计算,稍后将其传递到主 glsl 片段着色器,问题是该缓冲区需要将自身引用为纹理以获得它能够运行模拟的先前值。

我已经成功创建了 FBO:

// Framebuffer configuration.
unsigned int frameBufferOne;
glGenFramebuffers(1, &frameBufferOne);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferOne);

// Create a colour attachment texture.
unsigned int textureColourBufferOne;
glGenTextures(1, &textureColourBufferOne);
glBindTexture(GL_TEXTURE_2D, textureColourBufferOne);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColourBufferOne, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

并设法在我的渲染循环中调用它,以便我可以渲染到 FBO,然后将这些值传递到默认帧缓冲区:

// Render Loop.
while( !glfwWindowShouldClose( window ) )
{

    // Input.
    processInput( window );

    // Render.

    // Bind to frameBuffer and draw scene as normally would to colour texture.
    glBindFramebuffer( GL_FRAMEBUFFER, frameBufferOne );

    glClearColor( 0.2f, 0.3f, 0.1f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT );

    bufferShader.use();
    float currentFrame = glfwGetTime();
    //Set the iTimeDelta uniform.
    float deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;
    bufferShader.setFloat( "iTimeDelta", deltaTime );
    // Set the iTime uniform.
    float timeValue = currentFrame;
    bufferShader.setFloat( "iTime", timeValue );
    // Set the iResolution uniform.
    bufferShader.setVec2( "iResolution", WIDTH, HEIGHT );
    // Input iMouse.
    double xPos, yPos;
    glfwGetCursorPos( window, &xPos, &yPos );
    yPos = HEIGHT - yPos;
    bufferShader.setVec2( "iMouse", xPos, yPos );

    glBindVertexArray( VAO );
    glBindTexture( GL_TEXTURE_2D, textureColourBufferOne );
    glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
    glBindVertexArray( 0 );

    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    glDisable( GL_DEPTH_TEST );

    glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT );

    ourShader.use();
    ourShader.setVec2( "iResolution", WIDTH, HEIGHT );
    // Set the iTime uniform.
    ourShader.setFloat( "iTime", timeValue );
    glBindVertexArray(VAO);
    glBindTexture( GL_TEXTURE_2D, textureColourBufferOne );
    glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );

    glfwSwapBuffers( window );
    glfwPollEvents();

    frameCount++;
    finalTime = time( NULL );
    if( finalTime - initialTime > 0 )
    {

        std::cout << "FPS : " << frameCount / (finalTime - initialTime) << std::endl;
        frameCount = 0;
        initialTime = finalTime;

    }

但我无法将缓冲区渲染为纹理本身,我知道它输出未定义的行为,并且我应该使用乒乓球技术。

有人能指出我正确的方向吗?


但我无法将缓冲区渲染为纹理本身,我知道它输出未定义的行为,并且我应该使用乒乓球技术。

有人能指出我正确的方向吗?

您必须创建 2 个帧缓冲区对象,就像您对问题中的对象所做的那样:frameBufferOne and frameBufferTwo.
这 2 个帧缓冲区对象中的每一个都必须附加一个纹理对象:textureColourBufferOne and textureColourBufferTwo.

在程序的主循环中,您必须知道帧的编号是偶数还是奇数。
如果数字是偶数那么你必须渲染到textureColourBufferOne渲染通道的输入是textureColourBufferTwo.
如果数字是奇数,那么你必须渲染到textureColourBufferTwo渲染通道的输入是textureColourBufferOne.
渲染的结果始终存储在属于当前帧的帧缓冲区的纹理中:

bool even = true;
while( !glfwWindowShouldClose( window ) )
{
    .....

    glBindFramebuffer( GL_FRAMEBUFFER, even ? frameBufferOne : frameBufferTwo );

    glClearColor( 0.2f, 0.3f, 0.1f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT );

    .....

    glBindVertexArray( VAO );
    glBindTexture( GL_TEXTURE_2D, even ? textureColourBufferTwo : textureColourBufferOne );
    glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
    glBindVertexArray( 0 );

    .....

    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT );

    .....

    glBindVertexArray(VAO);
    glBindTexture( GL_TEXTURE_2D, even ? textureColourBufferOne : textureColourBufferTwo );
    glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );

    glfwSwapBuffers( window );
    glfwPollEvents();

    even = !even;

    .....
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL 实现多通道 的相关文章

随机推荐

  • 右值引用上的 std::vector::emplace_back

    我在类中有以下函数 void add state std string st state emplace back st state is a vector st根据我的理解 是一个左值 在这种情况下对字符串的右值引用 如果 我想搬家st到
  • 在 Angular2 中添加动态属性

    我有现有的 javascript 函数 用于使用 setAttribute 函数创建动态元素 现在我想将属性 ngModel 附加到此元素中以进行双向数据绑定 我尝试添加这个使用 obj setAttribute ngModel 模型名称
  • macOS Safari 缓存响应,而标头指定不缓存

    服务器对 GET 请求的响应具有以下标头 HTTP 1 1 200 OK Content Type application json charset utf 8 Pragma no cache Date Thu 08 Feb 2018 19
  • 使用我自己的 SSL 证书与 Google Cloud Run(完全托管)进行 SSL 固定

    我想要固定完全托管的 Google Cloud Run 集群的证书 我可以固定 Google 生成的 SSL 证书 但我不知道我是否可以依赖他们保留相同的证书直到其过期 而且我无法让客户端为他们将来生成的 SSL 证书做好准备 因为我不在
  • Unix,将文件分割成最大 N 字节的块,保持完整的行

    我想将文件拆分为最大 N 字节的块 同时保留完整的行 类似下面的内容在精确的字节边界上分解每个块的第一行和最后一行 split b 100m d data tsv data tsv 听起来像是一份工作split C split C 100m
  • 检索 Excel 中列等于某值的单元格列表

    我正在尝试在 Excel 中执行某些操作而不使用 VBA 宏 我怀疑这是可能的 但到目前为止还有一些空的 基本上 对于表中的值 我想有条件地检索 A 列中所有值的列表 其中 B 列等于我提供的值 例如 如果 B 列等于 0 我想要一个函数
  • 如何检查 Google Test 是否在我的代码中运行

    我有一段代码 如果正在进行单元测试 我不想运行它 我希望找到一些由 gtest 库设置的 define 标志 我可以检查 我找不到用于此目的的一个 但在查看 gtest 标头后 我找到了一个我认为可以像这样使用的 SomeClass Som
  • 如何同时拖动两个 3D 轴

    基本上 我在一个图中有两个 3d 轴 一个通过 matplotlib animation 构建的动画轴和一个并排的 3d 线图 我想添加功能 以便当您旋转一个轴时 另一个轴也会跟随它的旋转 例如 将当前视角发送到另一个轴的函数 例如 ang
  • 在 Docker 中运行 Blazor

    我使用 Visual Studio 2019 预览版 创建了第一个 Blazor 测试 回购协议是here https github com mitkins holly test 当我在 VS 中点击 IISExpress 按钮时 一切都按
  • Amazon Linux 2 OpenVPN 客户端包不可用?

    当我尝试跑步时sudo yum install openvpn在我刚刚创建的 Amazon Linux 2 实例上 我收到消息 No package openvpn available 我需要添加包存储库吗 我在任何地方都没有发现需要这样做
  • 如何在flutter中过滤列表?

    我正在尝试向我的过滤器添加过滤器list 这就是我所做的 productTemp sort a b gt b productPrice compareTo a productPrice productTemp productTemp whe
  • 如何修复运行 redis:alpine Docker 镜像时出现的警告

    如果我运行Redis 高山 https hub docker com redis 使用命令的 Docker 镜像 docker run redis alpine 我看到几个警告 1 C 08 May 08 29 32 308 Warning
  • 修改android项目名称

    我有没有可能改变name of my project正如它出现在Package Explorer 我正在使用 Eclipse IDE 我尝试编辑string xml in res value文件夹 但这不会在资源管理器视图中更改它 右键单击
  • vue:未捕获类型错误:无法读取未定义的属性...

    我在用着 电子邮件受保护 cdn cgi l email protection和vue 官方 webpack 模板 https github com vuejs templates webpack构建一个应用程序 本地开发时经常看到这样的警
  • 在 Django 应用程序中实现 Facebook 登录的简单且最新的方法

    这个问题在stackoverflow中很常见 并且有很多不同的问题和答案 但我找不到我需要的 首先 我想准确定义我需要的内容 允许用户使用其 Facebook 凭据登录我的应用程序的选项 该应用程序将保存匹配的经典 Django 用户 我只
  • 通过删除旧行自动强制执行最大数据库表大小

    我有一个 Oracle 表 其中包含应用程序的事件日志消息 我们不希望该表增长失控并占用太多空间 因此我们希望将其可以包含的行数设置为某个大数字 例如一百万 所以我们想告诉Oracle 当表变得太大时 它应该删除最旧的行 为新行腾出空间 有
  • 读取文件中的值,循环直到 value = $foo?

    我正在编写一个用于 grep 的 shell 脚本 foo然后计算出现的次数 然后运行命令 每次运行该命令时 该文件中都会减少一个 foo 实例 不确定如何连续读取该文件并减少我设置的变量中的值 count grep o foo some
  • 是否有在线模拟屏幕阅读器工具来测试自定义网页? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们关心我们网站的可访问性 并想看看普通屏幕阅读器如何感知和解码它 不 至少没有任何好处 也不代表屏幕阅
  • Google 地图可以设置为缓慢持续平移吗?就像一场全球革命?

    正如标题所说 我正在寻找解决方案 但没有找到任何可以引导我找到正确文档或文章的内容 如果您有任何想法或可以向我指出一个可以使用的可能解决方案 我将不胜感激 Thanks 你可以自己这样做 Use setInterval https deve
  • OpenGL 实现多通道

    我在移植一些已成功实现的代码时遇到问题着色玩具 https www shadertoy com view XdyfWK对于桌面 OpenGL 问题是我需要创建一个 FrameBufferObject FBO 以便我可以进行离屏计算 稍后将其