1. 简介
glPixelMap设置像素传输中的像素映射
2. 函数原型
// 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:
设置映射区域的值
3. 详细描述
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 |
4. 示例
我们现在要做这样一个功能:反转一张图片,让图片中的颜色变为它的互补色。假设我们设置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()