c++ - OpenCV Mat 到 OpenGL - glBindTexture() 错误

标签 c++ opencv opengl

我正在尝试将 OpenCV cv::Mat 图像转换为 OpenGL 纹理(我需要一个指向纹理的 GLuint)。到目前为止,这是我从大量 Google 搜索中拼凑而成的代码:

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;
}

崩溃发生在调用 glBindTextures 时。

我尝试用 catch (const std::exception& ex)catch (...) try catch 所有异常,但似乎没有抛出任何东西,让我的程序崩溃。

如果我做错了什么,我深表歉意,这是我第一次使用 OpenGL,对于我来说,使用 C++ 还为时尚早。从昨天开始我就一直坚持这个。我对 OpenGL 纹理有根本性的误解吗?如有必要,我愿意对代码进行重大修改。如果有任何改变,我正在运行 Ubuntu 16.04。

最佳答案

好的,这是正在发生的事情:

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;
}

解决这个问题的一种方法是将指针分配给 GLuint,例如:

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

这对于初学者来说是可行的,但您应该谨慎对待如何进行此操作。任何用 new 分配的东西都必须通过调用 delete 来删除,否则你会泄漏内存。一旦超出范围,智能指针会自动删除对象。

你也可以这样做:

GLuint texID;
cvMatToGlTex(tex_img, &texID);

请记住,GLuint texID 的生命周期仅在您声明它的那个函数内,因为它是一个局部变量。我不确定有什么更好的方法来做到这一点,因为我不知道你的程序是什么样子,但至少应该让崩溃消失。

关于c++ - OpenCV Mat 到 OpenGL - glBindTexture() 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48947629/

相关文章:

c++ - 顶帽过滤器运行时间

opencv - OpenCV的离散傅立叶变换的实际输出公式是什么?

c# - glsl VertexShader/FragmentShader 拒绝在 OpenTk c# 中编译

opengl - OpenGL 中两个纹理的幂

c++ - 如果我单击按钮,则调用 MFC 中的函数

c++ - 如何在 C/C++ 中执行 _mm256_maskstore_epi8()?

c++ - C/C++ 需要本地函数原型(prototype)吗?

visual-studio-2008 - 在 OpenCV 中转换为单 channel 图像

python - OpenCV Python OpenGL 纹理

c++ - 节拍器精度算法数学