OpenGL•PBO: glReadPixels&glDrawPixels

本文详细介绍了如何在OpenGL中利用Pixel Buffer Objects (PBO)与glReadPixels函数进行缓冲区交换。在initPBO()函数中,创建并分配了PBO内存,初始化为黑色。在render()函数中,首先清空颜色缓冲区,然后将下半部分窗口数据读入PBO,并在PBO处于UNPACK模式下绘制出来,实现了双缓冲效果。主要涉及OpenGL、缓冲技术和图像处理。
摘要由CSDN通过智能技术生成

PART ONE

6eb95c4ac5734287a67e225a57e818db.png

 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)。

 

 

 

 

 

 

OpenGL PBOOpenGL中的一个扩展,它允许通过在图形处理单元(GPU)上创建一个像素缓冲对象(PBO),将数据从CPU传输到GPU,然后可以使用这些数据在纹理中显示图像。 在使用PBO和YUV420p格式的纹理显示图像之前,我们需要将YUV420p格式的图像数据转换为适用于OpenGL纹理的格式。YUV420p是一种常见的视频图像格式,它包含一个与图像分辨率相同的Y分量(明亮度)和两个与图像分辨率的四分之一相同的UV分量(色度)。Y分量与图像分辨率相同,而UV分量的分辨率被降低以节省存储和传输带宽。 首先,我们需要创建一个纹理,并将它与PBO关联。然后,我们可以将YUV420p数据传输到PBO中。将数据传输到PBO的过程涉及到将Y、U和V分量的数据按照特定的布局传输到PBO中。我们可以使用glBufferData函数将数据传输到PBO。 接下来,我们需要将PBO中的数据绑定到纹理,并对纹理进行设置以正确地显示图像。我们可以使用glBindTexture函数来绑定纹理,并使用glTexSubImage2D函数将PBO中的数据传输到纹理中。 最后,我们可以使用OpenGL的渲染管线将纹理中的图像显示在屏幕上。我们可以使用一个简单的顶点着色器和一个片段着色器将纹理中的图像转换为可视化的图像。 总结起来,使用OpenGL PBO和YUV420p纹理可以更高效地显示图像。通过将图像数据传输到PBO中,并将PBO与纹理关联,可以在GPU上进行图像处理和渲染,从而提高了图像显示的效率和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱书网-上海

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值