OpenGL API 之 glPixelStore

来源:互联网 发布:专利公司 知乎 编辑:程序博客网 时间:2024/06/08 01:32

1. 简介

glPixelStore 用来设置像素存储模式(像素数据在存储空间中的布局方式)

2. 函数原型

// c stylevoid glPixelStoref(GLenum  pname,  GLfloat  param);void glPixelStorei(GLenum  pname,  GLint  param);
# python styledef 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布尔值falsetrue或者falseGL_PACK_LSB_FIRST布尔值falsetrue或者falseGL_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整型41,2,4,8GL_UNPACK_SWAP_BYTES布尔值falsetrue或者falseGL_UNPACK_LSB_FIRST布尔值falsetrue或者falseGL_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整型41,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
剩下的8个参数与上述参数含义一致,不过是用在解包中。另外需要注意的是:glPixelStore函数是客户端的状态,可以使用glPushClientAttrib和glPopClientAttrib来进行状态的压入和弹出。

4. 示例

示例演示了从一整张的纹理图片中截取其中的部分作为二维纹理图片(附件中有整块的纹理图片board.jpg,图片大小是1024*1024,其中每种颜色的格子是256*256),处理方式使用glPixelStore的方式跳过部分的像素数据

# -*- coding: utf-8 -*-import sysfrom OpenGL.GL import *from OpenGL.GLU import *from OpenGL.GLUT import *from PIL.Image import *xrot = yrot = zrot = 0.0texture = 0def 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() 

0 0
原创粉丝点击