c++ - 仅通过从程序中删除 std::cout<<"hi"<<std::endl OpenGL 崩溃

标签 c++ opengl glut

我发现了一个非常神秘的问题,我在程序中注释掉了调试行和程序“segmentaion fault (core dumped)”。

我缩小了程序的范围并得出了这个。这是重现问题的完整代码:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <highgui.h>
#include <GL/glut.h>
#include <iostream>

int main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_DOUBLE);
  glutInitWindowSize(500, 281);
  (void) glutCreateWindow("Alpha Test");

  cv::Mat image = cv::imread("alphatest.png");
  int texWidth = image.cols;
  int texHeight = image.rows;
  GLuint texId;
  glGenTextures(1, &texId);
  glBindTexture(GL_TEXTURE_2D, texId);

  //std::cout << "hi" << std::endl;

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, image.ptr());
}

此程序在 glTexImage2D 处崩溃并显示错误消息:

zsh: segmentation fault (core dumped)  ./mystery

(该程序已被命名为mystery)

通过取消对 cout 行的注释,程序可以正常运行而不会出现错误以及消息“hi”。我想知道为什么我必须保留调试行?

这是 alphatest.png enter image description here

最佳答案

很可能您的图像行对齐不符合 OpenGL 读取图像的默认设置(4 字节行对齐)。这可能会导致 OpenGL 从未映射的页面读取,从而导致段错误。当执行可能创建页面分配的 iostream 输出时,与图像缓冲区相邻,以便此问题保持“隐藏”状态。

测试这个:

glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);  /* tightly packed*/
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); /* tightly packed*/
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);   /* tightly packed*/
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);   /* tightly aligned*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, image.ptr());

此外,如果您的图像是灰度图像,那么读取 GL_BGRA 格式将需要比 imread 交付更多的数据。您不应对这些参数进行硬编码,而应在 imread 返回时从图像文件中确定它们。

关于c++ - 仅通过从程序中删除 std::cout<<"hi"<<std::endl OpenGL 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38374616/

相关文章:

c++ - 为什么 GLUT_DEPTH 破坏了我旋转茶壶的渲染?

c++ - 如何以编程方式缓慢移动窗口,就好像用户正在做一样?

opengl - 当面片大小 > 4 时,曲面分割如何知道面中哪些顶点属于一起?

c++ - 将 WGL 与 GLUT 结合起来,以实现 Windows 7 OpenGL 下的形状。缺少 GLUT INIT?

opengl - 如何使这段代码在 Mesa3d 上工作?

opengl - 为什么 OpenGL 的 glDrawArrays() 在核心配置文件 3.2 下会因 GL_INVALID_OPERATION 而失败,但在 3.3 或 4.2 下却不会?

java - Java 和 Android 中的 GLUT 替代品?

c++ - 尽管有 cin.ignore(),但 Cin 没有等待输入

c++ - 字符串缓冲区如何导致恶意代码运行?

c++ - 从数字和 C++ 中的位掩码生成数字数组