2017-04-22 84 views
0

我正在嘗試編寫一個需要迭代求解一些微分方程(Lattice-Boltzmann方法)的流體模擬器。我希望它是一個使用OpenGL的實時圖形可視化。我遇到了一個問題。我使用着色器在GPU上執行相關計算。我在t時刻將描述系統狀態的紋理傳遞給着色器,着色器執行計算並在時間t + dt返回系統的狀態,我在四邊形上渲染紋理,然後傳遞紋理回到着色器中。但是,我發現我無法同時讀取和寫入相同的紋理。但我相信我已經看到了GPU上這種計算的實現。他們如何解決它?我想我以一種不同的方式討論了OpenGL可以讀取和寫入相同紋理的事實,但我無法理解它們並將它們適用於我的案例。爲了渲染到紋理我用:glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);在OpenGL上爲迭代DE解算器編寫和讀取相同紋理

這裏是我的渲染程序:

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(); 



} 

現在發生了什麼,是當我渲染到幀緩衝,我紋理我得到的輸入是空的,我認爲。但是當我在屏幕上渲染相同的紋理時,它會成功呈現我所剔除的內容。

+1

通常在諸如蜂窩自動化等事情中,您使用兩個緩衝區 - 一個用於讀取,一個用於寫入和交換。他們在每一幀之後。這不適合你嗎? –

+0

@JanDvorak是的,我認爲這正是我正在尋找的。我只是對執行感到困惑。 –

回答

0

好吧,我想我已經設法弄清楚了一些事情。我可以做的是使用glCopyTexImage2D將屏幕上呈現的任何內容複製到紋理,而不是渲染到幀緩衝區。但是,現在我又遇到了另一個問題:我不明白glCopyTexImage2D是否可以與幀緩衝區配合使用。它適用於屏幕渲染,但是當我渲染幀緩衝時,我無法使其工作。不知道這是否甚至可能在第一位。對此做出了一個單獨的問題: Does glCopyTexImage2D work when rendering offscreen?