views:

617

answers:

1

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. I have these pictures to demonstrate:

This is how it looks,

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

I'm not using depth.

What could cause this erratic behaviour. Here's the code (The functions are indented in the actual code. It does show right), you may find useful,

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.surface_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.

This function may also be useful,

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()
+1  A: 

You don't show your projection matrix, so I'll assume it's identity too.

  • OpenGL framebuffer origin is bottom left, not top left.
  • The size issue is more difficult to explain. What is your projection matrix after all ?
  • also, you don't show how to use the texture, and I'm not sure what we're looking at in your "incorrect" image.

Some non-related comments:

  • creating a framebuffer each frame is not the right way to go about it.
  • come to think about it, why use framebuffer at all ? it seems that the only thing you're after is blending to the frame buffer ? glEnable(GL_BLEND) does that just fine.
Bahbar
Thank you for the answer. I will change the glTexCoord2f arguments to flip the textures. I'll answer your questions in order,For the projection matrix I've used gluOrtho2D(0,1280,720,0). I only need a simple 2D view.The textures are ultimately drawn to the screen with draw_texture(), which I showed. I use the same function for drawing textures when I have set up the frame buffer. For the problem, compare the bottom gradient and the menu in the middle. The images are drawn correctly because they are drawn directly to the screen.GL_BLEND isn't what I need, I do not think.
Matthew Mitchell
GL_BLEND is just for alpha blending, right? I need to put textures inside textures. You might recommend I draw everything per frame but I've discovered that to be terribly inefficient and ridden with memory leak thrashing issues.I will keep the frame buffer objects after I've created them and only destroy them when I delete the Surface objects. THat was going to be the next step.
Matthew Mitchell
WHAT? Nothing told me I had to reset the project matrix!!! I've used gluOrtho2D again and it's fixed the problem!Crazy. All that pain and the solution was that simple.Your mention of projection matrix made me suddenly think about that. Thank you very much. It's not completely done but almost there.
Matthew Mitchell
The projection matrix keeps the way it was last set (like every bit of OpenGL state). If you have to reset it, it means something changed it somewhere.
Bahbar