Рендеринг на экран и в FBO дает разные результаты

Я написал программу для рендеринга квадрата с текстурой на экран и в FBO. Я считаю, что результат рендеринга должен быть одинаковым для обоих случаев, отличается только назначение вывода. Удивительно, но это дает мне совершенно другой результат.

Для первого изображения я напрямую вывожу его на экран. Это хорошо, без проблем. Для второго изображения я визуализировал его в FBO с текстурой, а затем визуализировал эту текстуру на экране. В этом случае вывод полностью испорчен, кажется, что вывод содержит только верхний левый угол изображения.

Первое изображение. Прямое отображение на экране

Второе изображение. Рендеринг в текстуру и визуализация этой текстуры на экране

Связанный код:

def render(self):
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._fbids[1])
    gl.glBindTexture(gl.GL_TEXTURE_2D, self._texids[0])
    gl.glUseProgram(0)
    self.drawQuad2()

    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
    gl.glBindTexture(gl.GL_TEXTURE_2D, self._texids[1]) # This is for second, messed up output.
    # gl.glBindTexture(gl.GL_TEXTURE_2D, self._texids[0])   # This is for first, normal output.
    gl.glUseProgram(0)
    self.drawQuad2()

def drawQuad2(self):
    gl.glBegin(gl.GL_QUADS)

    gl.glTexCoord2f(0, 1)
    gl.glVertex2f(-1, 1)
    gl.glTexCoord2f(1, 1)
    gl.glVertex2f(1, 1)
    gl.glTexCoord2f(1, 0)
    gl.glVertex2f(1, -1)
    gl.glTexCoord2f(0, 0)
    gl.glVertex2f(-1, -1)

    gl.glEnd()
    gl.glFlush()

def setupTexture(self, num, rawstr, width, height):
    texids = gl.glGenTextures(num)
    for tid in texids:
        print 'texture binded %s' % tid
        gl.glBindTexture(gl.GL_TEXTURE_2D, tid)
        gl.glTexImage2D(
            gl.GL_TEXTURE_2D,
            0, gl.GL_RGBA, width, height,
            0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE,
            rawstr)
        gl.glTexParameteri(
            gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
        gl.glTexParameteri(
            gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
    gl.glEnable(gl.GL_TEXTURE_2D);

    return texids

def setupFramebuffer(self, num, texids):
    assert(len(texids) == num)
    fbids = gl.glGenFramebuffers(num)
    for i in range(len(fbids)):
        print 'framebuffer binded %s with texture %s' % (fbids[i], texids[i])
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, fbids[i])
        gl.glFramebufferTexture2D(
            gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
            gl.GL_TEXTURE_2D, texids[i], 0)
    return fbids

def reshape(self, w, h):
    if not h:
        return
    print 'reshape. w:%s, h:%s' % (w, h)

    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()

    gl.glViewport(0, 0, w, h)
    gl.glOrtho(-1, 1, -1, 1, -1, 1)

    gl.glMatrixMode(gl.GL_MODELVIEW)
    gl.glLoadIdentity()

person Lingfeng Xiong    schedule 22.06.2014    source источник


Ответы (1)


Вы должны использовать функцию glViewport, чтобы сообщить OpenGL размер целевого окна, к которому он будет обращаться при своих операциях рисования. Поэтому, когда вы переключаетесь на рендеринг в FBO, вы должны вызывать glViewport с чем-то, что имеет смысл для целевой текстуры; обычно сама целевая текстура. При переключении на рендеринг в окно вы вызываете glViewport с целевым размером окна.

Если целевое окно просмотра больше, чем целевой буфер кадра, это фактически приводит к увеличению масштаба.

person datenwolf    schedule 22.06.2014