OpenGl - 纹理,帧缓冲更新

时间:2016-09-18 00:54:52

标签: c++ opencv opengl

我正在尝试使用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();

}

0 个答案:

没有答案