OpenGL场景截取后存储(BMP图片)

变量声明部分


	GLenum lastBuffer_OpenGLShot;
	GLbyte* pBits_OpenGLShot = 0; // 图像数据
	unsigned long ImageSize_OpenGLShot;
	int Width_OpenGLShot, Height_OpenGLShot;
	bool IsOpenGLShot;

	SYSTEMTIME m_SystemTime_OpenGLShot;
	char* m_Name_OpenGLShot;
	unsigned int m_NameLength_OpenGLShot;

注意:存储到BMP图像的宽度,必须是4的整数倍

bool COpenGL::writeBMP(const char filename[], unsigned char* data, unsigned int w, unsigned int h)
{
	std::ofstream out_file;

	/** 检查data */
	if (!data)
	{
		std::cerr << "data corrupted! " << std::endl;
		out_file.close();
		return false;
	}

	/** 创建位图文件信息和位图文件头结构 */
	BITMAPFILEHEADER header;
	BITMAPINFOHEADER bitmapInfoHeader;

	//unsigned char textureColors = 0;/**< 用于将图像颜色从BGR变换到RGB */

	/** 打开文件,并检查错误 */
	out_file.open(filename, std::ios::out | std::ios::binary);
	if (!out_file)
	{
		std::cerr << "Unable to open file " << filename << std::endl;
		return false;
	}

	/** 填充BITMAPFILEHEADER */
	header.bfType = 0x4d42;// 'BM';
	header.bfSize = w*h * 3 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	header.bfReserved1 = 0;
	header.bfReserved2 = 0;
	header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	/** 写入位图文件头信息 */
	out_file.write((char*)&header, sizeof(BITMAPFILEHEADER));

	/** 填充BITMAPINFOHEADER */
	bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitmapInfoHeader.biWidth = w;
	bitmapInfoHeader.biHeight = h;
	bitmapInfoHeader.biPlanes = 1;
	bitmapInfoHeader.biBitCount = 24;
	bitmapInfoHeader.biCompression = BI_RGB; // BI_RLE4 BI_RLE8
	bitmapInfoHeader.biSizeImage = w * h * 3; // 当压缩类型为BI_RGB是也可以设置为0
	bitmapInfoHeader.biXPelsPerMeter = 0;
	bitmapInfoHeader.biYPelsPerMeter = 0;
	bitmapInfoHeader.biClrUsed = 0;
	bitmapInfoHeader.biClrImportant = 0;
	/** 写入位图文件信息 */
	out_file.write((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));

	/** 将指针移到数据开始位置 */
	out_file.seekp(header.bfOffBits, std::ios::beg);

	/** 写入图像数据 */
	out_file.write((char*)data, bitmapInfoHeader.biSizeImage);

	out_file.close();
	return true;
}

bool COpenGL::screenshot()
{
	glGetIntegerv(GL_VIEWPORT, viewport);
	Width_OpenGLShot = viewport[2] - viewport[2] % 4;
	Height_OpenGLShot = viewport[3];

	ImageSize_OpenGLShot = Width_OpenGLShot * Height_OpenGLShot * 3;

	pBits_OpenGLShot = (GLbyte*)new unsigned char[ImageSize_OpenGLShot];
	if (!pBits_OpenGLShot)
		return false;

	// 从color buffer中读取数据
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ROW_LENGTH, 0);
	glPixelStorei(GL_PACK_SKIP_ROWS, 0);
	glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

	//
	glGetIntegerv(GL_READ_BUFFER, (GLint*)&lastBuffer_OpenGLShot);
	glReadBuffer(GL_FRONT);
	glReadPixels(0, 0, Width_OpenGLShot, Height_OpenGLShot, GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits_OpenGLShot);
	glReadBuffer(lastBuffer_OpenGLShot);

	if (IsOpenGLShot)
	{
		if (Count_OpenGLShot++ < 2)
		{
			//修改保存路径并存储
			//
			GetLocalTime(&m_SystemTime_OpenGLShot);
			sprintf_s(m_Name_OpenGLShot, m_NameLength_OpenGLShot, "ScreenShot\\%d-%02d-%02d_%02d-%02d-%02d-%02d_OpenGL.bmp",
				m_SystemTime_OpenGLShot.wYear,
				m_SystemTime_OpenGLShot.wMonth,
				m_SystemTime_OpenGLShot.wDay,
				m_SystemTime_OpenGLShot.wHour,
				m_SystemTime_OpenGLShot.wMinute,
				m_SystemTime_OpenGLShot.wSecond,
				m_SystemTime_OpenGLShot.wMilliseconds
				);

			if (!writeBMP(m_Name_OpenGLShot, (unsigned char*)pBits_OpenGLShot, Width_OpenGLShot, Height_OpenGLShot))
			{
				printf("OpenGLShot error\n");
			}
		}


		if (Count_OpenGLShot == 10)
		{
			Count_OpenGLShot = 0;
			IsOpenGLShot = false;
		}

	}
	
	//

	delete pBits_OpenGLShot;
	return true;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值