OpenGL实施MultiPass [英] OpenGL Implementing MultiPass

查看:54
本文介绍了OpenGL实施MultiPass的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法将在 Shadertoy 中成功实现的某些代码移植到桌面OpenGL,问题是我需要创建一个FrameBufferObject FBO,以便可以进行屏幕外计算,然后再传递给主glsl片段着色器,问题是该缓冲区需要引用自身作为纹理,以获取先前的值.它可以进行仿真.

I am having trouble porting some code I have successfully implemented in Shadertoy to desktop OpenGL, the problem is that I need to create a FrameBufferObject FBO so that I can do offscreen computations that will be later passed on to the main glsl fragment shader, the thing is that this buffer needs to reference itself as a texture to get the previous values for it to be able to run a simulation.

我已经成功创建了FBO:

I have successfully created the 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,然后将这些值传递给默认帧缓冲区:

And managed to call it inside my Render Loop so that I can render to the FBO and later on pass those values to the Default Framebuffer:

// 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;

    }

但是我无法将缓冲区作为纹理呈现给自身,我知道它会输出未定义的行为,因此我应该使用像乒乓球这样的技术.

But I am not able to render the buffer to itself as a texture, I understand that it outputs undefined behaviour and that I should be using a technique as Ping-Pong.

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

Can somebody point me in the right direction?

推荐答案

但是我无法将缓冲区作为纹理呈现给自身,我知道它会输出未定义的行为,因此我应该使用像乒乓球这样的技术.

But I am not able to render the buffer to itself as a texture, I understand that it outputs undefined behaviour and that I should be using a technique as Ping-Pong.

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

Can somebody point me in the right direction?

您必须创建2个帧缓冲对象,就像您在问题中创建的那样:frameBufferOneframeBufferTwo.
这2个帧缓冲对象的每个对象都必须附加一个纹理对象:textureColourBufferOnetextureColourBufferTwo.

You have to create 2 framebuffer objects, as you did it with the one in your question: frameBufferOne and frameBufferTwo.
Each fo this 2 framebuffer objects has to have a texture object attached: textureColourBufferOne and textureColourBufferTwo.

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

In the main loop of your program you have to know if the number of the frame is even or odd.
If the number is even then you have to render to textureColourBufferOne and the input to the render pass is textureColourBufferTwo.
It the number is odd then you have to render to textureColourBufferTwo and the input to the render pass is textureColourBufferOne.
The result of the rendering is always stored int the texture which belongs to the framebuffer of the current frame:

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;

    .....
}

这篇关于OpenGL实施MultiPass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