我正在编写一个简单的应用程序,它加载图像并将其显示在屏幕上,以便分别呈现左半部分和右半部分。
import glm
import moderngl_window
import numpy as np
from PIL import Image
class BugExample(moderngl_window.WindowConfig):
LEFT_TEXTURE_IDX = 0
RIGHT_TEXTURE_IDX = 1
def __init__(self, **kwargs):
super().__init__(**kwargs)
image = Image.open("test.jpg").transpose(Image.FLIP_TOP_BOTTOM)
w, h = image.size
w_even = 2 * (w // 2)
left = image.crop((0, 0, w_even // 2, h))
right = image.crop((w_even // 2, 0, w_even, h))
self.texture_left = self.ctx.texture(left.size, 3, left.tobytes())
self.texture_left.use(self.LEFT_TEXTURE_IDX)
self.texture_right = self.ctx.texture(right.size, 3, right.tobytes())
self.texture_right.use(self.RIGHT_TEXTURE_IDX)
self.program = self.ctx.program(
vertex_shader="""
#version 330
in vec2 in_position;
uniform mat4 model;
out vec2 uv0;
void main() {
gl_Position = model * vec4(in_position, 0.0, 1.0);
uv0 = (0.5 * in_position) + vec2(0.5);
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
uniform sampler2D texture_idx;
in vec2 uv0;
void main() {
fragColor = texture(texture_idx, uv0);
}
""")
self.left_scale_mat = glm.scale(glm.mat4(), glm.vec3(0.5, 1.0, 1.0))
self.left_translate_mat = glm.translate(glm.mat4(), glm.vec3(-0.5, 0.0, 0.0))
self.left_model_mat = self.left_translate_mat * self.left_scale_mat
self.right_scale_mat = glm.scale(glm.mat4(), glm.vec3(0.5, 1.0, 1.0))
self.right_translate_mat = glm.translate(glm.mat4(), glm.vec3(0.5, 0.0, 0.0))
self.right_model_mat = self.right_translate_mat * self.right_scale_mat
vertices = np.array([-1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
-1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype='f4')
self.vbo = self.ctx.buffer(vertices)
self.vao = self.ctx.simple_vertex_array(self.program, self.vbo, 'in_position')
def render(self, time, frame_time):
self.ctx.clear(1.0, 1.0, 1.0)
self.program["model"].write(bytes(self.left_model_mat))
self.program["texture_idx"].value = self.LEFT_TEXTURE_IDX
self.vao.render()
self.program["model"].write(bytes(self.right_model_mat))
self.program["texture_idx"].value = self.RIGHT_TEXTURE_IDX
self.vao.render()
if __name__ == '__main__':
moderngl_window.run_window_config(BugExample, args=('--window', 'glfw'))
运行此程序将打开一个带有您的图像的窗口test.jpg。
但是在纹理索引 31 处发生了一些奇怪的事情:
如果您更改索引以使首先加载的纹理(在我们的例子中是左侧纹理,如render方法中所述)具有索引 31,它将被另一个纹理覆盖,并且您将看到右半部分重复两次。
我应该指出,如果我只有一个纹理,而不是两个,并且该纹理的索引为31,则不会有问题。仅当一个纹理具有索引且另一个纹理在纹理之后31加载时,才会出现此问题。31
[编辑:我还应该指出,我加载超过32 个纹理没有问题。如果我要将图像分成 32 个或更多块(而不是上面示例中的 2 个块),甚至 64 个块或更多块,唯一的问题将是纹理索引31将被最后加载的纹理覆盖。]
我有一个模糊的猜测,这与将数字31作为 int 操作的方式有关吗?(像这里)
所以,最后,我的问题是- 这里发生了什么?我是否错过了正在发生的更大的事情,或者它只是生活中的一个事实,我应该避免纹理索引31并忘记它?
