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;
}
效果:
相关文章推荐
- 使用xshell时中文横着显示的解决办法
- win上传Linux文件乱码问题解决办法
- EV SSL证书,防范钓鱼网站的神兵利器
- Hadoop(一):概述
- Windows环境下编译OpenCV3.1和OpenCV_contrib for vs2008
- 分布式学习第一章 SOA服务简述
- MVC三层,BLL层获取网站根目录
- Linux进程通信的几种方式
- Tomcat配置Jconsole , JvisualVm 监控配置
- linux编程之GDB调试
- 怎样安装两个tomcat,怎样配置
- [转]Stop Sharing Session State between Multiple Tabs of Browser
- tomcat结合nginx使用 基础教程
- ecshop 后台模板设置-》设置模板
- NSRunloop 个人思考与实践
- Apache Arrow:一个跨平台的内存数据交换格式
- eclipse中pom.xml org.apache.maven.plugins报错的解决
- telnet不能用!提示:-bash: telnet: command not found
- 与 Hadoop 对比,如何看待 Spark 技术
- docker学习笔记16:Dockerfile 指令 ADD 和 COPY介绍