简体   繁体   中英

OpenCV Mat to OpenGL - error on glBindTexture()

I'm trying to convert an OpenCV cv::Mat image to an OpenGL texture (I need a GLuint that points to the texture). Here's the code I have so far, pieced together from numerous Google searches:

void otherFunction(cv::Mat tex_img) // tex_img is a loaded image
{
    GLuint* texID;
    cvMatToGlTex(tex_img, texID);

    // Operations on the texture here 
}

void cvMatToGlTex(cv::Mat tex_img, GLuint* texID) 
{
    glGenTextures(1, texID);
    // Crashes on the next line:
    glBindTexture(GL_TEXTURE_2D, *texID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_img.cols, tex_img.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, tex_img.ptr());

    return;
}

The crash happens when calling glBindTextures .

I tried a try-catch for all exceptions with catch (const std::exception& ex) and catch (...) , but it didn't seem to throw anything, just crash my program.

I apologize if I'm doing anything blatantly wrong, this has been my first experience with OpenGL, and it's still early days for me with C++. I've been stuck on this since yesterday. Do I have a fundamental misunderstanding of OpenGL textures? I'm open to a major reworking of the code if necessary. I'm running Ubuntu 16.04 if that changes anything.

OK, here's what's happening:

void otherFunction(cv::Mat tex_img)
{
    GLuint* texID; // You've created a pointer but not initialised it. It could be pointing
                   // to anywhere in memory.
    cvMatToGlTex(tex_img, texID); // You pass in the value of the GLuint*
}

void cvMatToGlTex(cv::Mat tex_img, GLuint* texID) 
{
    glGenTextures(1, texID); // OpenGL will dereference the pointer and write the
                // value of the new texture ID here. The pointer value you passed in is 
                // indeterminate because you didn't assign it to anything. 
                // Dereferencing a pointer pointing to memory that you don't own is 
                // undefined behaviour. The reason it's not crashing here is because I'll 
                // bet your compiler initialised the pointer value to null, and 
                // glGenTextures() checks if it's null before writing to it. 

    glBindTexture(GL_TEXTURE_2D, *texID); // Here you dereference an invalid pointer yourself. 
                            // It has a random value, probably null, and that's 
                            // why you get a crash

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_img.cols, tex_img.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, tex_img.ptr());

    return;
}

One way to fix this would be to allocate the pointer to a GLuint like:

GLuint* texID = new GLuint; // And pass it in

That will work for starters, but you should be careful about how you go about this. Anything allocated with new will have to be deleted with a call to delete or you'll leak memory. Smart pointers delete the object automatically once it goes out of scope.

You could also do this:

GLuint texID;
cvMatToGlTex(tex_img, &texID);

Remember though that the lifetime of GLuint texID is only within that function you declared it in, because it's a local variable. I'm not sure what better way to do this because I don't know what your program looks like, but at least that should make the crash go away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM