2016-07-14 30 views
1

Ich habe sehr mysteriöse Problem gefunden, wo ich aus die Debug-Zeile habe ich in Programm und das Programm "Segmentaion Fehler (Core Dumped) ".OpenGL crash nur durch Entfernen von std :: cout << "hi" << std :: endl aus dem Programm

Ich habe das Programm eingegrenzt und komme dazu. Das ist der ganze Code, das Problem zu reproduzieren:

#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()); 
} 

Dieses Programmabsturz bei glTexImage2D mit Fehlermeldung:

zsh: segmentation fault (core dumped) ./mystery 

(Das Programm mit dem Namen Geheimnis wurde)

von uncommenting die cout Linie läuft das Programm ohne Fehler zusammen mit der Nachricht "hi". Ich frage mich, warum ich die Debug-Zeile behalten muss?

Und die alphatest.png enter image description here

+0

nach 'glut' inits sollten Sie einen gültigen OpenGL-Kontext erzeugen und' glew' Funktionszeiger initialisieren, indem Sie 'glewInit()' aufrufen, bevor Sie 'gl' aufrufen. – ampawd

+1

@ampawd: glTexImage2D ist eine Funktion aus alten Zeiten. Es gibt es seit OpenGL-1.0. Es erfordert ganz bestimmt nicht GLEW. – datenwolf

+0

@datenwolf yeah, aber bevor er einige moderne gl-Funktionen 'glGenTexture'' glBindTexture' aufruft, die '' glew''-Initialisierung benötigt, um korrekt zu arbeiten. – ampawd

Antwort

4

Wahrscheinlich Ihre Bildzeile Ausrichtung entspricht nicht Standardeinstellung, bei der OpenGL Bilder liest (4 Byte Zeile alignment). Dies kann dazu führen, dass OpenGL von einer nicht zugeordneten Seite liest und einen Segfault verursacht. Wenn diese Iostream-Ausgabe ausgeführt wird, kann eine Seitenzuordnung neben dem Bildpuffer erstellt werden, so dass dieses Problem "verborgen" bleibt.

-Test folgt aus:

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()); 

Außerdem, wenn Ihr Bild Graustufen ist, dann ein GL_BGRA Format lesen, werden mehr Daten erwarten als imread geliefert. Sie sollten diese Parameter nicht fest codieren, sondern sie aus der Bilddatei bestimmen, wenn das Ergebnis zurückkehrt.

+0

Es ist wahr! Mein Bild hat nur einen Kanal, daher ist das Lesen falsch. Und danke für Iostream Erklärung !! – 5argon