Search code examples
openglresolutionglfwframebufferglreadpixels

Can't glreadPixels more than 3844x1065


I am trying to render to an off-screen FBO a scene I made, and if I set width/height above 3844/1065, my final image gets limited to that resolution. I am using two monitors. The following image was rendered using 4500x2160 resolution. The "active" area is 3844x1065.

enter image description here

Here is some code:

        windowWidth = 4500 
        windowHeight = 2160
        mainWindow = glfw.create_window(windowWidth, windowHeight, windowTitle, None, None)
        glfw.set_window_pos(mainWindow, 10, 10)
        glfw.make_context_current(mainWindow)
        glfw.set_window_size_callback(mainWindow, window_resize)
        frameBuffer = glGenFramebuffers(1)
        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer)
        renderBuffer = glGenRenderbuffers(1)
        glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer)
        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, windowWidth, windowHeight)
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer)

        glDrawBuffer(GL_COLOR_ATTACHMENT0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # draw all the stuff
        glReadBuffer(GL_COLOR_ATTACHMENT0)
        img_buf = glReadPixels(0, 0, windowWidth, windowHeight, GL_RGB, GL_UNSIGNED_BYTE)
        image = Image.frombytes(mode="RGB", size=(windowWidth, windowHeight), data=img_buf)
        image = image.transpose(Image.FLIP_TOP_BOTTOM)
        image.save('example.png')
        glfw.set_window_should_close(mainWindow, True)


        def window_resize(window, width, height):
            glViewport(0, 0, width, height)

FOUND a hint:

If I do :

     w,h = glfw.get_window_size(self.mainWindow)
     print(w)
     print(h)

I get: 3844 1065

Therefore GLFW limits my window size, and drawing buffer is using that size only.

How can I set output for drawing to FBO of my selected size ? (ex 5000x3000).

The parameters of size of set_window_size_callback in the call of window_resize are the ones from _GLFWwindowsizefun, which are 3844x1065


Solution

  • The viewport size always has to be the size of the rendertarget. This is not necessarily the size of the window.

    Before rendering to the renderbuffer, you have to set the viewport to the renderbuffer size:

    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer)
    glViewport(windowWidth, windowHeight); //Not the size of the window but of the renderbuffer
    
    glDrawBuffer(GL_COLOR_ATTACHMENT0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    
    # draw all the stuff
    

    When you render to the FBO as well as to the window, then you have to adjust the viewport settings whenever you change the render target:

    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer)
    glViewport(fboWidth, fboHeight);
    
    # Render to FBO
    
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glViewport(windowWidth, windowHeight);
    
    # Render to Window