Skip to content

Instantly share code, notes, and snippets.

@shuj1
Forked from royshil/OGL_OCV_common.cpp
Created June 22, 2017 08:01
Show Gist options
  • Select an option

  • Save shuj1/5533e059f687c23bc50cfa9e261beaf2 to your computer and use it in GitHub Desktop.

Select an option

Save shuj1/5533e059f687c23bc50cfa9e261beaf2 to your computer and use it in GitHub Desktop.

Revisions

  1. @royshil royshil created this gist Feb 16, 2015.
    198 changes: 198 additions & 0 deletions OGL_OCV_common.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,198 @@
    /*
    * OGL_OCV_common.cpp
    * Common interop between OpenCV and OpenGL
    *
    * Created by Roy Shilkrot on 2/16/2015
    * Copyright 2015 Roy Shilkrot. All rights reserved.
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    * THE SOFTWARE.
    *
    */

    #include "OGL_OCV_common.hpp"

    namespace RS {

    void drawOpenCVImageInGLOnlyQuad(const OpenCVGLTexture& tex, int width, int height) {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex.tex_id);

    double ithr = tex.thr, itwr = tex.twr;
    double n[3] = {0,0,-1};

    glBegin(GL_QUADS);

    glNormal3dv(n);
    glTexCoord2d(0, 0);
    glVertex2d (0, 0);

    glTexCoord2d(0, ithr);
    glVertex2d (0, height);

    glTexCoord2d(itwr, ithr);
    glVertex2d (width, height);

    glTexCoord2d(itwr, 0);
    glVertex2d (width, 0);

    glEnd();
    }

    void drawOpenCVImageInGLFullViewport(const OpenCVGLTexture& tex) {
    glDisable(GL_LIGHTING);
    glDisable(GL_BLEND);

    int vPort[4]; glGetIntegerv(GL_VIEWPORT, vPort);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex.tex_id);
    glPushMatrix();
    glColor3ub(255, 255, 255);

    glScaled(vPort[3], vPort[3], 1);

    double aw2h = tex.aspect_w2h, ithr = tex.thr, itwr = tex.twr;
    double n[3] = {0,0,-1};

    GLint face_ori; glGetIntegerv(GL_FRONT_FACE, &face_ori);
    glFrontFace(GL_CW); //we're gonna draw clockwise

    glBegin(GL_QUADS);

    glNormal3dv(n);
    glTexCoord2d(0, 0);
    glVertex2d (0, 0);

    glTexCoord2d(0, ithr);
    glVertex2d (0, 1);

    glTexCoord2d(itwr, ithr);
    glVertex2d (aw2h, 1);

    glTexCoord2d(itwr, 0);
    glVertex2d (aw2h, 0);

    glEnd();
    glPopMatrix();

    glFrontFace(face_ori); //restore front face orientation

    glDisable(GL_TEXTURE_2D);
    glEnable(GL_LIGHTING);
    glEnable(GL_BLEND);
    }

    void glEnable2D()
    {
    glPushAttrib(GL_ENABLE_BIT);
    glPushAttrib(GL_CURRENT_BIT);

    int vPort[4];
    glGetIntegerv(GL_VIEWPORT, vPort);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, vPort[2], 0, vPort[3], -1, 4);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslated(0.375, 0.375, 0);

    // glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // clear the screen

    // glDisable(GL_DEPTH_TEST);
    }

    void glEnable2D(int w,int h, int x, int y) {
    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(x, y, w, h);

    RS::glEnable2D();

    glScaled(w, h, 1);
    }

    void glDisable2D()
    {
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    // glEnable(GL_DEPTH_TEST);

    glPopAttrib();
    glPopAttrib();

    }

    void glDisable2Dvp() {
    glDisable2D();
    glPopAttrib();
    }


    #if defined(WIN32)
    #define log2(x) log10((double)(x))/log10(2.0)
    #endif

    Mat copyImgToTex(const Mat& _tex_img, GLuint* texID, double* _twr, double* _thr) {
    Mat tex_img = _tex_img;
    flip(_tex_img,tex_img,0);
    Mat tex_pow2(pow(2.0,ceil(log2(tex_img.rows))),pow(2.0,ceil(log2(tex_img.cols))),CV_8UC3);
    // std::cout << "original image size " << tex_img.size() << std::endl;
    // std::cout << "adjusted to OpenGL texture: " << tex_pow2.size() << std::endl;
    Mat region = tex_pow2(Rect(0,0,tex_img.cols,tex_img.rows));
    if (tex_img.type() == region.type()) {
    tex_img.copyTo(region);
    } else if (tex_img.type() == CV_8UC1) {
    cvtColor(tex_img, region, CV_GRAY2BGR);
    } else {
    tex_img.convertTo(region, CV_8UC3, 255.0);
    }

    if (_twr != 0 && _thr != 0) {
    *_twr = (double)tex_img.cols/(double)tex_pow2.cols;
    *_thr = (double)tex_img.rows/(double)tex_pow2.rows;
    }
    glBindTexture( GL_TEXTURE_2D, *texID );
    glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_pow2.cols, tex_pow2.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, tex_pow2.data);
    return tex_pow2;
    }

    OpenCVGLTexture MakeOpenCVGLTexture(const Mat& _tex_img) {
    OpenCVGLTexture _ocvgl;

    glGenTextures( 1, &_ocvgl.tex_id );
    glBindTexture( GL_TEXTURE_2D, _ocvgl.tex_id );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    if (!_tex_img.empty()) { //image may be dummy, just to generate pointer to texture object in GL
    copyImgToTex(_tex_img,&_ocvgl.tex_id,&_ocvgl.twr,&_ocvgl.thr);
    _ocvgl.aspect_w2h = (double)_tex_img.cols/(double)_tex_img.rows;
    }

    return _ocvgl;
    }

    }
    90 changes: 90 additions & 0 deletions OGL_OCV_common.hpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    /*
    * OGL_OCV_common.h
    * Common interop between OpenCV and OpenGL
    *
    * Created by Roy Shilkrot on 2/16/2015
    * Copyright 2015 Roy Shilkrot. All rights reserved.
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    * THE SOFTWARE.
    *
    */
    #pragma once

    #include <opencv2/opencv.hpp>

    using namespace cv;

    #if defined(__APPLE__)
    # include <OpenGL/gl.h>
    #elif defined(__linux__) || defined(__MINGW32__) || defined(WIN32)
    # define GLEW_STATIC
    //# include <GL/glew.h>
    //# include <GL/wglew.h>
    # include <GL/gl.h>
    # include <GL/glu.h>
    //# include <GL/glext.h>
    #else
    # include <gl.h>
    #endif

    namespace RS {

    Mat copyImgToTex(const Mat& _tex_img, GLuint* texID, double* _twr, double* _thr);

    typedef struct my_texture {
    GLuint tex_id;
    double twr,thr,aspect_w2h;
    Mat image,tex_pow2;
    my_texture():tex_id(-1),twr(1.0),thr(1.0) {}
    bool initialized;
    void set(const Mat& ocvimg) {
    if(tex_pow2.empty()) {
    ocvimg.copyTo(image);
    copyImgToTex(image, &tex_id, &twr, &thr);
    aspect_w2h = (double)ocvimg.cols/(double)ocvimg.rows;
    } else {
    Mat region = tex_pow2(Rect(0,0,ocvimg.cols,ocvimg.rows));
    if (ocvimg.type() == region.type()) {
    flip(ocvimg,region,0);
    } else {
    if (ocvimg.type() == CV_8UC1) {
    cvtColor(ocvimg, region, CV_GRAY2BGR);
    } else {
    ocvimg.convertTo(region, CV_8UC3, 255.0);
    }
    flip(region,region,0);
    }

    glBindTexture( GL_TEXTURE_2D, tex_id );
    glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_pow2.cols, tex_pow2.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, tex_pow2.data);
    }
    }
    } OpenCVGLTexture;

    void glEnable2D(); // setup 2D drawing
    void glEnable2D(int w,int h, int x, int y); // setup 2D drawing with viewport & postion setting
    void glDisable2D(); // end 2D drawing
    void glDisable2Dvp(); // end 2D drawing and pop viewport attrib
    OpenCVGLTexture MakeOpenCVGLTexture(const Mat& _tex_img); // create an OpenCV-OpenGL image

    // draw an OpenCV-OpenGL image
    void drawOpenCVImageInGLOnlyQuad(const OpenCVGLTexture& tex, int width, int height);
    void drawOpenCVImageInGLFullViewport(const OpenCVGLTexture& tex);

    }