2016-10-23 1 views
-1

Ich versuche OpenGL als Student zu lernen. Ich habe viel Zeit damit verbracht, herauszufinden, warum diese einfache Anwendung nicht funktioniert. Es ist ein Beispiel von unserem Professor gegeben. (Wir arbeiten in Windows mit Visual Studio, aber ich habe keine andere Wahl, als Linux zu Hause zu verwenden, es ist keine Laune). Hier ist das Programm, das ich geschrieben habe (On Windows funktioniert perfekt) und zeigt nur ein schwarzes Fenster (es soll ein Dreieck anzeigen).Einfache OpenGL-Anwendung

// 
// main.cpp 
// OpenGL_Shader_Example_step1 
// 
// Created by CGIS on 30/11/15. 
// Copyright © 2015 CGIS. All rights reserved. 
// 

#define GLEW_STATIC 

#include <iostream> 
#include "GL/glew.h" 
#include "GLFW/glfw3.h" 

#include <fstream> 
#include <sstream> 
#include <iostream> 
#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 

int glWindowWidth = 640; 
int glWindowHeight = 480; 
int retina_width, retina_height; 
GLFWwindow* glWindow = NULL; 

GLuint shaderProgram; 

GLfloat vertexCoordinates[] = { 
           0.0f, 0.5f, 0.0f, 
           0.5f, -0.5f, 0.0f, 
           -0.5f, -0.5f, 0.0f 
           }; 
GLuint verticesVBO; 
GLuint triangleVAO; 

void windowResizeCallback(GLFWwindow* window, int width, int height) 
{ 
    fprintf(stdout, "window resized to width: %d , and height: %d\n", width, height); 
    //TODO 
} 

void initObjects() 
{ 
    //generate a unique ID corresponding to the verticesVBO 
    glGenBuffers(1, &verticesVBO); 
    //bind the verticesVBO buffer to the GL_ARRAY_BUFFER target, 
    //any further buffer call made to GL_ARRAY_BUFFER will configure the 
    //currently bound buffer, which is verticesVBO 
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO); 
    //copy data into the currently bound buffer, the first argument specify 
    //the type of the buffer, the second argument specify the size (in bytes) of data, 
    //the third argument is the actual data we want to send, 
    //the last argument specify how should the graphic card manage the data 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoordinates), vertexCoordinates, GL_STATIC_DRAW); 

    //generate a unique ID corresponding to the triangleVAO 
    glGenVertexArrays(1, &triangleVAO); 
    glBindVertexArray(triangleVAO); 
    glBindBuffer(GL_ARRAY_BUFFER, verticesVBO); 
    //set the vertex attributes pointers 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
    glEnableVertexAttribArray(0); 
    //unbind the triangleVAO 
    glBindVertexArray(0); 
} 

bool initOpenGLWindow() 
{ 
    if (!glfwInit()) { 
     fprintf(stderr, "ERROR: could not start GLFW3\n"); 
     return false; 
    } 

    //for Mac OS X 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    glWindow = glfwCreateWindow(glWindowWidth, glWindowHeight, "OpenGL Shader Example", NULL, NULL); 
    if (!glWindow) { 
     fprintf(stderr, "ERROR: could not open window with GLFW3\n"); 
     glfwTerminate(); 
     return false; 
    } 

    glfwSetWindowSizeCallback(glWindow, windowResizeCallback); 
    glfwMakeContextCurrent(glWindow); 

    glfwWindowHint(GLFW_SAMPLES, 4); 

    // start GLEW extension handler 
    glewExperimental = GL_TRUE; 
    glewInit(); 

    // get version info 
    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string 
    const GLubyte* version = glGetString(GL_VERSION); // version as a string 
    printf("Renderer: %s\n", renderer); 
    printf("OpenGL version supported %s\n", version); 

    //for RETINA display 
    glfwGetFramebufferSize(glWindow, &retina_width, &retina_height); 

    return true;  
} 

void renderScene() 
{ 
    //clear the color and depth buffer before rendering the current frame 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    //specify the background color 
    glClearColor(0.8, 0.8, 0.8, 1.0); 
    //specify the viewport location and dimension 
    glViewport (0, 0, retina_width, retina_height); 

    //process the keyboard inputs 
    if (glfwGetKey(glWindow, GLFW_KEY_A)) { 
    //TODO 
    } 

    if (glfwGetKey(glWindow, GLFW_KEY_D)) { 
    //TODO 
    } 

    //bind the shader program, any further rendering call 
    //will use this shader program 
    glUseProgram(shaderProgram); 

    //bind the VAO 
    glBindVertexArray(triangleVAO); 
    //specify the type of primitive, the starting index and 
    //the number of indices to be rendered 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
} 

std::string readShaderFile(std::string fileName) 
{ 
    std::ifstream shaderFile; 
    std::string shaderString; 

    //open shader file 
    shaderFile.open(fileName.c_str()); 

    std::stringstream shaderStringStream; 

    //read shader content into stream 
    shaderStringStream << shaderFile.rdbuf(); 

    //close shader file 
    shaderFile.close(); 

    //convert stream into GLchar array 
    shaderString = shaderStringStream.str(); 
    return shaderString; 
} 

void shaderCompileLog(GLuint shaderId) 
{ 
    GLint success; 
    GLchar infoLog[512]; 

    //check compilation info 
    glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); 
    if (!success) 
    { 
     glGetShaderInfoLog(shaderId, 512, NULL, infoLog); 
     std::cout << "Shader compilation error\n" << infoLog << std::endl; 
    } 
} 

void shaderLinkLog(GLuint shaderProgramId) 
{ 
    GLint success; 
    GLchar infoLog[512]; 

    //check linking info 
    glGetProgramiv(shaderProgramId, GL_LINK_STATUS, &success); 
    if (!success) { 
     glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); 
     std::cout << "Shader linking error\n" << infoLog << std::endl; 
    } 
} 

GLuint initBasicShader(std::string vertexShaderFileName, std::string fragmentShaderFileName) 
{ 
    //read, parse and compile the vertex shader 
std::string v = readShaderFile(vertexShaderFileName); 
const GLchar* vertexShaderString = v.c_str(); 
GLuint vertexShader; 
vertexShader = glCreateShader(GL_VERTEX_SHADER); 
glShaderSource(vertexShader, 1, &vertexShaderString, NULL); 
glCompileShader(vertexShader); 
//check compilation status 
shaderCompileLog(vertexShader); 

//read, parse and compile the vertex shader 
std::string f = readShaderFile(fragmentShaderFileName); 
const GLchar* fragmentShaderString = f.c_str(); 
GLuint fragmentShader; 
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
glShaderSource(fragmentShader, 1, &fragmentShaderString, NULL); 
glCompileShader(fragmentShader); 
//check compilation status 
shaderCompileLog(fragmentShader); 

//attach and link the shader programs 
shaderProgram = glCreateProgram(); 
glAttachShader(shaderProgram, vertexShader); 
glAttachShader(shaderProgram, fragmentShader); 
glLinkProgram(shaderProgram); 
glDeleteShader(vertexShader); 
glDeleteShader(fragmentShader); 
//check linking info 
shaderLinkLog(shaderProgram); 

return shaderProgram; 
} 

int main(int argc, const char * argv[]) 
{ 
    initOpenGLWindow(); 

    initObjects(); 

    shaderProgram = initBasicShader("shaders/shader.vert", "shaders/shader.frag"); 

    while (!glfwWindowShouldClose(glWindow)) { 
     renderScene(); 

     glfwPollEvents(); 
     glfwSwapBuffers(glWindow); 
    } 

    //close GL context and any other GLFW resources 
    glfwTerminate(); 

    return 0; 
} 

Hier sind die Shader-Programme: shader.frag:

#version 300 es 
precision mediump float; 

in vec3 colour; 
out vec4 frag_colour; 

void main() { 
    frag_colour = vec4 (colour, 1.0); 
} 

und shader.vert:

#version 300 es 

layout (location = 0) in vec3 vertex_position; 

out vec3 colour; 

void main() { 
    colour = vec3(1.0, 0.0, 0.0); 
    gl_Position = vec4(vertex_position, 1.0); 
} 

und hier wird der Befehl verwendet, um das Programm zu kompilieren (ich bin unter Verwendung des visuellen Studiokodes):

{ 
    // See https://go.microsoft.com/fwlink/?LinkId=733558 
    // for the documentation about the tasks.json format 
    "version": "0.1.0", 
    "command": "g++", 
    "isShellCommand": true, 
    "args": ["-g", 
      "-Wall", 
      "-o", "lab2.exe", 
      "main.cpp", 
      "-I/usr/include/c++/4.8.5", 
      "-I/usr/include/GL", 
      "-I/usr/include/glm", 
      "-I/usr/local/include/GLFW", 
      "-L/usr/local/lib", "-lGLEW", "-lGLU", "-lglfw3", "-lGL", "-lm", "-ldl", "-lXrender", "-ldrm", 
      "-lXdamage", "-lX11-xcb", "-lxcb-glx", "-lxcb-dri2", "-lxcb-dri3", "-lxcb-present", "-lxcb-sync", "-lxshmfence", "-lXxf86vm", 
      "-lXfixes", "-lXext", "-lX11", "-lpthread", "-lxcb", "-lXau", "-lXdmcp", 
      "-lXrandr", "-lXi", "-lXxf86vm", "-lXcursor"], 
    "showOutput": "always" 
} 

Der args-Parameter wird an g ++ übergeben. Wenn ich einen Fehler hätte, hätte ich einen Punkt, von dem aus ich anfangen kann, aber ich weiß nicht, was ich tun soll. Hier

ist das Ergebnis des glxinfo | grep OpenGL Befehls:

OpenGL vendor string: Intel Open Source Technology Center 
OpenGL renderer string: Mesa DRI Intel(R) Haswell Mobile 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.2.0 
OpenGL core profile shading language version string: 3.30 
OpenGL core profile context flags: (none) 
OpenGL core profile profile mask: core profile 
OpenGL core profile extensions: 
OpenGL version string: 3.0 Mesa 11.2.0 
OpenGL shading language version string: 1.30 
OpenGL context flags: (none) 
OpenGL extensions: 
+1

Debugging-Hilfe Fragen erfordern eine [mcve] wie in der [Hilfe]. Dein Code ist nicht minimal. Bitte bearbeiten Sie Ihre Frage, um sicherzustellen, dass Ihr Code Minimal ist (nur der Code, der für die Reproduktion Ihres Problems in Ihrer Frage benötigt wird), Vollständig (Benutzer brauchen nichts anderes, um Ihr Problem zu reproduzieren) und Verifizierbar (der mitgelieferte Code reproduziert) das genaue Problem, dem Sie gegenüberstehen). Wie es Ihre Frage ist, ist Off-Topic für Stack Overflow. Beachten Sie, dass dies auch ein häufiger Grund ist (http://idownvotedyoubecause.com/so/TooMuchCode). –

+0

Sie scheinen keine konkrete konkrete Frage zur Programmierung zu haben. Sie könnten mehr davon profitieren, wenn Sie nur lesen, wie kleine Programme zu debuggen sind (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – StoryTeller

+2

Sie fragen nach OpenGL 4.1 aber Treiber unterstützt nur 3.3. Ich habe nicht sorgfältig geprüft, ob Sie tatsächlich etwas verwenden, das die neuere Version benötigt. Aber um zu überprüfen, was schief läuft, wollen Sie gl Debugging oder Tracing verwenden, um zu sehen, was opengl/glx-Aufrufe scheitern. Das wird helfen herauszufinden, was das Problem eigentlich ist. –

Antwort

0

Ich würde vorschlagen, mit einem OpenGL/GLSL-Debugger, um zu sehen, was los ist. Es ist schon eine Weile her, aber ich hatte viel Erfolg damit, glslDevil vorher zu verwenden - es ist Linux-kompatibel und kann Ihnen helfen, einen OpenGL-Fehler zu entdecken - insbesondere eine nicht unterstützte Funktion auf Ihrer Hardware/Plattform.