glPixelMap设置像素传输中的像素映射
// c style void glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values); void glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values); void glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values);
# python style def glPixelMapfv( map , mapsize , values ) def glPixelMapuiv( map , mapsize , values ) def glPixelMapusv( map , mapsize , values )
参数描述:
map: 指明一个映射的选项名称,可选的取值有 GL_PIXEL_MAP_I_TO_I GL_PIXEL_MAP_S_TO_S GL_PIXEL_MAP_I_TO_R GL_PIXEL_MAP_I_TO_G GL_PIXEL_MAP_I_TO_B GL_PIXEL_MAP_I_TO_A GL_PIXEL_MAP_R_TO_R GL_PIXEL_MAP_G_TO_G GL_PIXEL_MAP_B_TO_B GL_PIXEL_MAP_A_TO_A mapsize: 设置映射区域的大小 values: 设置映射区域的值
glPixelMap设置像素传输的转换表(或者称为对应关系),当设置之后,它会影响如下API的作用效果:
glCopyPixels,glCopyTexImage1D,glCopyTexImage2D,glCopyTexSubImage1D,glCopyTexSubImage2D,glCopyTexSubImage3D,glDrawPixels,glReadPixels,glTexImage1D,glTexImage2D,glTexImage3D,glTexSubImage1D,glTexSubImage2DglTexSubImage3D
如果 ARB_imaging扩展开启,那么以下API的调用也会受到glPixelMap的影响:
glColorTableglColorSubTableglConvolutionFilter1DglConvolutionFilter2DglHistogramglMinmaxglSeparableFilter2D
glPixelMap中的mapsize的参数定义了映射的数组的大小(mapsize的大小必须是2的n次方,否则结果未定义),value指向实际数组的地址(如果开启了PBO,那么value的作用就是PBO中的偏移量)下表列出了glPixelMap中参数的初始值:
map取值 | 查询索引(源) | 查询索引(目标) | 初始值 | 初始值 |
---|---|---|---|---|
GL_PIXEL_MAP_I_TO_I | 颜色索引值 | 颜色索引值 | 1 | 0 |
GL_PIXEL_MAP_S_TO_S | 模板索引值 | 模板索引值 | 1 | 0 |
GL_PIXEL_MAP_I_TO_R | 颜色索引值 | 红色 | 1 | 0 |
GL_PIXEL_MAP_I_TO_G | 颜色索引值 | 绿色 | 1 | 0 |
GL_PIXEL_MAP_I_TO_B | 颜色索引值 | 蓝色 | 1 | 0 |
GL_PIXEL_MAP_I_TO_A | 颜色索引值 | Alpha | 1 | 0 |
GL_PIXEL_MAP_R_TO_R | 红色 | 红色 | 1 | 0 |
GL_PIXEL_MAP_G_TO_G | 绿色 | 绿色 | 1 | 0 |
GL_PIXEL_MAP_G_TO_B | 蓝色 | 蓝色 | 1 | 0 |
GL_PIXEL_MAP_G_TO_A | Alpha | Alpha | 1 | 0 |
我们现在要做这样一个功能:反转一张图片,让图片中的颜色变为它的互补色。假设我们设置mapsize的大小是255,并设置value的取值是从1.0到0.0按255的级别递减,也就是:
mapArray = [1]; for i in range(1, 256): mapArray.append(1.0- ((1.0)/255.0)*i)
然后我们使用GL_PIXEL_MAP_R_TO_R、GL_PIXEL_MAP_G_TO_G、GL_PIXEL_MAP_G_TO_B让颜色通过映射表中的颜色得到它的处理后的颜色。假设图片中某一像素的颜色是RGB(255,127,127),那么它映射的计算过程如下:先把颜色从[0,255](颜色的取值范围)映射到mapsize这个大小上,也就是 R = round(255/255)*255、G=round(127/255)*255、B=round(127/255)*255 = R(255,127,127)然后利用得到的索引值去mapArray数组中查询对应地方的颜色得到最终RGB是(0.0,0.5,0.5),最后将得到的结果进行处理并绘制出来。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * from PIL.Image import * ix = 0 iy = 0 data = None def gl_init(): glClearColor(0.0, 0.0, 0.0, 0.0) image = open("textures/lzl.png") global ix global iy ix = image.size[0] iy = image.size[1] global data data = image.tobytes("raw", "RGBX", 0, -1) glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, data) 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) glEnable(GL_TEXTURE_2D) def keyboard(key, x, y): global data global ix global iy if key == ' ': glPixelTransferi(GL_MAP_COLOR, GL_TRUE) mapArray = [1]; for i in range(1, 256): mapArray.append(1.0- ((1.0)/255.0)*i) glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 255, mapArray) glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 255, mapArray) glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 255, mapArray) glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, data) glutPostRedisplay() def display(): glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0.0, 0.0, -3.0) glBegin(GL_QUADS) glTexCoord2f(0,0) glVertex3f(-1, -1, 0) glTexCoord2f(1,0) glVertex3f(1, -1, 0) glTexCoord2f(1,1) glVertex3f(1, 1, 0) glTexCoord2f(0,1) glVertex3f(-1, 1, 0) glEnd() glutSwapBuffers() def resize(w, h): if h == 0: h = 1 glViewport(0, 0, w, h) global windowWidth global windowHeight windowWidth = w windowHeight = 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) glutReshapeFunc(resize) glutKeyboardFunc(keyboard) gl_init() glutMainLoop() if __name__ == '__main__': main()