2014-03-04 62 views
2

我在linux機器上編譯this project。修復所有include和lib錯誤後,我得到一個核心轉儲錯誤。但如果我註釋掉initGLSL行,它運行良好。下面給出initGLSL函數。GLSL加載核心轉儲

void Viewer :: initGLSL(void) 
{ 
    shader.loadVertex("shaders/vertex.glsl"); 
    shader.loadFragment("shaders/fragment.glsl"); 
} 

vertex.glsl:

varying vec3 position; 
varying vec3 normal; 

void main() 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_FrontColor = gl_Color; 

    position = gl_Vertex.xyz; 
    normal = gl_Normal.xyz; 
} 

我不知道如何調試此程序。我該如何檢查這個錯誤是因爲GLSL還是加載函數?

---------------感謝您的評論------------

負載的功能:

void Shader::loadVertex(const char* filename) 
{ 
    load(GL_VERTEX_SHADER, filename, vertexShader); 
} 

void Shader::loadFragment(const char* filename) 
{ 
    load(GL_FRAGMENT_SHADER, filename, fragmentShader); 
} 


void Shader::load(GLenum shaderType, const char* filename, GLuint& shader) 
// read vertex shader from GLSL source file, compile, and attach to program 
{ 
    string source; 

    if(!readSource(filename, source)) 
    { 
     return; 
    } 

    if(program == 0) 
    { 
     program = glCreateProgram(); 
    } 

    if(shader != 0) 
    { 
     glDetachShader(program, shader); 
    } 

    shader = glCreateShader(shaderType); 
    const char* source_c_str = source.c_str(); 
    glShaderSource(shader, 1, &(source_c_str), NULL); 

    glCompileShader(shader); 
    GLint compileStatus; 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); 

    if(compileStatus == GL_TRUE) 
    { 
     glAttachShader(program, shader); 
     linked = false; 
    } 
    else 
    { 
     GLsizei maxLength = 0; 
     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); 

     if(maxLength > 0) 
     { 
     GLchar* infoLog = new char[ maxLength ]; 
     GLsizei length; 

     glGetShaderInfoLog(shader, maxLength, &length, infoLog); 

     cerr << "GLSL Error: " << infoLog << endl; 

     delete[] infoLog; 
     } 
    } 
} 

,當我試圖用gdb調試,我得到的消息:

(gdb) p (filename) 
$1 = 0x482e41 "shaders/vertex.glsl" 
(gdb) n 
77  if(program == 0) 
(gdb) n 
79   program = glCreateProgram(); 
(gdb) n 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000000000 in ??() 
+0

當應用程序不正常終止時,通常會得到一個核心轉儲 - 可能是由於訪問衝突或一些未捕獲的信號或由於C++中未處理的異常而中止。如果您的應用程序在着色器中崩潰,這很可能是由於當前驅動程序中的錯誤。 GLSL着色器中的語法錯誤應該永遠不會導致程序終止。 – thokra

+0

如果可以,請顯示'loadVertex(...)'的實現。我懷疑你沒有使用'glXGetProcAddress(...)'或適當的擴展文件庫加載適當的GLSL函數。一個調試器會立即告訴你,這是你需要在某個時候拾取的技能。由於產生這種崩潰是微不足道的,所以你不必學習任何精心製作的語法來使用'gdb';只有一兩個命令。 –

+0

@thokra語法錯誤和許多其他事情肯定可以(但同意,*應該*從不)導致程序終止。我從新的GL特性中收到了許多segfaults(在glCompileShader和glLinkProgram中),編寫代碼GLSL並不期望長循環,分支和展開大量代碼。這些顯然是驅動程序錯誤,但它們可能會發生。 – jozxyqk

回答

0

你有絕對調用shader.load*之前創建OpenGL上下文?

E.g.其中之一,如果你使用相應的庫:

glutInit 
glutCreateWindow 

glfwInit 
glfwCreateWindow 

SDL_init 
SDL_CreateWindow 
SDL_GL_CreateContext 

我沒有與這麼多的經驗,但有些GL功能在運行時不會默認情況下鏈接 - glCreateProgram創建後仍可能NULL上下文。我用GLEW爲我做這個(glewInit()),但是there are other ways

+0

actully,我使​​用glew,該項目本身不包含glew,但在我的平臺上,我發現許多函數只存在於glew.h,所以你的意思是我應該在glCreatProgram之前添加glewInit()? – tintin

+0

@tintin是的。 glew.h將提供一些聲明,但在運行時需要'glewInit'來鏈接函數指針。您也可以動態檢查'glCreateProgram == NULL'。 – jozxyqk

+0

我試過glewInit,它的工作,非常感謝 – tintin