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);
}
Ich wette, dass das Problem nicht eine niedrigere Version setzt, sondern explizit ein _core_ Profil anfordert. – derhass
@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. –
@derhass Ich habe einige zusätzliche Informationen hinzugefügt, die hilfreich sein können. –