2016-10-23 2 views
-1

Я пытаюсь изучить OpenGL в качестве студента. Я потратил много времени, пытаясь понять, почему это простое приложение не работает. Это пример нашего профессора. (Мы работаем в окнах с визуальной студией, но у меня нет выбора, кроме как использовать Linux дома, это не каприз). Вот программа, которую я написал (над окнами работает отлично) и просто показывает черные окна (он должен отображать треугольник).Простое приложение OpenGL

// 
// 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; 
} 

Вот шейдерные программы: shader.frag:

#version 300 es 
precision mediump float; 

in vec3 colour; 
out vec4 frag_colour; 

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

и 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); 
} 

и здесь команда используется для компиляции программы (я используя код визуальной студии):

{ 
    // 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" 
} 

Параметр args задан g ++. Если бы у меня была ошибка, у меня была бы точка, с которой нужно начинать, но я не знаю, что делать.

Вот результат команды glxinfo | grep OpenGL:

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

Отладочные справки требуют [mcve] согласно [help]. Ваш код не минимален. Пожалуйста, отредактируйте свой вопрос, чтобы убедиться, что ваш код минимален (только код, необходимый для воспроизведения вашей проблемы в вашем вопросе), Complete (пользователям не нужно ничего другого, чтобы воспроизвести вашу проблему) и Подтверждаемый (предоставленный код воспроизводит точная проблема, с которой вы сталкиваетесь). Поскольку это ваш вопрос вне темы для переполнения стека. Обратите внимание, что это также общая причина [downvote] (http://idownvotedyoubecause.com/so/TooMuchCode). –

+0

У вас нет конкретного конкретного вопроса о программировании. Вы можете получить больше преимуществ только от чтения [как отлаживать небольшие программы] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – StoryTeller

+2

вы запрашиваете opengl 4.1, но драйвер поддерживает только 3.3. Я не проверял внимательно, если вы на самом деле используете что-либо, требующее более новой версии. Но чтобы проверить, что пойдет не так, вы хотите использовать отладку или трассировку gl, чтобы увидеть, что вызовы opengl/glx терпят неудачу. Это поможет выяснить, что на самом деле является проблемой. –

ответ

0

Я хотел бы предложить, используя OpenGL/GLSL отладчик, чтобы посмотреть, что происходит. Прошло некоторое время, но я с большим успехом использовал glslDevil - он совместим с linux и может помочь вам обнаружить ошибку opengl, особенно неподдерживаемую функцию на вашем оборудовании/платформе.

Смежные вопросы