PART ONE
codes.cpp
#include <stdio.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define width 222
#define height 207
GLuint PBO;
void initPBO()
{
glGenBuffers(1, &PBO);
glBindBuffer(GL_PIXEL_PACK_BUFFER, PBO);
glBufferData(GL_PIXEL_PACK_BUFFER, width*height*4*sizeof(GLubyte), NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glBindBuffer(GL_PIXEL_PACK_BUFFER, PBO);
glReadPixels(0,0, width, height/2, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PBO);
glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
// init GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(width, height);
glutInitWindowPosition(200, 100);
int id = glutCreateWindow("PBO&glReadPixels");
// init GLEW after GLUT
GLenum err = glewInit();
if (err != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(err));
return 1;
}
initPBO();
glutDisplayFunc(render);
glutMainLoop();
return 0;
}
部分二
代码分析
1、在函数initPBO()中,glBufferData( , width*height*4*sizeof(GLubyte), NULL, )函数分配内存大小,数据初始化部分为NULL,实际对应0x00(黑色)。
2、在render()函数中通过glReadPixels( , , , height/2, , , )函数将通过glClearColor()函数产生的下半个高度窗口的数据写入到PBO中,因为此时PBO绑定点为:GL_PIXEL_PACK_BUFFER并且glReadPixels()函数中最后一个参数为NULL。又因为PBO的初始数据为NULL(NULL对应0x00为黑色),故此时PBO中整体的下半部分为灰色,上半部分为黑色。之后通过将PBO设置为UNPACK模式,调用函数glDrawPixels( , , , , NULL)将PBO的数据进行渲染并swapbuffer进行显示。
3、如果glReadPixels( , , , , , , NULL)函数中最后一个参数不是NULL,glReadPixels则将DFB(Default Framebuffer)中的数据写入NULL对应的参数下。例如,如果定义个一个三维GLubyte的image[][][4]数组,在NULL的位置写入image,则glReadPixels( , , , , , , image)是将像素数据写入image对应的CPU端内存中。
4、 main()函数中数据初始化部分调用initPBO(),分配buffer用的内存,和初始化为黑色(0x00:NULL)。