簡體   English   中英

C ++-glDrawElements()上的OpenGL崩潰

[英]C++ - OpenGL crash on glDrawElements()

因此,在我的程序中,我嘗試顯示許多紋理。 在我的代碼前面,我為紋理生成了VAO,為每個紋理生成了ibo(或索引緩沖區)。 但是,當我運行代碼時,它在glDrawElements()調用和nvoglv32.dll中崩潰。 我已經讀過nvidia驅動程序中的錯誤可能是導致該錯誤的原因,但我對此表示懷疑。 生成或綁定VAO或ibo時可能出了些問題,但我不知道在哪里。 這是發生錯誤的代碼部分:

for (int i = 0; i < NUM_TEXTURES; i++){

    glBindVertexArray(VAO_T[i]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[i]);
    glBindTexture(GL_TEXTURE_2D, texture[i]);

    //error here
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, BUFFER_OFFSET(0));//error right here

}

這是我在調試中運行時遇到的錯誤:

Comp465.exe中0x0263FE4A的未處理異常:0xC0000005:訪問沖突讀取位置0x00000000。

這是我生成VAO,ibo和紋理的代碼:

glGenVertexArrays(NUM_TEXTURES, VAO_T);
glGenBuffers(NUM_TEXTURES, VBO_T);
glGenBuffers(NUM_TEXTURES, ibo);
glGenTextures(NUM_TEXTURES, texture);

...

for (int i = 0; i < NUM_TEXTURES; i++){

    //Tel GL which VAO we are using
    glBindVertexArray(VAO_T[i]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[i]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[i]), indices[i], GL_STATIC_DRAW);

    //initialize a buffer object
    glEnableVertexAttribArray(VBO_T[i]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_T[i]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(point[i]) + sizeof(texCoords), NULL, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(point[i]), point[i]);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(point[i]), sizeof(texCoords), texCoords);

    GLuint vPosition = glGetAttribLocation(textureShader, "vPosition");
    glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(vPosition);

    GLuint vTexCoord = glGetAttribLocation(textureShader, "vTexCoord");
    glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(point[i])));
    glEnableVertexAttribArray(vTexCoord);

    //Get handles for the uniform structures in the texture shader program
    VP = glGetUniformLocation(textureShader, "ViewProjection");

    //Bind the texture that we want to use
    glBindTexture(GL_TEXTURE_2D, texture[i]);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    // set texture parameters
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    //Load texture
    texture[i] = loadRawTexture(texture[i], TEX_FILE_NAME[i], PixelSizes[i][0], PixelSizes[i][1]);
    if (texture[i] != 0) {
        printf("texture loaded \n");
    }
    else
        printf("Error loading texture \n");
}

該語句肯定看起來是錯誤的:

glEnableVertexAttribArray(VBO_T[i]);

glEnableVertexAttribArray()將屬性位置作為其參數,而不是緩沖區ID。 您實際上稍后會正確使用它:

GLuint vPosition = glGetAttribLocation(textureShader, "vPosition");
...
glEnableVertexAttribArray(vPosition);

GLuint vTexCoord = glGetAttribLocation(textureShader, "vTexCoord");
...
glEnableVertexAttribArray(vTexCoord);

因此,您應該能夠使用無效參數簡單地刪除該額外的調用。

除此之外,我還注意到了一些看起來有些微或至少可疑的東西:

  • 如果您使用的是基於代碼其余部分中顯示的內容的可編程管線,則以下調用毫無意義。 可以刪除。

     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
  • 這可能只是一個命名問題,但是textureShader必須是一個程序對象,即glCreateProgram()的返回值,而不是着色器對象。

  • 盡管沒有得出明確的結論,但我對此感到很不好,還有另外兩個類似的電話:

     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[i]), indices[i], GL_STATIC_DRAW); 

    如果indices[i]是一個數組,即聲明看起來像這樣:

     indices[NUM_TEXTURES][INDEX_COUNT]; 

    那沒關系 但是,如果indices[i]是指針,或在作為函數參數傳遞時退化為指針,則sizeof(indices[i])將是指針的大小。 您可能需要仔細檢查它是否給出了索引數組的實際大小。 其他類似情況也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM