'OpenGL doesn't draw anything if I use PIL (or PyPNG) to load textures
I have a program that uses OpenGL to draw a cube, and I wanted to add textures to the cube. I'm following this tutorial, and my texture loading code is pretty much copied from there. Whenever I call load_texture()
, any OpenGL calls after that seem to fail without any errors being thrown. Are there any known issues that could cause Pillow and OpenGL to behave oddly when working together? Most tutorials I could find use Pillow, so I think there has to be a workaround.
Here is my texture loading code:
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
Solution 1:[1]
There is just one problem with the code. You need to get the bytes from the converted image (convert
) and not the loaded image (image
):
image = Image.open(texture_path)
convert = image.convert("RGBA")
image_data = image.transpose(Image.FLIP_TOP_BOTTOM).tobytes()
image_data = convert.transpose(Image.FLIP_TOP_BOTTOM).tobytes()
After that change the code works fine, I tested it.
Solution 2:[2]
At the moment, there are no such tools for optimizing strategies in Pine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Rabbid76 |
Solution 2 | vgladkov |