OpenGL API 之 glPixelStore(2)

简介

glPixelsStore 主要是用来设置像素存储的模式

函数原型

void glPixelStoref( GLenum pname,
    GLfloat param);

void glPixelStorei( GLenum pname,
    GLint param);

参数描述:
1. pname:代表某种特性的标识符
2. param:设置对应pname的值

panme参数主要包含16个标识符,其中带GL_PACK前缀的是压包(将数据从OpenGL中读入内存)参数,带GL_UNPACK前缀的是解包(从内存读入OpenGL)参数。

参数类型初始默认值取值范围参数描述
GL_PACK_SWAP_BYTES布尔falseTRUE/FALSE是否开启字节高低位交换
GL_PACK_LSB_FIRST布尔falseTRUE/FALSE是否开启位的交换
GL_PACK_ROW_LENGTH整型0任何非负整数一行包含的像素个数
GL_PACK_IMAGE_HEIGHT整型0任何非负整数第三维度参数的设置
GL_PACK_SKIP_PIXELS整型0任何非负整数
GL_PACK_SKIP_ROWS整型0任何非负整数
GL_PACK_SKIP_IMAGES整型0任何非负整数
GL_PACK_ALIGNMENT整型41,2,4,8内存中字节对齐方式
GL_UNPACK_SWAP_BYTES布尔false同上PACK同上PACK
GL_UNPACK_LSB_FIRST布尔false同上PACK同上PACK
GL_UNPACK_ROW_LENGTH整型0同上PACK同上PACK
GL_UNPACK_IMAGE_HEIGHT整型0同上PACK同上PACK
GL_UNPACK_SKIP_PIXELS整型0同上PACK同上PACK
GL_UNPACK_SKIP_ROWS整型0同上PACK同上PACK
GL_UNPACK_SKIP_IMAGES整型0同上PACK同上PACK
GL_UNPACK_ALIGNMENT整型4同上PACK同上PACK

版本支持
OpenGL版本

详细描述

glPixelStore通过设置像素的存储模式,对后续的一些函数调用产生影响(如果不调用这些函数,那么glPixelStore并没有任何用处),这些函数包括:
- glDrawPixels
- glReadPixels
- glPolygonStipple
- glBitmap
- glTexImage{1,2,3}D
- glTexSubImage{1,2,3}D
如果OpenGL支持ARB_imaging扩展,那么还会影响
- glConvolutionFilter{1,2,3}D
- glColorTable
- glColorSubTable
- glHistogram
- glMinmax
下面我们先看pname设置为PACK前缀的参数的说明,PACK前缀的这些参数表示glPixelStore会对压包的操作产生影响

  1. GL_PACK_SWAP_BYTES
    如果设置为ture,那么对于颜色分量、深度分量、颜色索引和模板索引分量的解析都会反转。举例来说:如果四个字节分量的颜色的RGBA四个分量分别是b0,b1,b2,b3,当GL_PACK_SWAP_BYTES设置为true的时候,在内存中的存储顺序会被修改为b3,b2,b1,b0。这个参数对于单字节数据并没有效果。字节交换的结果如下图所示:
    PACK_SWAP_BYTES示意图
    一般来说,只要OpenGL应用程序不与其他不同体系(不同字节顺序)的计算机共享图像,就可以忽略字节顺序的问题。

  2. GL_PACK_LBS_FIRST
    这个参数只适用于在为徒上绘制或者读取1位图像,如果是false,那么数据位从字节的最高有效位开始提取,否则数据位从反方向开始提取。例如如果字节是0x31,位的顺序是{0,0,1,1,0,0,0,1},如果设置为true,那么位的顺序就会变为{1,0,0,0,1,1,0,0},示例程序如下:

#include <GL/glut.h>
#include <stdlib.h>

GLubyte rasters[24] = {
    0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
    0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
    0xff, 0xc0, 0xff, 0xc0 };

