You have to create a Framebuffer Object (before the main loop) with a resoultion smaller than the window resolution. See also Framebuffer Object Extension Examples:
fb_size = [50, 50]
depth_buffer_obj = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer_obj)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fb_size[0], fb_size[1])
color_buffer_obj = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, color_buffer_obj)
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, fb_size[0], fb_size[1])
fb_obj = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, fb_obj)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer_obj)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer_obj)
status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
if status != GL_FRAMEBUFFER_COMPLETE:
print("incomplete framebuffer object")
glBindFramebuffer(GL_FRAMEBUFFER, 0)
Se the size of the viewport to the size of the framebuffer, clear the frame buffer and render the cube to the Framebuffer:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glBindFramebuffer(GL_FRAMEBUFFER, fb_obj)
glViewport (0, 0, fb_size[0], fb_size[1])
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotatef(1, 3, 1, 1)
Cube()
Set the viewport size to the size of the window and use glBlitFramebuffer
with the filter parameter GL_NEAREST
to copy the pixels from the named framebuffer object to the default framebuffer. Note it is not necessary to clear the default framebuffer, because it is completely overwritten:
while True:
# .....
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_obj)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
glViewport(0, 0, 500, 500)
glBlitFramebuffer(
0, 0, fb_size[0], fb_size[1],
0, 0, 500, 500,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST)
pygame.display.flip()
pygame.time.wait(10)
Note, the line glBindFramebuffer(GL_READ_FRAMEBUFFER, fb_obj)
is not necessary, because fb_obj
is bound for read and draw at this point.
If your system down't support glBlitFramebuffer
, the you can create a framebuffer with a texture attached to its color plane:
fb_size = [50, 50]
depth_buffer_obj = glGenRenderbuffers(1)
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer_obj)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fb_size[0], fb_size[1])
#color_buffer_obj = glGenRenderbuffers(1)
#glBindRenderbuffer(GL_RENDERBUFFER, color_buffer_obj)
#glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, fb_size[0], fb_size[1])
color_tex_obj = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, color_tex_obj)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fb_size[0], fb_size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
fb_obj = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, fb_obj)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer_obj)
#glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer_obj)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_tex_obj, 0)
status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
if status != GL_FRAMEBUFFER_COMPLETE:
print("incomplete framebuffer object")
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glBindTexture(GL_TEXTURE_2D, 0)
Render to the framebuffer and draw a quad with the the texture over the entire window to the default framebuffer:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glBindFramebuffer(GL_FRAMEBUFFER, fb_obj)
glViewport (0, 0, fb_size[0], fb_size[1])
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotatef(1, 3, 1, 1)
gluSphere(gluNewQuadric( ), 2.0, 32, 32)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glViewport(0, 0, 500, 500)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
#glBlitFramebuffer(
# 0, 0, fb_size[0], fb_size[1],
# 0, 0, 500, 500,
# GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
# GL_NEAREST)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, color_tex_obj)
glBegin(GL_TRIANGLE_FAN)
glTexCoord2f(0,0)
glVertex2f(-1,-1)
glTexCoord2f(1,0)
glVertex2f(1,-1)
glTexCoord2f(1,1)
glVertex2f(1,1)
glTexCoord2f(0,1)
glVertex2f(-1,1)
glEnd()
glDisable(GL_TEXTURE_2D)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
pygame.display.flip()
pygame.time.wait(10)