C++ 在OpenGL上为迭代解算器从同一纹理进行写入和读取

C++ 在OpenGL上为迭代解算器从同一纹理进行写入和读取,c++,opengl,C++,Opengl,我正试图编写一个流体模拟器,需要迭代求解一些微分方程(晶格玻尔兹曼方法)。我希望它是一个使用OpenGL的实时图形可视化。我遇到了一个问题。我使用着色器在GPU上执行相关计算。我要做的是将描述时间t时系统状态的纹理传递到着色器中,着色器执行计算并返回时间t+dt时系统的状态,我在四边形上渲染纹理,然后将纹理传递回着色器中。然而,我发现我不能同时读写同一个纹理。但我确信我已经在GPU上看到了这种计算的实现。他们是如何解决这个问题的?我想我看到了一些关于OpenGL可以读取和写入相同纹理这一事实的不

我正试图编写一个流体模拟器,需要迭代求解一些微分方程(晶格玻尔兹曼方法)。我希望它是一个使用OpenGL的实时图形可视化。我遇到了一个问题。我使用着色器在GPU上执行相关计算。我要做的是将描述时间t时系统状态的纹理传递到着色器中,着色器执行计算并返回时间t+dt时系统的状态,我在四边形上渲染纹理,然后将纹理传递回着色器中。然而,我发现我不能同时读写同一个纹理。但我确信我已经在GPU上看到了这种计算的实现。他们是如何解决这个问题的?我想我看到了一些关于OpenGL可以读取和写入相同纹理这一事实的不同工作方式的讨论,但我不能完全理解它们并使它们适应我的情况。要渲染到纹理,我使用:
glFramebufferTexture(GL\u FRAMEBUFFER,GL\u COLOR\u ATTACHMENT0,renderedTexture,0)

以下是我的渲染例程:

do{


    //count frames
    frame_counter++;


    // Render to our framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
    glViewport(0,0,windowWidth,windowHeight); // Render on the whole framebuffer, complete from the lower left corner to the upper right

    // Clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Use our shader
    glUseProgram(programID);
    // Bind our texture in Texture Unit 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, renderTexture);


    glUniform1i(TextureID, 0);

    printf("Inv Width: %f", (float)1.0/windowWidth);
    //Pass inverse widths (put outside of the cycle in future)
    glUniform1f(invWidthID, (float)1.0/windowWidth);
    glUniform1f(invHeightID, (float)1.0/windowHeight);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
    glVertexAttribPointer(
                          0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                          3,                  // size
                          GL_FLOAT,           // type
                          GL_FALSE,           // normalized?
                          0,                  // stride
                          (void*)0            // array buffer offset
                          );

    // Draw the triangles !
    glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles

    glDisableVertexAttribArray(0);
    // Render to the screen
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    // Render on the whole framebuffer, complete from the lower left corner to the upper right
    glViewport(0,0,windowWidth,windowHeight);

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Use our shader
    glUseProgram(quad_programID);

    // Bind our texture in Texture Unit 0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, renderedTexture);
    // Set our "renderedTexture" sampler to user Texture Unit 0
    glUniform1i(texID, 0);

    glUniform1f(timeID, (float)(glfwGetTime()*10.0f) );

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
    glVertexAttribPointer(
                          0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                          3,                  // size
                          GL_FLOAT,           // type
                          GL_FALSE,           // normalized?
                          0,                  // stride
                          (void*)0            // array buffer offset
                          );

    // Draw the triangles !
    glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles

    glDisableVertexAttribArray(0);

    glReadBuffer(GL_BACK);
    glBindTexture(GL_TEXTURE_2D, sourceTexture);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, windowWidth, windowHeight, 0);


    // Swap buffers
    glfwSwapBuffers(window);
    glfwPollEvents();



}

现在发生的事情是,当我渲染到帧缓冲区时,我认为作为输入的纹理是空的。但是,当我在屏幕上渲染相同的纹理时,它成功地渲染了我所期望的内容。

好的,我想我已经设法找到了答案。我能做的不是渲染到帧缓冲区,而是使用
glCopyTexImage2D
将屏幕上渲染的内容复制到纹理。然而,现在我有另一个问题:我不明白
glCopyTexImage2D
是否可以与帧缓冲区一起工作。它可以在屏幕上进行渲染,但在渲染到帧缓冲区时无法使其正常工作。我不确定这在一开始是否可行。就这一点提出了单独的问题:

通常在诸如蜂窝自动化之类的应用中,您使用两个缓冲区(一个用于读取,一个用于写入)和交换。在每一帧之后都会显示它们。这不是你的选择吗?@JanDvorak是的,我想这正是我想要的。我只是对实施感到困惑。