您的位置:首页 > 运维架构

VS平台下 OpenGL glReadPixels、glDrawPixels、glCopyPixels函数

2016-03-11 11:56 791 查看

glReadPixels

glReadPixels (GLint x, GLint y, GLsizeiwidth, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);

参数1,2:矩阵的左下角横、纵坐标(坐标以窗口最左下角为零,最右上角为最大值)。

参数3,4:矩阵的宽度、高度。

参数5:  读取的内容。例如:GL_RGB就会依次读取像素的红、绿、蓝三种数据,GL_RGBA则会依次读取像素的红、绿、蓝、alpha四种数据,GL_RED则只读取像素的红色数据(类似的还有GL_GREEN,GL_BLUE,以及GL_ALPHA)。如果采用的不是RGBA颜色模式,而是采用颜色索引模式,则也可以使用GL_COLOR_INDEX来读取像素的颜色索引。目前仅需要知道这些,但实际上还可以读取其它内容,例如深度缓冲区的深度数据等。

参数6: 读取的内容保存到内存时所使用的格式。例如:GL_UNSIGNED_BYTE会把各种数据保存为GLubyte,GL_FLOAT会把各种数据保存为GLfloat等。

参数7:表示一个指针,像素数据被读取后,将被保存到这个指针所表示的地址。

注:

1.需要保证该地址有足够的可以使用的空间,以容纳读取的像素数据。

      2. glReadPixels实际上是从缓冲区中读取数据,如果使用了双缓冲区,则默认是从正在显示的缓冲(即前缓冲)中读取,而绘制工作是默认绘制到后缓冲区的。因此,如果需要读取已经绘制好的像素,往往需要先交换前后缓冲。

 

问题:

1.OpenGL常用的RGB像素数据与BMP文件的BGR像素数据顺序不一致

可以使用一些代码交换每个像素的第一字节和第三字节,使得RGB的数据变成BGR的数据。当然也可以使用另外的方式解决问题:新版本的OpenGL除了可以使用GL_RGB读取像素的红、绿、蓝数据外,也可以使用GL_BGR按照相反的顺序依次读取像素的蓝、绿、红数据,这样就与BMP文件格式相吻合了。即使你的gl/gl.h头文件中没有定义这个GL_BGR,也没有关系,可以尝试使用GL_BGR_EXT。虽然有的OpenGL实现(尤其是旧版本的实现)并不能使用GL_BGR_EXT,但我所知道的Windows环境下各种OpenGL实现都对GL_BGR提供了支持,毕竟Windows中各种表示颜色的数据几乎都是使用BGR的顺序,而非RGB的顺序。这可能与IBM-PC的硬件设计有关。

 

1.    BMP文件中“对齐”带来的影响

只要通过glPixelStore修改“像素保存时对齐的方式”就可以了

例:

      intalig = 4;

      glPixelStorei(GL_UNPACK_ALIGNMENT,alig);

第一个参数表示“设置像素的对齐值”,第二个参数表示实际设置为多少。这里像素可以单字节对齐(实际上就是不使用对齐)、双字节对齐(如果长度为奇数,则再补一个字节)、四字节对齐(如果长度不是四的倍数,则补为四的倍数)、八字节对齐。分别对应alignment的值为1,
2, 4, 8。实际上,默认的值是4,正好与BMP文件的对齐方式相吻合。

glPixelStorei也可以用于设置其它各种参数。

glDrawPixels

glDrawPixels (GLsizei width, GLsizei height, GLenumformat, GLenum type, const GLvoid *pixels);

参数1:图像宽度

参数2:图像高度

参数3:像素数据内容

参数4:像素数据在内存中的格式

参数5:用于绘制的像素数据在内存中的位置。

glCopyPixels

glCopyPixels (GLint x, GLint y, GLsizei width, GLsizeiheight, GLenum type);

参数1,2:表示复制像素来源的矩阵的左下角横、纵坐标

参数3,4:表示复制像素来源的矩阵的宽度和高度

参数5:通常使用GL_COLOR,表示复制像素的颜色,但也可以是GL_DEPTH或GL_STENCIL,分别表示复制深度缓冲数据或模板缓冲数据。

例:

void display(void)

{
//清除屏幕
glClear(GL_COLOR_BUFFER_BIT);

//绘制
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);

glVertex2f(0.0f, 0.0f);

glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);

glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(0.5f, 1.0f);

glEnd();
glPixelZoom(-0.5f, -0.5f);
glRasterPos2i(1, 1);
glCopyPixels(500, 500, 500, 500, GL_COLOR);

//完成绘制,并抓取图像保存为BMP文件
glutSwapBuffers();

}

int main(int argc, char **argv)

{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(400, 300);
glutCreateWindow("OpenGL 窗口");
glutDisplayFunc(&display);
//glutIdleFunc(&setLight);
glutMainLoop();
return 0;

}

效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: