2016-05-08 2 views
1

Mein Computer läuft Ubuntu 16.04 und ist mit einer Nvidia GeForce GT 630M Grafikkarte mit einem proprietären Treiber installiert. Die glGetString(GL_VERSION) Funktion zeigt, dass meine Grafikkarte standardmäßig OpenGL 4.5 unterstützt.OpenGL-Programm wird nicht ordnungsgemäß ausgeführt, wenn eine explizite Version festgelegt ist

Ich verfolge die Learn OpenGL Tutorial-Serie und ich habe folgende Schwierigkeiten: Ich kann nur das „Hallo Dreieck“ Programm Tutorial erhalten ordnungsgemäß ausgeführt werden, wenn ich die Zeilen auf Kommentar

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

verlassen diese Zeilen als -is verhindert, dass das Dreieck erscheint.

Ich habe Probleme zu verstehen, warum Einstellung einer erforderlichen OpenGL-Version unteren als die OpenGL-Version, die meine Karte unterstützen kann, würde das Programm fehlschlagen.

EDIT: die Befehle

std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; 
std::cout << "Version: " << glGetString(GL_VERSION) << std::endl; 
std::cout << "Shading Language: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; 

Ausgang

Renderer: GeForce GT 630M/PCIe/SSE2 
Version: 4.5.0 NVIDIA 361.42 
Shading Language: 4.50 NVIDIA 

, wenn diese Linien werden auf Kommentar und

Renderer: GeForce GT 630M/PCIe/SSE2 
Version: 3.3.0 NVIDIA 361.42 
Shading Language: 3.30 NVIDIA via Cg compiler 

, wenn diese Linien werden an Ort und Stelle belassen.

EDIT2: Hier ist die eigentliche Quellcode:

#include <array> 
#include <fstream> 
#include <iostream> 
#include <sstream> 
#include <string> 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 

constexpr char FRAGMENT_SHADER_SOURCE_FILE[] = "simple_fragment.shader"; 
constexpr char VERTEX_SHADER_SOURCE_FILE[] = "simple_vertex.shader"; 

constexpr int WINDOW_WIDTH = 800; 
constexpr int WINDOW_HEIGHT = 800; 
constexpr char WINDOW_TITLE[] = "Triangle"; 

constexpr std::array<GLfloat, 4> bgColour { 0.3f, 0.1f, 0.3f, 1.0f }; 

/* 
* Instructs GLFW to close window if escape key is pressed. 
*/ 
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mode); 

