【问题标题】:OpenGL doesn't draw anything if I use PIL (or PyPNG) to load textures如果我使用 PIL(或 PyPNG)加载纹理,OpenGL 不会绘制任何东西
【发布时间】:2022-12-24 14:09:54
【问题描述】:

我有一个使用 OpenGL 绘制立方体的程序,我想为立方体添加纹理。我正在关注 this 教程,我的纹理加载代码几乎是从那里复制的。每当我调用 load_texture() 时,此后的任何 OpenGL 调用似乎都会失败,并且不会抛出任何错误。是否有任何已知问题会导致 Pillow 和 OpenGL 在协同工作时表现异常?我能找到的大多数教程都使用 Pillow,所以我认为必须有一个解决方法。

这是我的纹理加载代码:

from OpenGL.GL import *
import gl_debugging as debug
from PIL import Image

# loads a texture from an image file into VRAM
def load_texture(texture_path):
        # open the image file and convert to necessary formats
        print("loading image", texture_path)
        image = Image.open(texture_path)
        convert = image.convert("RGBA")
        image_data = image.transpose(Image.FLIP_TOP_BOTTOM ).tobytes()
        w = image.width
        h = image.height
        image.close()

        # create the texture in VRAM
        texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, texture)

        # configure some texture settings
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) # when you try to reference points beyond the edge of the texture, how should it behave?
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) # in this case, repeat the texture data
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) # when you zoom in, how should the new pixels be calculated?
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) # when you zoom out, how should the existing pixels be combined?
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

        # load texture onto the GPU
        glTexImage2D(
                GL_TEXTURE_2D,    # where to load texture data
                0,                # mipmap level
                GL_RGBA8,         # format to store data in
                w,                # image dimensions
                h,                #
                0,                # border thickness
                GL_RGBA,          # format data is provided in
                GL_UNSIGNED_BYTE, # type to read data as
                image_data)       # data to load as texture
        debug.check_gl_error()

        # generate smaller versions of the texture to save time when its zoomed out
        glGenerateMipmap(GL_TEXTURE_2D)

        # clean up afterwards
        glBindTexture(GL_TEXTURE_2D, 0)

        return texture

【问题讨论】:

  • 代码究竟是如何工作的没有加载图像?在那种情况下,你使用什么纹理?
  • 您使用的是教程 02 脚本的副本吗?或者也许您确实对其进行了一些修改?只是问一下,因为如果您忘记添加一两条指令,很容易搞砸 OpenGL 渲染。
  • 顺便说一句,convert = image.convert("RGBA") 不会导致 image 发生变化(这就是为什么有返回值),之后您的代码中似乎没有任何内容使用 convert
  • @KarlKnechtel,我认为这就是问题所在。在存储库的纹理加载器上,这条指令是这样写的:glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE, self.buffer)。看见?它加载 RGB,而不是 RGBA 文件。所以脚本的作者确实使用了转换,但由于他没有使用新图像,它可能作为 RGB 加载以跳过错误。
  • 不过,这似乎应该只是导致纹理被破坏(并且可能部分地从不相关的内存中获取),而不是因为 OpenGL 调用失败。

标签: python python-3.x opengl python-imaging-library textures


【解决方案1】:

代码只有一个问题。您需要从转换后的图像 (convert) 而不是加载的图像 (image) 中获取字节:

from PIL.Image import Transpose

image = Image.open(texture_path)
convert = image.convert("RGBA")

image_data = image.transpose(Image.FLIP_TOP_BOTTOM).tobytes()

image_data = convert.transpose(Transpose.FLIP_TOP_BOTTOM).tobytes()

更改代码后工作正常,我测试了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多