-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtexture.py
More file actions
142 lines (114 loc) · 5.18 KB
/
texture.py
File metadata and controls
142 lines (114 loc) · 5.18 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import OpenGL.GL as gl
from PIL import Image
import numpy as np
def make_texture(data):
"""
Create an OpenGL texture from a numpy array.
:param data: Numpy array containing image data.
:return: OpenGL texture ID.
"""
height, width = data.shape[:2]
texture_id = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)
# Set texture parameters
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
# Determine the format based on the shape of the data
if data.ndim == 2:
format = gl.GL_RED
elif data.shape[2] == 3:
format = gl.GL_RGB
elif data.shape[2] == 4:
format = gl.GL_RGBA
else:
raise ValueError("Unsupported number of channels in image data")
# Specify the 2D texture
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1);
gl.glTexImage2D(
gl.GL_TEXTURE_2D, # Target
0, # Mipmap level
format, # Internal format
width, # Image width
height, # Image height
0, # Border (must be 0)
format, # Format of the pixel data
gl.GL_UNSIGNED_BYTE, # Data type of the pixel data
data # Actual image data
)
# Generate mipmaps (optional, for smoother scaling)
# gl.glGenerateMipmap(gl.GL_TEXTURE_2D)
# Unbind the texture
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
return texture_id,width,height
def load_texture(image_path):
"""
Load a JPEG image and set it as a texture in PyOpenGL.
:param image_path: Path to the JPEG image file.
:return: OpenGL texture ID.
"""
# Load the image using Pillow (PIL)
image = Image.open(image_path)
image = image.transpose(Image.FLIP_TOP_BOTTOM) # Flip the image vertically for OpenGL
if image.mode == "I;16":
# Normalize 16-bit grayscale to 8-bit
arr = np.array(image, dtype=np.uint16)
arr = (arr / 256.0).astype(np.uint8) # scale 0-65535 to 0-255
image_rgb = Image.fromarray(arr, mode="L").convert("RGBA")
else:
image_rgb = image.convert("RGBA")
image_data = image_rgb.tobytes() # Convert to bytes for OpenGL
texture_id = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)
# Set texture parameters
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
# Specify the 2D texture
gl.glTexImage2D(
gl.GL_TEXTURE_2D, # Target
0, # Mipmap level
gl.GL_RGBA, # Internal format
image.width, # Image width
image.height, # Image height
0, # Border (must be 0)
gl.GL_RGBA, # Format of the pixel data
gl.GL_UNSIGNED_BYTE, # Data type of the pixel data
image_data # Actual image data
)
# Generate mipmaps (optional, for smoother scaling)
gl.glGenerateMipmap(gl.GL_TEXTURE_2D)
# Unbind the texture
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
del image_data
return texture_id, image.width, image.height
def create_texture(w, h, type = "uint8"):
# Generate texture ID
texture_id = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)
if(type == "rgba32f"):
# Create a black pixel buffer (RGBA format)
black_data = np.zeros((h, w, 4), dtype=np.float32)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, w, h, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, black_data)
elif (type == "int32"):
# Create a black pixel buffer (RGBA format)
result = gl.glGetInternalformativ(gl.GL_TEXTURE_2D, gl.GL_R32UI, gl.GL_INTERNALFORMAT_SUPPORTED, 1)
print(result == True)
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4)
black_data = np.zeros((h, w), dtype=np.uint32)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_R32UI, w, h, 0, gl.GL_RED_INTEGER , gl.GL_UNSIGNED_INT, black_data)
else:
# Create a black pixel buffer (RGBA format)
black_data = np.zeros((h, w, 4), dtype=np.uint8) # Shape: (height, width, 4)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA8, w, h, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, black_data)
# Allocate and upload the texture
# Set texture parameters
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)
# Unbind the texture
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
return texture_id # Return texture handle