我正在尝试将 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/