我正在尝试使用OpenGL渲染在OpenCV上捕获的帧(imshow太慢),但是我无法使用每个新帧更新纹理。我知道我可以在OpenCV上使用GPU,但我只是不想重建它,我还认为在OpenGL上渲染它应该很容易。
以下是我正在研究的代码 - 它应该非常直接但我不知道我在哪里弄乱。
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#include "opencv2/opencv.hpp"
using namespace cv;
void render();
void initFrame();
void createTexture();
GLuint textureId;
GLuint fb;
int width = 400;
int height = 400;
VideoCapture cap;
int main(int argc, char **argv)
{
cap.set(CV_CAP_PROP_FRAME_WIDTH, width);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, height);
if(!cap.open(0))
exit(-1);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("Test");
glutDisplayFunc(render);
glutIdleFunc(glutPostRedisplay);
createTexture();
initFrame();
glutMainLoop();
return 0;
}
void createTexture()
{
//create texture id
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, //Type of texture
0, //pyramid level (for mip-mapping) - 0: top level
GL_RGB, //Internal color format to convert to
width, //Image width
height, //Image height
0, //border width in pix (either 1 or 0)
GL_RGB, //Input image format
GL_UNSIGNED_BYTE,// Image data type
0 // image data
);
/*
else if(mat.channels() == 4)
{
glTexImage2D(GL_TEXTURE_2D, //Type of texture
0, //pyramid level (for mip-mapping) - 0: top level
GL_RGBA, //Internal color format to convert to
width, //Image width
height, //Image height
0, //border width in pix (either 1 or 0)
GL_RGBA, //Input image format
GL_UNSIGNED_BYTE,// Image data type
0 // image data
);
}
*/
//free(imgPtr);
//glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
}
void initFrame()
{
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
}
void render()
{
Mat frame;
cap >> frame;
if(frame.empty())
exit(-1);
glTexSubImage2D(textureId,
0,
0,
0,
frame.cols,
frame.rows,
GL_RGB,
GL_UNSIGNED_BYTE,
frame.ptr()
);
glBindTexture(GL_TEXTURE_2D,0);
glFlush();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
glBindFramebuffer(GL_FRAMEBUFFER,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureId);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float cube[][2] = {
{-1, -1},
{ 1, -1},
{ 1, 1},
{-1, 1}
};
float textCor[][2] = {
{0,0},
{1,0},
{1,1},
{0,1}
};
unsigned int faces[] = {1,0,3,2};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 2*sizeof(float), &cube[0][0]);
glTexCoordPointer(2, GL_FLOAT, 2*sizeof(float), &textCor[0][0]);
glCullFace(GL_FRONT);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, faces);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
glFlush();
glutSwapBuffers();
}