glTexImage2D 数据未按预期填充
glTexImage2D data not filled as expected
想了解glTexImage2D,我在Python写了如下测试代码:
import numpy as np
import OpenGL.GL as gl
import glfw
# initiating context
glfw.init()
w = glfw.create_window(100, 100, 'dd', None, None)
glfw.make_context_current(w)
# prepare sample image
width, height = 3, 3
image = np.array([i for i in range(width * height * 3)], dtype='ubyte')
# prepare texture
t = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, t)
iformat = gl.GL_RGB
# upload texture
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, iformat, width, height, 0, iformat, gl.GL_UNSIGNED_BYTE, image)
# read texture
p = gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, iformat, gl.GL_UNSIGNED_BYTE)
# display pixel values
pixels = iter(p)
for x in range(width):
for y in range(height):
print([next(pixels), next(pixels), next(pixels)])
出乎意料的是,打印结果如下:
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[12, 13, 14]
[15, 16, 17]
[18, 19, 20]
[24, 25, 26]
[0, 0, 0]
[0, 0, 93]
显然缺少一些值。为什么会这样?我错过了什么吗?
如果将具有 3 个颜色通道的 RGB 图像加载到纹理对象中,GL_UNPACK_ALIGNMENT
必须设置为 1:
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, iformat, width, height, 0, iformat, gl.GL_UNSIGNED_BYTE, image)
GL_UNPACK_ALIGNMENT
指定内存中每个像素行开始的对齐要求。默认情况下 GL_UNPACK_ALIGNMENT
设置为 4。
这意味着假定图像每一行的开头与 4 的倍数的地址对齐。由于图像数据紧密打包并且每个像素的大小为 3 个字节,因此必须更改对齐方式。
如果图像的宽度可以被 4 整除(更确切地说,如果 3*width
可以被 4 整除)那么错误是不明显的。
由于你是从GPU读回纹理,你还需要改变GL_PACK_ALIGNMENT
:
gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
p = gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, iformat, gl.GL_UNSIGNED_BYTE)
想了解glTexImage2D,我在Python写了如下测试代码:
import numpy as np
import OpenGL.GL as gl
import glfw
# initiating context
glfw.init()
w = glfw.create_window(100, 100, 'dd', None, None)
glfw.make_context_current(w)
# prepare sample image
width, height = 3, 3
image = np.array([i for i in range(width * height * 3)], dtype='ubyte')
# prepare texture
t = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, t)
iformat = gl.GL_RGB
# upload texture
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, iformat, width, height, 0, iformat, gl.GL_UNSIGNED_BYTE, image)
# read texture
p = gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, iformat, gl.GL_UNSIGNED_BYTE)
# display pixel values
pixels = iter(p)
for x in range(width):
for y in range(height):
print([next(pixels), next(pixels), next(pixels)])
出乎意料的是,打印结果如下:
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[12, 13, 14]
[15, 16, 17]
[18, 19, 20]
[24, 25, 26]
[0, 0, 0]
[0, 0, 93]
显然缺少一些值。为什么会这样?我错过了什么吗?
如果将具有 3 个颜色通道的 RGB 图像加载到纹理对象中,GL_UNPACK_ALIGNMENT
必须设置为 1:
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, iformat, width, height, 0, iformat, gl.GL_UNSIGNED_BYTE, image)
GL_UNPACK_ALIGNMENT
指定内存中每个像素行开始的对齐要求。默认情况下 GL_UNPACK_ALIGNMENT
设置为 4。
这意味着假定图像每一行的开头与 4 的倍数的地址对齐。由于图像数据紧密打包并且每个像素的大小为 3 个字节,因此必须更改对齐方式。
如果图像的宽度可以被 4 整除(更确切地说,如果 3*width
可以被 4 整除)那么错误是不明显的。
由于你是从GPU读回纹理,你还需要改变GL_PACK_ALIGNMENT
:
gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
p = gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, iformat, gl.GL_UNSIGNED_BYTE)