-
Notifications
You must be signed in to change notification settings - Fork 2
/
TextureImage.py
92 lines (77 loc) · 3.23 KB
/
TextureImage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from PIL import Image
from OpenGL.GL import *
from cStringIO import StringIO
import numpy
useMipmapping = False
class TextureImage:
""" A basic 2-d OpenGL texture image, as loaded from (for instance) a png file. """
def __init__(self, filename = None, data = None, flat = None):
self.filename = filename
self.data = data
self.texobj = None
self.flat = flat
def __read(self):
if self.data:
return Image.open(StringIO(self.data))
if self.filename:
return Image.open(self.filename)
if self.flat:
return Image.new(*self.flat)
assert False
def initGL(self):
img = self.__read()
if img.mode not in ['RGB', 'L', 'I']:
img = img.convert('RGB')
max_texture_size = glGetIntegerv(GL_MAX_TEXTURE_SIZE);
if img.size[0] > max_texture_size or img.size[1] > max_texture_size:
new_size = (min(max_texture_size, img.size[0]),
min(max_texture_size, img.size[1]))
print "Resizing image from %s to %s due to OpenGL limits" % (img.size, new_size)
img = img.resize(new_size, Image.BILINEAR)
self.texobj = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glBindTexture(GL_TEXTURE_2D, self.texobj)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
if useMipmapping:
# Enable mipmapping (i.e. trilinear filtering) to soften
# out the subsampling artifacts.
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
else:
# Just use bilinear filtering.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
if img.mode == 'I':
# PIL mode 'I': integer 32-bit pixels. This is how PIL
# loads 16-bit image files.
img_data = numpy.fromstring(img.tobytes(), dtype = 'uint32')
num_pixels = img.size[0] * img.size[1]
type = GL_UNSIGNED_SHORT
if len(img_data) == num_pixels:
# Must be grayscale.
format = GL_LUMINANCE
elif len(img_data) == num_pixels * 3:
# Must be RGB.
format = GL_RGB
elif len(img_data) == num_pixels * 4:
# Must be RGBA.
format = GL_RGBA
else:
# What could it be?
assert False
else:
# Otherwise, it's an 8-bit format.
type = GL_UNSIGNED_BYTE
if img.mode == 'RGB':
format = GL_RGB
elif img.mode == 'L':
format = GL_LUMINANCE
else:
assert False
img_data = numpy.fromstring(img.tobytes(), dtype = 'uint8')
glTexImage2D(GL_TEXTURE_2D, 0, format, img.size[0], img.size[1], 0, format, type, img_data)
def apply(self):
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.texobj)
glEnable(GL_TEXTURE_2D)