1. 简介
glPixelStore 用来设置像素存储模式(像素数据在存储空间中的布局方式)
2. 函数原型
// c style void glPixelStoref(GLenum pname, GLfloat param); void glPixelStorei(GLenum pname, GLint param);
# python style def glPixelStoref( pname , param ) def glPixelStorei( pname , param )
参数描述:
pname: 设置打包和解包参数的名称 打包参数包括: GL_PACK_SWAP_BYTES, GL_PACK_LSB_FIRST, GL_PACK_ROW_LENGTH, GL_PACK_IMAGE_HEIGHT, GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_IMAGES, GL_PACK_ALIGNMENT. 解包参数包括: GL_UNPACK_SWAP_BYTES, GL_UNPACK_LSB_FIRST, GL_UNPACK_ROW_LENGTH, GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_IMAGES, GL_UNPACK_ALIGNMENT. param: 对应pname的取值
3. 详细描述
glPixelStore设置像素存储空间内的像素布局,设置之后会影响到以下函数调用的结果:
glDrawPixelsglReadPixelsglPolygonStippleglBitmapglTexImage1DglTexImage2DglTexImage3DglTexSubImage1DglTexSubImage2D glTexSubImage3D
如果开启了ARB_imaging扩展,那么还会影响到以下函数的调用:
glConvolutionFilter1DglConvolutionFilter2DglSeparableFilter2DglColorTableglColorSubTableglHistogramglMinmax
下表中给出了glPixelStore中pname的取值,初始取值以及取值范围
pname取值 | 类型 | 初始的param取值 | param的取值范围 |
---|---|---|---|
GL_PACK_SWAP_BYTES | 布尔值 | false | true或者false |
GL_PACK_LSB_FIRST | 布尔值 | false | true或者false |
GL_PACK_ROW_LENGTH | 整型 | 0 | 非负数 |
GL_PACK_IMAGE_HEIGHT | 整型 | 0 | 非负数 |
GL_PACK_SKIP_ROWS | 整型 | 0 | 非负数 |
GL_PACK_SKIP_PIXELS | 整型 | 0 | 非负数 |
GL_PACK_SKIP_IMAGES | 整型 | 0 | 非负数 |
GL_PACK_ALIGNMENT | 整型 | 4 | 1,2,4,8 |
GL_UNPACK_SWAP_BYTES | 布尔值 | false | true或者false |
GL_UNPACK_LSB_FIRST | 布尔值 | false | true或者false |
GL_UNPACK_ROW_LENGTH | 整型 | 0 | 非负数 |
GL_UNPACK_IMAGE_HEIGHT | 整型 | 0 | 非负数 |
GL_UNPACK_SKIP_ROWS | 整型 | 0 | 非负数 |
GL_UNPACK_SKIP_PIXELS | 整型 | 0 | 非负数 |
GL_UNPACK_SKIP_IMAGES | 整型 | 0 | 非负数 |
GL_UNPACK_ALIGNMENT | 整型 | 4 | 1,2,4,8 |
下面对表中的参数作一些详细的说明:
-
GL_PACK_SWAP_BYTES
- 如果设置为true,那么存储空间中的字节解析方式就会反向(有点类似于Big-Edian和Little-Edian之间转换的效果),需要注意的是:GL_PACK_SWAP_BYTES是以一个像素为单位(像素中可以存储颜色、索引、深度等),但是该像素的解析不受GL_PACK_SWAP_BYTES的影响,也就是说如果一个像素是颜色GL_RGB,那么在解析的时候还是按R、G、B的顺序进行 GL_PACK_LSB_FIRST
- 如果设置为true,【TODO】 GL_PACK_ROW_LENGTH
- 设置像素数据布局中每一行所包含的像素个数 GL_PACK_IMAGE_HEIGH
- 设置像素数据需要跳过的行数(当设置glTexImage3D纹理的时候,处理方式与glTexImage2D类似,只是此时的跳过字节数乘上GL_PACK_IMAGE_HEIGH) GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_IMAGES
- 设置从像素数据中跳过多少字节,字节数= GL_PACK_ROW_LENGTH * GL_PACK_SKIP_ROWS + GL_PACK_SKIP_PIXELS(GL_PACK_SKIP_IMAGES) GL_PACK_ALIGNMENT
- 设置像素数据每一行在内存中的对齐方式,取值可以为1,2,4,8
4. 示例
示例演示了从一整张的纹理图片中截取其中的部分作为二维纹理图片(附件中有整块的纹理图片board.jpg,图片大小是1024*1024,其中每种颜色的格子是256*256),处理方式使用glPixelStore的方式跳过部分的像素数据
# -*- coding: utf-8 -*-
import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from PIL.Image import *
xrot = yrot = zrot = 0.0
texture = 0
def loadTextures():
image = open("board.jpg")
ix = image.size[0]
iy = image.size[1]
image = image.convert("RGBA").tobytes("raw", "RGBA")
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glGenTextures(1, texture)
glBindTexture(GL_TEXTURE_2D, texture)
#Skip 1024*256+256 bytes, so the color is blue
glPixelStorei(GL_UNPACK_ROW_LENGTH, 1024)
glPixelStorei(GL_UNPACK_SKIP_ROWS, 512)
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 512)
glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
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_WRAP_S, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
def gl_init():
glClearColor(0.0, 0.0, 0.0, 0.0)
glEnable(GL_TEXTURE_2D)
glEnable(GL_DEPTH_TEST)
loadTextures()
def display():
global xrot, yrot, zrot
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -5)
glRotatef(xrot,1.0,0.0,0.0) # Rotate The Cube On It's X Axis
glRotatef(yrot,0.0,1.0,0.0) # Rotate The Cube On It's Y Axis
glRotatef(zrot,0.0,0.0,1.0) # Rotate The Cube On It's Z Axis
glBindTexture(GL_TEXTURE_2D, texture)
glBegin(GL_QUADS)
# Front Face (note that the texture's corners have to match the quad's corners)
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) # Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) # Top Left Of The Texture and Quad
# Back Face
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) # Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) # Bottom Left Of The Texture and Quad
# Top Face
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0) # Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0) # Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
# Bottom Face
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0) # Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0) # Top Left Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
# Right face
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) # Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) # Top Left Of The Texture and Quad
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
# Left Face
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) # Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) # Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
glEnd()
xrot += 0.2
yrot += 0.3
zrot += 0.4
glutSwapBuffers()
def resize(w, h):
if h == 0:
h = 1
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(w)/float(h), 0.001, 1000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE)
glutInitWindowSize(640, 480)
glutInitWindowPosition(500, 500)
glutCreateWindow(u"OpenGL 测试")
glutDisplayFunc(display)
glutIdleFunc(display)
glutReshapeFunc(resize)
gl_init()
glutMainLoop()
if __name__ == '__main__':
main()