I am trying to draw a 2d image in OpenGL using pillow to load the image, but when I render it in OpenGL, the image is skewed.
This is the original image:
Loading.png
This is the code:
JavaScript
x
82
82
1
# -*- coding: utf-8 -*-
2
import glfw
3
from OpenGL.GL import *
4
if not glfw.init():
5
sys.exit()
6
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 1)
7
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 4)
8
window = glfw.create_window(800, 600, "Hello World", None, None)
9
if not window:
10
sys.exit()
11
glfw.make_context_current(window)
12
glEnable(GL_BLEND)
13
glClearColor(1.0/255.0*68.0, 1.0/255.0*68.0, 1.0/255.0*68.0, 1.0)
14
glClear(GL_COLOR_BUFFER_BIT)
15
glViewport(0, 0, 800, 600)
16
glMatrixMode(GL_PROJECTION)
17
glLoadIdentity()
18
glOrtho(0.0, 800.0, 600.0, 0.0, 0.0, 1.0)
19
20
import numpy
21
from PIL import Image # pillow
22
def ReadTexture( filename):
23
# PIL can open BMP, EPS, FIG, IM, JPEG, MSP, PCX, PNG, PPM
24
# and other file types. We convert into a texture using GL.
25
print('trying to open', filename)
26
try:
27
image = Image.open(filename)
28
except IOError as ex:
29
print('IOError: failed to open texture file')
30
message = template.format(type(ex).__name__, ex.args)
31
print(message)
32
return -1
33
print('opened file: size=', image.size, 'format=', image.format)
34
imageData = numpy.array(list(image.getdata()), numpy.uint8)
35
36
textureID = glGenTextures(1)
37
glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
38
glBindTexture(GL_TEXTURE_2D, textureID)
39
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
40
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
41
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
42
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
43
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)
44
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
45
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.size[0], image.size[1],
46
0, GL_RGB, GL_UNSIGNED_BYTE, imageData)
47
48
image.close()
49
return textureID
50
51
import sys
52
def get_user_input(str):
53
if sys.version_info[0] < 3:
54
return raw_input(str)
55
else:
56
return input(str)
57
print("started")
58
59
texture_id = ReadTexture("loading.png")
60
while True:
61
glfw.poll_events()
62
glClear(GL_COLOR_BUFFER_BIT)
63
glEnable(GL_TEXTURE_2D)
64
glBindTexture(GL_TEXTURE_2D, texture_id)
65
glBegin(GL_QUADS)
66
glTexCoord2f(0, 0)
67
glVertex2f(0,0)
68
glTexCoord2f(0, 1)
69
glVertex2f(0,100)
70
glTexCoord2f(1, 1)
71
glVertex2f(100,100)
72
glTexCoord2f(1, 0)
73
glVertex2f(100,0)
74
glEnd()
75
glDisable(GL_TEXTURE_2D)
76
glfw.swap_buffers(window)
77
78
glfw.destroy_window(window)
79
glfw.terminate()
80
81
get_user_input("PRESS ENTER")
82
Result
As you can see, the result is a skewed image, I don’t know why this is happening, and I can’t see the problem with the code.
edit: can confirm same problem in python 2.7 and 3.8
Advertisement
Answer
When the image is loaded to a texture object, then GL_UNPACK_ALIGNMENT
has to be set to 1:
JavaScript
1
4
1
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
2
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.size[0], image.size[1],
3
0, GL_RGB, GL_UNSIGNED_BYTE, imageData)
4
Note, in your case the alignment is set to 4 (what is defualt). This means that each line of the image is assumed to be aligned to a size which is a multiple of 4. Since the image data are tightly packed and each pixel has a size of 3 bytes (GL_RGB
), the alignment has to be changed.