PDA

View Full Version : Frame buffer object renders wrong to texture



Matthew4693434
01-03-2010, 01:52 PM
My last topic didn't go down too well so I'm going to start a new one. It makes sense because my code has changed a lot since last time. I seem to have made some progress with other parts of my game but the texture to texture rendering is still problematic.

I'm using python but OpenGL is pretty much done exactly the same way as in any other language.

The problem is that when I try to render a texture or a line to a texture by means of a frame buffer object, it is rendered upside down, too small in the bottom left corner. Very weird. A picture would best demonstrate the problem. I'll upload one shortly.

The code is as follows with some comments to help along the way,


def texture_to_texture(target,surface,offset): #Target is an object of a class which contains texture data. This texture should be the target. Surface is the same but is the texture which should be drawn onto the target. offset is the offset where the surface texture will be drawn on the target texture.
#This will create the textures if not already. It will create textures from image data or block colour. Seems to work fine as direct rendering of textures to the screen works brilliantly.
if target.texture == None:
create_texture(target)
if surface.texture == None:
create_texture(surface)
frame_buffer = glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, target.texture, 0) #target.texture is the texture id from the object
glPushAttrib(GL_VIEWPORT_BIT)
glViewport(0,0,target.surface_size[0],target.surface_size[1])
draw_texture(surface.texture,offset,surface.surfac e_size,[float(c)/255.0 for c in surface.colour]) #The last part changes the 0-255 colours to 0-1 The textures when drawn appear to have the correct colour. Don't worry about that.
glPopAttrib()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
glDeleteFramebuffersEXT(1, [int(frame_buffer)]) #Requires the sequence of the integer conversion of the ctype variable, meaning [int(frame_buffer)] is the odd required way to pass the frame buffer id to the function.


What could be causing this erratic behaviour?

Thank you for any help.

This is how it looks,

www.godofgod.co.uk/my_files/Incorrect_operation.png (http://www.godofgod.co.uk/my_files/Incorrect_operation.png)

This is how it did look when I was using pygame instead. Pygame is too slow, I've learnt. My game would be unplayable without OpenGL's speed. Ignore the curved corners. I haven't implemented those in OpenGL yet. I need to solve this issue first.

www.godofgod.co.uk/my_files/Correct_operation.png (http://www.godofgod.co.uk/my_files/Correct_operation.png)

Oh, and this is the draw_texture function which works fine when done for the screen,

def draw_texture(texture,offset,size,c):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() #Loads model matrix
glColor4fv(c)
glBegin(GL_QUADS)
glVertex2i(*offset) #Top Left
glVertex2i(offset[0],offset[1] + size[1]) #Bottom Left
glVertex2i(offset[0] + size[0],offset[1] + size[1]) #Bottom, Right
glVertex2i(offset[0] + size[0],offset[1]) #Top, Right
glEnd()
glColor4fv((1,1,1,1))
glBindTexture(GL_TEXTURE_2D, texture)
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2i(*offset) #Top Left
glTexCoord2f(0.0, 1.0)
glVertex2i(offset[0],offset[1] + size[1]) #Bottom Left
glTexCoord2f(1.0, 1.0)
glVertex2i(offset[0] + size[0],offset[1] + size[1]) #Bottom, Right
glTexCoord2f(1.0, 0.0)
glVertex2i(offset[0] + size[0],offset[1]) #Top, Right
glEnd()

It might help to know that I'm not using depth.

Matthew4693434
01-04-2010, 11:37 AM
What if I used some other method? But what can I do?

Matthew4693434
01-06-2010, 04:58 AM
I have more problems but the first problem has been solved. The problem was that I didn't know I needed to reset the project matrix. Nothing told me to do that. I'm very annoyed about that. This is the texture_to_texture function at the moment,


def texture_to_texture(target,surface,offset):
#Create textures if not done already
if target.texture == None:
create_texture(target)
if surface.texture == None:
create_texture(surface)
#Render child to parent
if target.frame_buffer == None:
target.frame_buffer = glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, target.frame_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, target.texture, 0)
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
glPushAttrib(GL_VIEWPORT_BIT)
glEnable(GL_LINE_SMOOTH,GL_FASTEST) #Create antialiased lines
glEnable(GL_BLEND) #Enable alpha blending
glEnable(GL_TEXTURE_2D) #Enable 2D Textures
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) #The recomended blending functions.
glViewport(0,0,target.surface_size[0],target.surface_size[1])
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(target.surface_size[0],0,0,target.surface_size[1])
draw_texture(surface.texture,offset,surface.surfac e_size,[float(c)/255.0 for c in surface.colour])
glPopAttrib()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

You can see I use gluOrtho2D now.

But lines still fail,


def add_line(surface,c,a,b,w = 1):
c = [float(sc)/255 for sc in c] #Divide colours by 255 because OpenGL uses 0-1
if len(c) != 4:
c.append(1) #Add a value for aplha transparency if needed
#Create texture if not done already
if surface.texture == None:
create_texture(surface)
#Render child to parent
if surface.frame_buffer == None:
surface.frame_buffer = glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface.frame_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)
glPushAttrib(GL_VIEWPORT_BIT)
glViewport(0,0,surface.surface_size[0],surface.surface_size[1])
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(surface.surface_size[0],0,0,surface.surface_size[1])
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() #Loads model matrix
glColor4fv(c)
glLineWidth(w)
glBegin(GL_LINES)
glVertex2iv(a)
glVertex2iv(b)
glEnd()
glPopAttrib()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

What is supposed to be a gradient is showing as grey with little stripes in it. Nothing normal at all.