void init(void)
{
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_UNPACK_LSB_FIRST, TRUE);
    glClearColor(0.0, 0.0, 0.0, 0.0);
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glRasterPos2i(20, 20);
    glBitmap(10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
    glBitmap(10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
    glBitmap(10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
    glFlush();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, w, 0, h, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 27:
        exit(0);
    }
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(100, 100);
    glutInitWindowPosition(100, 100);
    glutCreateWindow(argv[0]);
    init();
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

glPixelStorei(GL_UNPACK_LSB_FIRST, TRUE);设置为ture和false的时候,读取到的图片是不同的。这主要是因为对于raster中变量的解析不同导致的。当使用默认值false的时候解析的方式如下:
原始解析
当使用true之后,得到的是一个倒着的F
这个程序的两个输出如下所示:
- true
GL_UNPACK_LBS_FIRST = true
- false
GL_UNPACK_LBS_FIRST = false
3. GL_PACK_ROW_LENGTH

该参数主要是设置了一行中的像素数量,如果该参数指定为0,那么行宽度就使用glReadPixels、glDrawPixels或glCopyPixels所指定的宽度。如果该参数不是0,那么行宽度就会使用该参数设置的值,而导致以上三个参数中设置的width参数无效。
假设第一行的像素其实位置是内存中的地址p,那么下一行像素的起始位置需要跳过的字节数(也就是说一行所占的字节)计算公式如下:
GL_PACK_ROW计算公式
参数的含义如下:
n:代表一个像素中包含的分量(例如像素中包含RGBA四个分量,那么n就等于4)
l:代表一行中包含的像素数量(也就是本函数指定的值,如果为0,就是各自调用函数glReadPixels、glDrawPixels、glCopyPixels中的width参数的值)
a:代表字节对齐的值(GL_PACK(UNPACK)_ALIGNMENT中设置的值,默认是4)
s:代表像素单一成分所占用的字节数
4. GL_PACK_IMAGE_HEIGHT
该参数主要用来设置三维纹理的第三个维度值,与ROW_LENGTH有点类似。假设第一行的第一个像素位置在内存中的p出,那么下一行第一个像素的内存地址由下面的公式计算:
GL_PACK_IMAGE_HEIGHT
参数的含义如下:
n:代表一个像素中包含的分量
l:代表一行中像素的数量(如果GL_PACK_ROW_LENGTH不为0,那么使用该变量设置的值,否则使用glTexImage3D中的width参数设置的值)
h:代表第三个维度的值(如果GL_PACK_IMAGE_HEIGHT不为0,那么就使用设置的值,否则使用glTexImage3D种height参数设置的值)
a:代表字节对齐的值(GL_PACK(UNPACK)_ALIGNMENT中设置的值,默认是4)
s:代表像素单一成分所占用的字节数

5.GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_IMAGES
这三个参数主要是用来截取一个影像中的一部分。第一个参数主要是用来设置跳过多少个字节,让截取像素从跳过的字节之后开始计算。第二个参数是结合GL_PACK_ROW_LENGTH进行计算,跳过的字节数是二者的乘积。第三个参数是结合GL_PACK_IMAGE_HEIGHT进行计算,跳过的字节数是二者的乘积。
6. GL_PACK_ALIGNMENT
用来设置像素对齐,可以设置的值是1(byte-alignment),2(even-numbered byte),4(word-alignment)和8(double-word)
像素对齐的含义是什么呢?简单来说就是不足的地方直接补齐。也就是把不足字节对齐数位数的按1,2,4,8字节获取出来。假设对于上面提到的位图:
对齐位图
如果我们设置对齐是4,那么当我们调用函数,如

glBitmap(10,12,0.0,0.0,0.0,11.0,0.0,rasters)

的时候,我们指定长度是10,但是我们要求对齐是4个字节(32位),那么最底下的两行数据会被一起作为第一行被解析(正好32位),我们只取前10位,剩下的被丢弃。第二行起始位置是图中的第三行,我们也取前10位。这样会造成混乱,导致整个数据单元数据不够用(正好12行,但是被我们这样取会只有6行,剩下的6行有可能访问到其他非初始化的内存空间)而出错,绘制出的图形肯定也不是前面程序中运行的效果。

其他的UNPACK的参数与PACK中介绍的含义是一样的,只不过它们表示的是解包操作(从内存读取到OpenGL中),另外glPixelStore是两个函数族,glPixelStorei和glPixelStoref,一般使用i版本即可,f版本设置的参数是浮点数,它会被截断成与之浮点数设置最近的整数。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值