I'm writing an application using PyOpengl and PySide. My main machine is installed with ubuntu and an nvidia card (proprietary drivers), the premise is just to tell that the application is working properly in this setting.
I'm testing this application on a machine with an intel hd 3000 and Ubuntu 12.10, the drivers are the default intel drivers. Everything is working so far except for the application of multiple post-processing filters.
The process works like that:
render the scene and output a color texture (texture0) using a framebuffer object (called fb0).
render the first postprocessing effect by binding the textures produced in the previous step. The processed color output is saved in another texture (extratexture1) by using another framebuffer (fb1).
render another postprocessing effect by using the new color texture (extratexture2 and fb2).
render the result on the screen.
What I obtain is a white screen (my background color perhaps).
If I remove the last step and render the extratexture1, I obtain the correct result. If I remove the second step only and render the extratexture2 I obtain the correct result. Therefore the problem should not be in the texture initialization code.
It's like that this driver doesn't support more than 2 framebuffers (+ default one) at a time. Or probably failing to reset some important state.
Was anybody able to code a similar thing on an intel video card? I'm running out of ideas of what the problem can be.
I add some example code to troubleshoot any error:
Initialization of framebuffers and textures, at initialization time. The texture are regenerated at each resize.
self.fb0, self.fb2, self.fb1 = glGenFramebuffers(3)
# Creation of texture0
glDrawBuffers(1, np.array([GL_COLOR_ATTACHMENT0], dtype='uint32'))
# Creation of extratexture1
# Creation of extratexture2
Creation of each texture:
def create_color_texture(fb, width, height):
# Simple wrapper for glGenTexture and glTexImage2D
texture = Texture(GL_TEXTURE_2D, width, height, GL_RGB, GL_RGB,
GL_UNSIGNED_BYTE)
# Set some parameters
texture.set_parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST)
texture.set_parameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glBindFramebuffer(GL_FRAMEBUFFER, fb)
glViewport(0, 0, width, height)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
texture.id, 0)
return texture
Code that draws the texture to screen:
def render(self, fb, textures):
# We need to render to a quad
glBindFramebuffer(GL_FRAMEBUFFER, fb)
glViewport(0, 0, self.widget.width(), self.widget.height())
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(self.quad_program)
qd_id = glGetUniformLocation(self.quad_program, "rendered_texture")
# Setting up the texture
glActiveTexture(GL_TEXTURE0)
textures['color'].bind()
# Set our "rendered_texture" sampler to user Texture Unit 0
glUniform1i(qd_id, 0)
# Set resolution
glUniform2f(glGetUniformLocation(self.quad_program, 'resolution'), self.widget.width(), self.widget.height())
# Set gamma value
glUniform1f(glGetUniformLocation(self.quad_program, 'gamma'), self.gamma)
# Let's render a quad
quad_data = np.array([-1.0, -1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
1.0, 1.0, 0.0],
dtype='float32')
vboquad = vbo.VBO(quad_data)
vboquad.bind()
glVertexPointer(3, GL_FLOAT, 0, None)
glEnableClientState(GL_VERTEX_ARRAY)
# draw "count" points from the VBO
glDrawArrays(GL_TRIANGLES, 0, 6)
vboquad.unbind()
glDisableClientState(GL_VERTEX_ARRAY)