int main() { 
    // Start GLFW. 
    if (not glfwInit()) { 
     std::cerr << "ERROR: Failed to start GLFW.\n"; 
     return 1; 
    } 

    // Set OpenGL version. 
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    // Create window and bind to current contex. 
    GLFWwindow *window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, nullptr, 
              nullptr); 
    if (not window) { 
     std::cerr << "ERROR: Failed to create GLFW window.\n"; 
     glfwTerminate(); 
     return 1; 
    } 
    glfwMakeContextCurrent(window); 

    // Set keyboard callback functions. 
    glfwSetKeyCallback(window, keyCallback); 

    // Initialize GLEW with experimental features turned on. 
    glewExperimental = GL_TRUE; 
    if (glewInit() != GLEW_OK) { 
     std::cerr << "ERROR: Failed to start GLEW.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Create viewport coordinate system. 
    int width, height; 
    glfwGetFramebufferSize(window, &width, &height); 
    glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height)); 

    // Create a vertex shader object. 
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 

    // Load the vertex shader source code. 
    std::string vertexShaderSource; 
    std::ifstream vsfs(VERTEX_SHADER_SOURCE_FILE); 
    if (vsfs.is_open()) { 
     std::stringstream ss; 
     ss << vsfs.rdbuf(); 
     vertexShaderSource = ss.str(); 
    } 
    else { 
     std::cerr << "ERROR: File " << VERTEX_SHADER_SOURCE_FILE << " could not be found.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Attach the shader source code to the vertex shader object and compile. 
    const char *vertexShaderSource_cstr = vertexShaderSource.c_str(); 
    glShaderSource(vertexShader, 1, &vertexShaderSource_cstr, nullptr); 
    glCompileShader(vertexShader); 

    // Check if compilation was successful. 
    GLint success; 
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 
    if (not success) { 
     std::cerr << "ERROR: Vertex shader compilation failed.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Create a fragment shader object. 
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 

    // Load the fragment shader source code. 
    std::string fragmentShaderSource; 
    std::ifstream fsfs(FRAGMENT_SHADER_SOURCE_FILE); 
    if (fsfs.is_open()) { 
     std::stringstream ss; 
     ss << fsfs.rdbuf(); 
     fragmentShaderSource = ss.str(); 
    } 
    else { 
     std::cerr << "ERROR: File " << FRAGMENT_SHADER_SOURCE_FILE << " could not be found.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Attach the shader source code to the fragment shader object and compile. 
    const char *fragmentShaderSource_cstr = fragmentShaderSource.c_str(); 
    glShaderSource(fragmentShader, 1, &fragmentShaderSource_cstr, nullptr); 
    glCompileShader(fragmentShader); 

    // Check if compilation was successful. 
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); 
    if (not success) { 
     std::cerr << "ERROR: Fragment shader compilation failed.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Create a shader program by linking the vertex and fragment shaders. 
    GLuint shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glLinkProgram(shaderProgram); 

    // Check that shader program was successfully linked. 
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); 
    if (not success) { 
     std::cerr << "ERROR: Shader program linking failed.\n"; 
     glfwTerminate(); 
     return 1; 
    } 

    // Delete shader objects. 
    glDeleteShader(vertexShader); 
    glDeleteShader(fragmentShader); 

    // Coordinates of triangle vertices in Normalized Device Coordinates (NDC). 
    std::array<GLfloat, 9> vertices { 
     -0.5f, -0.5f, 0.0f, 
     0.5f, -0.5f, 0.0f, 
     0.0f, 0.5f, 0.0f 
    }; 

    // Create a vertex array object. 
    GLuint vao; 
    glGenBuffers(1, &vao); 
    glBindVertexArray(vao); 

    // Create a vertex buffer object. 
    GLuint vbo; 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 

    // Pass vertex data into currently bound vertex buffer object. 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW); 

    // Create vertex attribute. 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), static_cast<GLvoid*>(0)); 
    glEnableVertexAttribArray(0); 

    // Unbind the vertex array object and vertex buffer object. 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

    glClearColor(bgColour[0], bgColour[1], bgColour[2], bgColour[3]); 

    while (not glfwWindowShouldClose(window)) { 
     glClear(GL_COLOR_BUFFER_BIT); 
     glfwPollEvents(); 

     // Inform OpenGL to use the shader program created above. 
     glUseProgram(shaderProgram); 

     // Bind the vertex array object. 
     glBindVertexArray(vao); 

     // Draw the triangle. 
     glDrawArrays(GL_TRIANGLES, 0, 3); 

     // Unbind the vertex array object. 
     glBindVertexArray(0); 

     glfwSwapBuffers(window); 
    } 

    // Delete vertex array object. 
    glDeleteVertexArrays(1, &vao); 

    // Delete vertex buffer object. 
    glDeleteBuffers(1, &vbo); 

    // Delete shader program. 
    glDeleteProgram(shaderProgram); 

    glfwDestroyWindow(window); 
    glfwTerminate(); 
    return 0; 
} 

void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mode) { 
    if (key == GLFW_KEY_ESCAPE and action == GLFW_PRESS) { 
     glfwSetWindowShouldClose(window, GL_TRUE); 
    } 
} 

Hier sind die Inhalte von simple_vertex.shader und simple_fragment.shader:

#version 330 core 

layout (location = 0) in vec3 position; 

void main() { 
    gl_Position = vec4(position.x, position.y, position.z, 1.0); 
} 

und

#version 330 core 

out vec4 color; 

void main() { 
    color = vec4(1.0f, 0.5f, 0.2f, 1.0f); 
} 
+0

Ich wette, dass das Problem nicht eine niedrigere Version setzt, sondern explizit ein _core_ Profil anfordert. – derhass

+0

@derhass Leider hat nur 'glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); '' 'nichts verändert. Interessanterweise wird GLFW nicht einmal starten, wenn ich * nur * diese Zeile habe, also gibt es vielleicht ein Problem mit dem Kernprofil. –

+0

@derhass Ich habe einige zusätzliche Informationen hinzugefügt, die hilfreich sein können. –

Antwort

3

ich einen Tippfehler in meinem Code gemacht .

Ich habe die Funktion glGenBuffers anstelle von glGenVertexArrays verwendet, um mein Vertex-Array-Objekt zu erstellen. Anscheinend akzeptiert Nvidia dies, wenn ich keine OpenGL-Version festlege. Ich finde es immer noch verwirrend, aber zumindest ist das Problem behoben.

+1

Es gibt einen Unterschied, dass es legal ist, eigene IDs für bestimmte Objekttypen im Kompatibilitätsprofil zu generieren, während sie durch die entsprechenden 'glGen *()' Aufrufe im Kernprofil erzeugt werden müssen. Dies gilt jedoch nicht für VAOs. Ich vermute, dass der NVIDIA-Treiber dies möglicherweise nicht korrekt im Kompatibilitätsprofil überprüft. –

Verwandte Themen