《windows平台使用openGL显示摄像头数据代码实现》链接:
openGL显示摄像头数据代码实现
OpenGL(Open Graphics Library,开放图形库或者“开放式图)是用于渲染2D、3D图形的跨平台(windows,linux、安卓等)的应用程序编程接口(API)。OpenGL利用了图形加速硬件,所以其对图像的渲染效率很高。
GLUT 全名是OpenGL Utility Toolkit,freeglut 开源免费的GLUT 库。主要负责创建图形显示窗口、初始化 OpenGL 上下文等,使用freeglut 才能够在程序中使用OpenGL API来渲染图形到窗口。
freeGLUT的开源代码在:https://github.com/FreeGLUTProject/freeglut
该函数主要用于初始化GLUT,其两个参数必须来源自main函数的两个参数,即
argcp:指向从main()函数直接传递过来的argc变量。
argv:指向从main()函数直接传递过来argv变量。
该函数用于设置GLUT的初始显示模式。显示模式主要有以下:
模式 | 含义 |
---|---|
GLUT_RGB | 采用RGB 颜色模式的窗口 |
GLUT_RGBA | 采用RGBA 颜色模式的窗口 |
GLUT_INDEX | 采用颜色索引模式的窗口 |
GLUT_SINGLE | 采用单缓存窗口 |
GLUT_DOUBLE | 采用双缓存窗口 |
GLUT_ALPHA | 窗口的颜色分量包含 alpha 值 |
GLUT_LUMINANCE | 窗口采用亮度颜色模型 |
此外还有其他模型,详细定义在glut.h。
该函数用于设置显示窗口左上点在显示屏幕上的位置,。参数(x,y)是基于显示屏幕左上角的值,即(x,y)的原点(0,0)是屏幕坐上角。x,y值是像素为单位。
该函数是用于设置显示窗口的大小,通常和视频分辨率有关,可以大于或者等于视频分辨率。
该函数用于创建一个显示窗口,窗口的名字为title。返回值为成窗口的标记符。
该函数用于注册一个用户自定义的渲染函数(用于绘图像的函数)display1;窗口触发了一个事件该函数被调用一次,如当窗口位置发生变化的时候该渲染函数windDisplay将会被调用执行一次。
该函数用于设置定时器,该函数只会触发一次定时器,如过需要重复触发定时器调用函数,需要重复调用该函数。。
millis:表示定时器时间,单位是毫秒;
func:定时器触发调用的函数,定时时间结束后定时器调用该函数;
value:通常是用于区分定时器的。
进入GLUT事件处理循环,只有调用了这个函数之后才能将图像绘制到窗口。
注意,该函数之后的语句不会被执行。(glutMainLoop前执行glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);可以规避该问题)
该函数的功能是交换两个缓冲区指针。
通常,需要glutInitDisplayMode函数中使用GLUT_DOUBLE,当glutInitDisplayMode函数中使用GLUT_SINGLE时候需要使用glFlush()来更新缓冲区数据。GLUT_DOUBLE采用两个缓冲区,当一个缓冲区在显示的时候,另一个缓冲区可以用于接收待显示的图像来存储,既可以提高高渲染的效率,也可以避免单缓冲画面闪烁问题。如下图是双缓存的数据流程。红色线是从双buff中取数据到OpenGL显示窗口,实线是当前从BUFF1中取数据到OpenGL显示窗口,虚线表示下一次从该buff(BUFF 0)中取数据。蓝色线是将输入图像放入到双缓冲的过程,实线是将图像数据放入当前BUFF 0缓冲区,虚线表示下次将输入图像数据放入到BUFF1缓冲区;输入的写入和读取是从BUFF0/1交替执行的,且读取和写入不会同时操作同一个BUFF。
用于设置光栅坐标,也即是窗口坐标中维护的三维位置。glRasterPos3f 用于移动实际渲染的画面在窗口中的位置。如下图原本处于窗口坐下角的图像可以经过glRasterPos3f(-0.5,-0.5,0);移动到屏幕中间。
该函数可以用于设置窗口size和图像size的比例。通常窗口大小和图像大小不相等,如窗口大小1280x720,图像大小为640x320,在不配置glPixelZoom 图像画面只会在窗口中占一部分面积。如下图:橙色画面占窗口白色画面的一部分。
通过glPixelZoom ();来条件画面和窗口的大小比例,可以让图像画面和窗口大小一致 ,如下图所示:
参数xfactor:为窗口宽度和图像宽的比值,为float类型,(winSizeW/ImgSizeW);
参数yfactor:为窗口高度和图像高的比值,为float类型,(winSizeH/ImgSizeH).
该函数用于绘制宽度为width,高为height的矩形图像,该矩形图像的左下坐标为光栅位置,即设置了光栅坐标该矩形图像的位置也会随之变化,这就是为什么glRasterPos3f 函数能够改变图像位置的原因。
参数width:图像的实际宽度;
参数height:图像的实际高度;
参数format:为图像格式,常用的图像格式有:
GL_BGR,GL_BGRA,GL_LUMINANCE等。
参数type:图像数据类型,即format指定的类中每一个颜色分量像素值的类型,主要有:
GL_UNSIGNED_BYTE:无符号的字节8位类型。
GL_BYTE:带符号的字节8位类型。
以及其他类型。
参数pixels:为输入图像数据地址,存储图像的有效地址。
glDrawPixels(640, 320, GL_BGR, GL_UNSIGNED_BYTE, vbuf);表示渲染的图像宽高为640、320,图像为RGB的数据,RGB每一个分量的数据是8bit。
void winDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
static int cnt = 0;//调用次数统计,当鼠标点击窗口移动一次当前函数会被调用一次,窗口背景色会发送变化
//(在GLUT_SINGLE模式下,GLUT_DOUBLE下双buf的存在两个buf的颜色可能不同会交替出现闪烁)
if (cnt < 1)
glColor4f(1, 0, 0, 1);//红色
else
glColor4f(0, 0, 1, 1);//蓝色
glRectf(-1, -1, 1, 1);
glFinish();
cnt++;
cnt = cnt > 1 ? 0 : cnt;
}
void imgDisplay(void) {
/*
*获取图像数据到vbuf
*/
glRasterPos3f(-1.0f, -1.0f, 0);//移动图像在窗口中的位置
//Zoom, Flip
glPixelZoom((float)screen_w / (float)width, (float)screen_h / height);//设置图像和窗口大小一样
glDrawPixels(width, height, GL_BGR, GL_UNSIGNED_BYTE, vbuf);//将待显示的图像数据拷贝到显示缓冲区。
//GLUT_DOUBLE
glutSwapBuffers();//双缓冲区的buff交换。
}
//定时器设置函数
void timerFunc(int value) {
imgDisplay();
glutTimerFunc(1, timerFunc, 0);
}
void *opengl_main(void * )
{
glutInit(argcp, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);//设置窗口的位置从显示屏幕100x100点的位置开始
glutInitWindowSize(1280, 720);//设置窗口的分辨率
glutCreateWindow("rtsp Video Play OpenGL");
glutDisplayFunc(&winDisplay);//注册自定义的窗口渲染函数
glutTimerFunc(1, timerFunc, 0);//设置定时器出发函数
glutMainLoop();
return NULL;
}