opengl 保存渲染好的图像

在前面的文章中,我已经可以将媒体文件通过opengl来进行显示。

opengl 在显示的YUV视频序列上画多个框

opengl 显示BMP图像

如果希望将blend,或者其他方法处理过之后的图像数据保存为图像文件,该如何做呢?

这个时候我们就要用到glReadPixels函数,GPU渲染完数据在显存,回传内存的唯一方式glReadPixels函数,glReadPixels:读取一些像素。当前可以简单理解为“把已经绘制好的像素(它可能已经被保存到显卡的显存中)读取到内存”

 

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

代码如下:

BOOL WriteBitmapFile(char * filename, int wid, int hei, unsigned char * bitmapData)
{
	int width = wid;
	int height = hei;

	BITMAPFILEHEADER bitmapFileHeader;
	memset(&bitmapFileHeader, 0, sizeof(BITMAPFILEHEADER));
	bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER);
	bitmapFileHeader.bfType = 0x4d42;	//BM
	bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	//填充BITMAPINFOHEADER
	BITMAPINFOHEADER bitmapInfoHeader;
	memset(&bitmapInfoHeader, 0, sizeof(BITMAPINFOHEADER));
	bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmapInfoHeader.biWidth = width;
	bitmapInfoHeader.biHeight = height;
	bitmapInfoHeader.biPlanes = 1;
	bitmapInfoHeader.biBitCount = 24;
	bitmapInfoHeader.biCompression = BI_RGB;
	bitmapInfoHeader.biSizeImage = width * abs(height) * 3;

	//////////////////////////////////////////////////////////////////////////
	FILE * filePtr;
	unsigned char tempRGB;
	int imageIdx;

	//swap R B
	for (imageIdx = 0; imageIdx < bitmapInfoHeader.biSizeImage; imageIdx += 3)
	{
		tempRGB = bitmapData[imageIdx];
		bitmapData[imageIdx] = bitmapData[imageIdx + 2];
		bitmapData[imageIdx + 2] = tempRGB;
	}

	filePtr = fopen(filename, "wb");
	if (NULL == filePtr)
	{
		return FALSE;
	}

	fwrite(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);

	fwrite(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

	fwrite(bitmapData, bitmapInfoHeader.biSizeImage, 1, filePtr);

	fclose(filePtr);
	return TRUE;
}


void snap_shot(int img_w, int img_h)
{
	GLubyte* pPixelData;
	GLint line_width;
	GLint PixelDataLength;

	line_width = img_w * 3; // 得到每一行的像素数据长度 
	line_width = (line_width + 3) / 4 * 4;
	
	PixelDataLength = line_width * img_h;

	// 分配内存和打开文件 
	pPixelData = (GLubyte*)malloc(PixelDataLength);
	if (pPixelData == 0)
		exit(0);


	// 读取像素 
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

	//glReadPixels(0, 0, img_w, img_h, GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);
	glReadPixels(0, 0, img_w, img_h, GL_RGB, GL_UNSIGNED_BYTE, pPixelData);

	
	WriteBitmapFile("snapshot.bmp", img_w, img_h, pPixelData);
	free(pPixelData);
}

 

你可能感兴趣的:(opengl)