使用cv :: Mat在glTexImage2D()处出现异常

时间:2015-01-24 17:44:53

标签: c++ opencv opengl

我尝试将cv :: Mat加载到OGL纹理中。代码确实有效。然后我在另一个项目中尝试了相同的代码片段(加载纹理的地方)。从那时起它将不再起作用。

通过在glTexImage2D()调用上运行代码,我得到以下异常。

Unhandled exception at 0x518F4290 (atioglxx.dll) in InputFromCamWithOGL.exe: 0xC0000005: Access violation reading location 0x08A3FFFC.

这是代码:

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

cv::VideoCapture capture0;
cv::VideoCapture capture1;

void captureFromWebcam(cv::Mat &frame, cv::VideoCapture &capture)
{
    capture.read(frame);
}

bool initializeCapturing()
{
    capture0.open(0);
    capture1.open(1);

    if(!capture0.isOpened() | !capture1.isOpened())
    {
        std::cout << "Ein oder mehrere VideoCaptures konnten nicht geöffnet werden" << std::endl;

        if(!capture0.isOpened())
            capture0.release(); 
        if(!capture1.isOpened())
            capture1.release();
        return false;
    }

    return true;
}

void releaseCapturing()
{
    capture0.release();
    capture1.release();
}




int main ()
{
    int w = 800,h=600;

    glfwInit();

    //configure glfw 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);


    GLFWwindow* window = glfwCreateWindow(w, h, "OpenGL", NULL, nullptr); // windowed
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    glewInit();

    initializeCapturing();

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // An array of 3 vectors which represents 3 vertices (singular: vertex -> ein Punkt im dreidimensionalen raum)
    static const GLfloat g_vertex_buffer_data[] = {
        //x,y,z
       -1.0f, -1.0f, 0.0f, //unten links
       1.0f, -1.0f, 0.0f, //unten rechts
       0.0f,  1.0f, 0.0f, //mittig oben
    };

    // This will identify our vertex buffer
    GLuint vertexbuffer;

    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    glGenBuffers(1, &vertexbuffer);

    // The following commands will talk about our 'vertexbuffer' buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    // Give our vertices to OpenGL.
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);


    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);

    //was passiert wenn die texture koordinaten außerhalb des bereichs sind?
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    //was passiert wenn die textur gestreckt/gestaucht wird?
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    cv::Mat frame;
    captureFromWebcam(frame,capture0);
    //Thats the point where i get the exception
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,frame.size().width,frame.size().height,0,GL_RGBA,GL_UNSIGNED_BYTE,frame.data);

    while(!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
           0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
           3,                  // size
           GL_FLOAT,           // type
           GL_FALSE,           // normalized?
           0,                  // stride
           (void*)0            // array buffer offset
        );

        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

        glDisableVertexAttribArray(0);


        glfwSwapBuffers(window);
    }


    releaseCapturing();
    glfwTerminate();

    return 1;
}

但以下代码不会引发异常:

#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

cv::VideoCapture capture0;
cv::VideoCapture capture1;

void captureFromWebcam(cv::Mat &frame, cv::VideoCapture &capture)
{
    capture.read(frame);
}

bool initializeCapturing()
{
    capture0.open(0);
    capture1.open(1);

    if(!capture0.isOpened() | !capture1.isOpened())
    {
        std::cout << "Ein oder mehrere VideoCaptures konnten nicht geöffnet werden" << std::endl;

        if(!capture0.isOpened())
            capture0.release(); 
        if(!capture1.isOpened())
            capture1.release();
        return false;
    }

    return true;
}

void releaseCapturing()
{
    capture0.release();
    capture1.release();
}

int main ()
{
    initializeCapturing();
    GLuint tex;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);

        //was passiert wenn die texture koordinaten außerhalb des bereichs sind?
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        //was passiert wenn die textur gestreckt/gestaucht wird?
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        cv::Mat frame;
        captureFromWebcam(frame,capture0);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,frame.size().width,frame.size().height,0,GL_RGBA,GL_UNSIGNED_BYTE,frame.data);
    releaseCapturing();
    return 1;
}

我再也没有任何想法了。任何帮助将不胜感激。

--- --- UPDATE

由于第二个代码没有意义,我还有另一个可行的例子。我知道这是一些老式的代码,但我认为这不重要。

const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;

    int tex;

    int loadTexture(){
        cv::Mat frame;
        captureFromWebcam(frame,capture0);
        GLuint object;
        glGenTextures(1,&object);
        glBindTexture(GL_TEXTURE_2D,object);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,frame.size().width,frame.size().height,0,GL_RGBA,GL_UNSIGNED_BYTE,frame.data);
        return object;
    }
    void init(){
        glClearColor(0.0,0.0,0.0,0.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0.0,800,600,1.0,-1.0,1.0);
        glEnable(GL_BLEND);
        glEnable(GL_TEXTURE_2D);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        tex = loadTexture();
    }
    void draw(){
        glClear(GL_COLOR_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D,tex);
        glBegin(GL_QUADS);
            glTexCoord2f(0,0);
            glVertex2f(0,0);
            glTexCoord2f(1,0);
            glVertex2f(500,0);
            glTexCoord2f(1,1);
            glVertex2f(500,500);
            glTexCoord2f(0,1);
            glVertex2f(0,500);
        glEnd();
        glFlush();
    }

void showImage_online_sample()
{
        //initialisiere glfw
    glfwInit();

    //konfiguriere glfw (immer gleich)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    //die größe des Fensters ist nicht änderbar
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);


    //erzeuge ein Fenster
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, nullptr); // windowed

    //erzeuge den openGL context
    glfwMakeContextCurrent(window);

    //nötig. erlaubt die anpassung an unterschiedliche Systeme
    glewExperimental = GL_TRUE;
    glewInit();

    initializeCapturing();

        init();
        while(!glfwWindowShouldClose(window)){

            draw();
           glfwPollEvents();

        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);
           glfwSwapBuffers(window); 
        }
        glfwTerminate();
        releaseCapturing();
        return;

}

0 个答案:

没有答案