OpenGL API 之 glPixelStore

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
剩下的8个参数与上述参数含义一致,不过是用在解包中。另外需要注意的是:glPixelStore函数是客户端的状态,可以使用glPushClientAttrib和glPopClientAttrib来进行状态的压入和弹出。

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()
 
OpenGL API 之 glPixelStore_第1张图片

你可能感兴趣的:(api,OpenGL)