2013-01-09 82 views
1

我的程序編譯得很好,但是當我嘗試執行它時,我得到一個奇怪的錯誤。 我已經包含錯誤的圖片。 此外,我想提一提,這個源代碼是從這裏http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/Opengl 3.3 C++運行時錯誤'向量下標超出範圍'

錯誤的圖片發現了一個在線的openGL教程:

http://postimage.org/image/i6ernf8d7/

http://postimage.org/image/dvywy86xf/full/

這裏是我的源代碼:

片段着色器

#version 330 core 

// Ouput data 
out vec3 color; 

void main() 
{ 

    // Output color = red 
    color = vec3(1,0,0); 

} 

頂點着色器

#version 330 core 

// Input vertex data, different for all executions of this shader. 
layout(location = 0) in vec3 vertexPosition_modelspace; 

void main(){ 

    gl_Position.xyz = vertexPosition_modelspace; 
    gl_Position.w = 1.0; 

} 

shader.hpp

#include <stdio.h> 
#include <string> 
#include <vector> 
#include <fstream> 
#include <GL/glew.h> 

GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){ 

    // Create the shaders 
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); 
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 

    // Read the Vertex Shader code from the file 
    std::string VertexShaderCode; 
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); 
    if(VertexShaderStream.is_open()) 
    { 
     std::string Line = ""; 
     while(getline(VertexShaderStream, Line)) 
      VertexShaderCode += "\n" + Line; 
     VertexShaderStream.close(); 
    } 

    // Read the Fragment Shader code from the file 
    std::string FragmentShaderCode; 
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); 
    if(FragmentShaderStream.is_open()){ 
     std::string Line = ""; 
     while(getline(FragmentShaderStream, Line)) 
      FragmentShaderCode += "\n" + Line; 
     FragmentShaderStream.close(); 
    } 

    GLint Result = GL_FALSE; 
    int InfoLogLength; 

    // Compile Vertex Shader 
    printf("Compiling shader : %s\n", vertex_file_path); 
    char const * VertexSourcePointer = VertexShaderCode.c_str(); 
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); 
    glCompileShader(VertexShaderID); 

    // Check Vertex Shader 
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    std::vector<char> VertexShaderErrorMessage(InfoLogLength); 
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); 
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); 

    // Compile Fragment Shader 
    printf("Compiling shader : %s\n", fragment_file_path); 
    char const * FragmentSourcePointer = FragmentShaderCode.c_str(); 
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); 
    glCompileShader(FragmentShaderID); 

    // Check Fragment Shader 
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); 
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength); 
    glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); 
    fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); 

    // Link the program 
    fprintf(stdout, "Linking program\n"); 
    GLuint ProgramID = glCreateProgram(); 
    glAttachShader(ProgramID, VertexShaderID); 
    glAttachShader(ProgramID, FragmentShaderID); 
    glLinkProgram(ProgramID); 

    // Check the program 
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); 
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); 
    std::vector<char> ProgramErrorMessage(glm::max(InfoLogLength, int(1))); 
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); 
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); 

    glDeleteShader(VertexShaderID); 
    glDeleteShader(FragmentShaderID); 

    return ProgramID; 
} 

的main.cpp

#include <stdio.h> 
#include <stdlib.h> 

#include <GL/glew.h> 
#include <GL/glfw.h> 
#include <glm/glm.hpp> 
using namespace glm; 

#include <iostream> 
using namespace std; 

#include "shader.hpp" 

int main() 
{ 

    if(!glfwInit()) 
    { 
     fprintf(stderr, "Failed to initialize GLFW\n"); 
     return -1; 
    } 

    glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x antialiasing 
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // We want OpenGL 3.3 
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); 
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL 

    // Open a window and create its OpenGL context 
    if(!glfwOpenWindow(1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW)) 
    { 
     fprintf(stderr, "Failed to open GLFW window\n"); 
     glfwTerminate(); 
     return -1; 
    } 
    else 
    { 
     glfwSetWindowTitle("Tutorial 01"); 
    } 

    // Initialize GLEW 
    glewExperimental=true; // Needed in core profile 
    if (glewInit() != GLEW_OK) { 
     fprintf(stderr, "Failed to initialize GLEW\n"); 
     return -1; 
    } 



    glfwEnable(GLFW_STICKY_KEYS); 


    glClearColor(0.3f, 0.5f, 0.9f, 0.0f); 

    GLuint VertexArrayID; 
    glGenVertexArrays(1, &VertexArrayID); 
    glBindVertexArray(VertexArrayID); 

    // Create and compile our GLSL program from the shaders 
    GLuint programID = LoadShaders("vertex.shader", "fragment.shader"); 


    static const GLfloat g_vertex_buffer_data[] = { 
     -1.0f, -1.0f, 0.0f, 
     1.0f, -1.0f, 0.0f, 
     0.0f, 1.0f, 0.0f, 
    }; 

    GLuint vertexbuffer; 
    glGenBuffers(1, &vertexbuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 



    do{ 

     // Clear the screen 
     glClear(GL_COLOR_BUFFER_BIT); 

     // Use our shader 
     glUseProgram(programID); 

     // 1rst attribute buffer : vertices 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
     glVertexAttribPointer(
      0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
      3,     // size 
      GL_FLOAT,   // type 
      GL_FALSE,   // normalized? 
      0,     // stride 
      (void*)0   // array buffer offset 
     ); 

     // Draw the triangle ! 
     glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle 

     glDisableVertexAttribArray(0); 

     // Swap buffers 
     glfwSwapBuffers(); 

    } // Check if the ESC key was pressed or the window was closed 
    while(glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS && 
    glfwGetWindowParam(GLFW_OPENED)); 


    // Close OpenGL window and terminate GLFW 
    glfwTerminate(); 

    // Cleanup VBO 
    glDeleteBuffers(1, &vertexbuffer); 
    glDeleteVertexArrays(1, &VertexArrayID); 

    return 0; 
} 

我沒有與OpenGL和C++,因此任何意見,如果我錯過了很好的經驗有些東西將不勝感激。

回答

3

第47行的矢量索引超出範圍。在調試時檢查矢量的大小是否與預期一致。

考慮使用data()而不是取第一個元素的地址。

VertexShaderErrorMessage.data() 

代替

&VertexShaderErrorMessage[0] 

但是,如果向量是空的這不會解決你的問題。

+0

最近更新NVIDIA驅動程序後,我遇到了同樣的問題。完成上述操作並將VertexShaderErrorMessage.data()的等價物轉換爲GLchar *解決了我的問題。謝謝。 – henryprescott

+0

爲了避免轉換,考慮將vector更改爲包含GLchar,那麼對數據的調用將返回所需的類型。 – ChetS

相關問題