2014-01-12 30 views
2

我正在使用Marmalade C++和Open GL ES 2.0。有一些教程,我通過工作,我不斷收到同樣的錯誤:在調用glGetShaderInfoEXC_BAD_ACCESS glGetShaderInfoLog - 如何繼續?

EXC_BAD_ACCESS()

這裏是我的代碼。我該如何處理這種情況?

static int eglInit() 
{ 
    if (!IwGLInit()) 
    { 
     s3eDebugErrorShow(S3E_MESSAGE_CONTINUE, "eglInit failed"); 
     return 1; 
    } 
    return 0; 
} 

const char* vShaderStr = 
    "attribute vec4 vPosition;\n" 
    "void main()\n" 
    "{\n" 
    "gl_Position = vPosition;\n" 
    "};\n"; 

const char* fShaderStr = 
    "precision mediump float;\n" 
    "void main()\n" 
    "{\n" 
    "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 
    "}\n"; 

GLuint LoadShader(GLenum type, const char *shaderSrc) 
{ 
    GLuint shader; 
    GLint compiled; 

    // Create the shader object 
    shader = glCreateShader(type); 

    if (shader == 0) 
     return 0; 

    // Load the shader source 
    glShaderSource(shader, 1, &shaderSrc, NULL); 

    // Compile the shader 
    glCompileShader(shader); 

    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 

    if (!compiled) 
    { 
     GLint infoLen = 0; 
     glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 
     if (infoLen > 1) 
     { 
      char* infoLog = (char*)malloc(sizeof(char) * infoLen); 

      glGetShaderInfoLog(shader, infoLen, NULL, infoLog); 
      printf("Error compiling shader:\n%s\n", infoLog); 

      free(infoLog); 
     } 

     glDeleteShader(shader); 
     return 0; 
    } 

    return shader; 
} 

int main() 
{ 
    if (eglInit()) 
     return 1; 
    printf("Screen BPP: %d\n", s3eSurfaceGetInt(S3E_SURFACE_PIXEL_TYPE) & S3E_SURFACE_PIXEL_SIZE_MASK); 
    printf("\n"); 
    printf("Vendor  : %s\n", (char*)glGetString(GL_VENDOR)); 
    printf("Renderer : %s\n", (char*)glGetString(GL_RENDERER)); 
    printf("Version : %s\n", (char*)glGetString(GL_VERSION)); 
    printf("Extensions : %s\n", (char*)glGetString(GL_EXTENSIONS)); 
    printf("\n"); 

    GLuint vertexShader; 
    vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); 

    bool quit = false; 
    int numFrames = 0; 
    while (!quit) { 
     s3eKeyboardUpdate(); 
     s3eDeviceYield(0); 
     if (s3eDeviceCheckQuitRequest()) 
      quit = 1; 
     if (s3eKeyboardGetState(s3eKeyEsc) & S3E_KEY_STATE_PRESSED) 
      quit = 1; 
     numFrames++; 
    } 
    //Shutdown GL system 
    IwGLTerminate(); 
    return 0; 
} 

回答

1

在:

glGetShaderInfoLog(shader, infoLen, NULL, infoLog); 

你傳遞一個NULL作爲第三個參數,它應該接受一個GLsizei*來代替。此參數(第三個)is populated具有信息日誌的實際長度,因此應該是有效的指針。

爲了解決這個問題,你可以這樣做:

GLsizei info_length = 0; 
glGetShaderInfoLog(shader, infoLen, &info_length, infoLog); 
+0

@icktoofay號的for'infoLen'返回值:「在信息的字符數日誌着色器包括空終止字符」 ([參考](http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderiv.xml))。 – Shoe

+0

太棒了,這個工程。謝謝。我想知道爲什麼我閱讀的所有這些書籍和教程都爲該值提供了一個NULL值。我檢查了文檔,並且如你所說NULL沒有意義放在那裏。 –

+1

@SeanBollin:因爲它不是必需的,所以如果你通過'NULL',一個兼容的OpenGL/ES實現應該忽略它。顯然你的不兼容: - \此外,你真的應該使用'infoLen - 1'作爲着色器的長度。當你調用glGetShaderiv(着色器,GL_INFO_LOG_LENGTH和infoLen)時,你得到了什麼;'是字符串的長度(包括NULL終止符)。您只爲'infoLen - 1'字符分配了足夠的存儲空間,因爲您需要爲NULL終止符添加一個額外的字節。 –