【问题标题】:OpenGL Frame Buffer Object for rendering to textures, renders weirdly用于渲染纹理的 OpenGL 帧缓冲区对象,渲染奇怪
【发布时间】:2010-01-04 23:21:29
【问题描述】:

我使用的是 python,但 OpenGL 的完成方式几乎与任何其他语言完全相同。

问题是当我尝试通过帧缓冲区对象将纹理或线条渲染到纹理时,它被颠倒渲染,左下角太小。很奇怪。我有这些图片要演示:

这就是它的样子,

www.godofgod.co.uk/my_files/Incorrect_operation.png

这就是我使用 pygame 时的样子。 Pygame太慢了,我学会了。如果没有 OpenGL 的速度,我的游戏将无法运行。忽略弯曲的角落。我还没有在 OpenGL 中实现这些。我需要先解决这个问题。

www.godofgod.co.uk/my_files/Correct_operation.png

我没有使用深度。

什么可能导致这种不稳定的行为。这是代码(函数在实际代码中缩进。它确实显示正确),你可能会觉得有用,

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.

这个功能也可能有用,

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()

【问题讨论】:

    标签: opengl object buffer textures frame


    【解决方案1】:

    你没有显示你的投影矩阵,所以我也假设它是身份。

    • OpenGL 帧缓冲区原点位于左下角,而不是左上角。
    • 尺寸问题更难解释。你的投影矩阵到底是什么?
    • 另外,您没有展示如何使用纹理,我不确定我们在您的“不正确”图像中看到了什么。

    一些不相关的cmets:

    • 为每帧创建一个帧缓冲区并不是正确的做法。
    • 想一想,为什么要使用帧缓冲?似乎您唯一要做的就是混合到帧缓冲区? glEnable(GL_BLEND) 可以做到这一点。

    【讨论】:

    • 感谢您的回答。我将更改 glTexCoord2f 参数以翻转纹理。我将按顺序回答您的问题,对于投影矩阵,我使用了 gluOrtho2D(0,1280,720,0)。我只需要一个简单的 2D 视图。纹理最终使用我展示的 draw_texture() 绘制到屏幕上。当我设置帧缓冲区时,我使用相同的函数来绘制纹理。对于问题,比较底部渐变和中间的菜单。图像是正确绘制的,因为它们是直接绘制到屏幕上的。 GL_BLEND 不是我需要的,我不认为。
    • GL_BLEND 仅用于 alpha 混合,对吗?我需要将纹理放入纹理中。您可能会建议我每帧绘制所有内容,但我发现这样做效率非常低,并且存在内存泄漏抖动问题。我将在创建帧缓冲区对象后保留它们,并且仅在删除 Surface 对象时销毁它们。这将是下一步。
    • 什么?没有告诉我我必须重置项目矩阵!!!我再次使用了 gluOrtho2D,它解决了问题!疯狂的。所有的痛苦和解决方案就是这么简单。你提到投影矩阵让我突然想到了这一点。非常感谢你。它还没有完全完成,但几乎完成了。
    • 投影矩阵保持上次设置的方式(就像 OpenGL 状态的每一位)。如果你必须重置它,这意味着某处改变了它。
    猜你喜欢
    • 2014-07-08
    • 2011-05-14
    • 1970-01-01
    • 2011-09-06
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多