2017-10-09 4 views
0

Ci-dessous j'ai inclus glfw-quick-test.c, qui est essentiellement copié mot pour mot de http://www.glfw.org/docs/latest/quick.html - sauf pour un usage retiré de glad, couleur de fond ajouté, deux des defines il compile sur Ubuntu 14.04 (64 bits), et un commutateur de préprocesseur #ifdef (macro DO_OPENGL_THREE) pour modifier la version OpenGL demandée.glfw3 ne dessine pas si OpenGL 3+ est demandé?


Quand je compilez avec:

gcc -g -o glfw-quick-test.exe glfw-quick-test.c -lglfw -lGLU -lGL -lm 
./glfw-quick-test.exe 

... alors je reçois le message "GLFW Requesting OpenGL 2.1" et le dessin est très bien:

glfw3A


Quand je compile avec:

gcc -g -DDO_OPENGL_THREE -o glfw-quick-test.exe glfw-quick-test.c -lglfw -lGLU -lGL -lm 
./glfw-quick-test.exe 

... alors je reçois le message « GLFW Requesting OpenGL 3.2 » et le triangle de rotation n'est pas tiré du tout - que la couleur de fond est préservée:

glfw3B


Quelqu'un peut-il expliquer pourquoi le fait cela arrive? Puis-je en quelque sorte obtenir GLFW3 pour dessiner même si OpenGL 3.2 est demandé, et si oui, comment?

(Je sais que le code source d'origine dit "// NOTE: OpenGL error checks have been omitted for brevity", mais je ne suis pas sûr du type de vérification d'erreur que je devrais ajouter, pour voir quel serait le problème avec le dessin OpenGL 3.2 ...)

Le code, glfw-quick-test.c (EDIT: maintenant avec vérification d'erreur):

// http://www.glfw.org/docs/latest/quick.html 

#define UBUNTU14 
#ifdef UBUNTU14 // assume Ubuntu 14.04 
// strange; Ubuntu 14 GLFW/glfw3.h doesn't have GLFW_TRUE, GLFW_FALSE, mentions GL_TRUE GL_FALSE 
#define GLFW_TRUE GL_TRUE 
#define GLFW_FALSE GL_FALSE 
#endif 

//~ #include <glad/glad.h> // "GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs." 
#include <GLFW/glfw3.h> 
#include "linmath.h" 
#include <stdlib.h> 
#include <stdio.h> 
static const struct 
{ 
    float x, y; 
    float r, g, b; 
} vertices[3] = 
{ 
    { -0.6f, -0.4f, 1.f, 0.f, 0.f }, 
    { 0.6f, -0.4f, 0.f, 1.f, 0.f }, 
    { 0.f, 0.6f, 0.f, 0.f, 1.f } 
}; 
static const char* vertex_shader_text = 
"uniform mat4 MVP;\n" 
"attribute vec3 vCol;\n" 
"attribute vec2 vPos;\n" 
"varying vec3 color;\n" 
"void main()\n" 
"{\n" 
" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" 
" color = vCol;\n" 
"}\n"; 
static const char* fragment_shader_text = 
"varying vec3 color;\n" 
"void main()\n" 
"{\n" 
" gl_FragColor = vec4(color, 1.0);\n" 
"}\n"; 
static void error_callback(int error, const char* description) 
{ 
    fprintf(stderr, "Error: %s\n", description); 
} 
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 
{ 
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
    glfwSetWindowShouldClose(window, GLFW_TRUE); 
} 
void checkGLerrors(char *label) { 
    // check OpenGL error 
    GLenum err; 
    while ((err = glGetError()) != GL_NO_ERROR) { 
    char* errorstr = ""; 
    switch(err) { 
     case GL_INVALID_OPERATION: errorstr="INVALID_OPERATION"; break; 
     case GL_INVALID_ENUM:  errorstr="INVALID_ENUM";  break; 
     case GL_INVALID_VALUE:  errorstr="INVALID_VALUE"; break; 
     case GL_OUT_OF_MEMORY:  errorstr="OUT_OF_MEMORY"; break; 
     case GL_INVALID_FRAMEBUFFER_OPERATION: errorstr="INVALID_FRAMEBUFFER_OPERATION"; break; 
    } 
    printf("OpenGL error ('%s'): %d %s\n", label, err, errorstr); 
    } 
} 

int main(void) 
{ 
    GLFWwindow* window; 
    GLuint vertex_buffer, vertex_shader, fragment_shader, program; 
    GLint mvp_location, vpos_location, vcol_location; 
    glfwSetErrorCallback(error_callback); 
    if (!glfwInit()) 
    exit(EXIT_FAILURE); 
    // NB: Ubuntu will not draw if 3.2 (just black screen) - only if 2.0 or 2.1? 
    #ifdef DO_OPENGL_THREE 
    printf("GLFW Requesting OpenGL 3.2\n"); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // only 3.2+ 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); //only 3.0+ 
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // https://stackoverflow.com/q/23834680/ 
    #else 
    printf("GLFW Requesting OpenGL 2.1\n"); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // 2); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // 0); 
    #endif 
    checkGLerrors("post hint"); 
    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL); 
    if (!window) 
    { 
    glfwTerminate(); 
    exit(EXIT_FAILURE); 
    } 
    checkGLerrors("post glfwCreateWindow"); 
    glfwSetKeyCallback(window, key_callback); 
    glfwMakeContextCurrent(window); 
    //~ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); 
    glfwSwapInterval(1); 
    // NOTE: OpenGL error checks have been omitted for brevity 
    glGenBuffers(1, &vertex_buffer); 
    checkGLerrors("post glGenBuffers"); 
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    vertex_shader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); 
    glCompileShader(vertex_shader); 
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); 
    glCompileShader(fragment_shader); 
    program = glCreateProgram(); 
    glAttachShader(program, vertex_shader); 
    glAttachShader(program, fragment_shader); 
    glLinkProgram(program); 
    checkGLerrors("post glLinkProgram"); 
    mvp_location = glGetUniformLocation(program, "MVP"); 
    vpos_location = glGetAttribLocation(program, "vPos"); 
    vcol_location = glGetAttribLocation(program, "vCol"); 
    checkGLerrors("post gl locations"); 
    glEnableVertexAttribArray(vpos_location); 
    checkGLerrors("post gl EnableVertexAttribArray"); 
    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, 
       sizeof(float) * 5, (void*) 0); 
    checkGLerrors("post glVertexAttribPointer"); 
    glEnableVertexAttribArray(vcol_location); 
    checkGLerrors("post glEnableVertexAttribArray"); 
    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, 
       sizeof(float) * 5, (void*) (sizeof(float) * 2)); 
    checkGLerrors("post glVertexAttribPointer"); 
    while (!glfwWindowShouldClose(window)) 
    { 
    float ratio; 
    int width, height; 
    mat4x4 m, p, mvp; 
    glfwGetFramebufferSize(window, &width, &height); 
    ratio = width/(float) height; 
    glViewport(0, 0, width, height); 
    glClearColor(0.784314, 0.780392, 0.305882, 1.0); // add background color 
    glClear(GL_COLOR_BUFFER_BIT); 
    mat4x4_identity(m); 
    mat4x4_rotate_Z(m, m, (float) glfwGetTime()); 
    mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); 
    mat4x4_mul(mvp, p, m); 
    glUseProgram(program); 
    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glfwSwapBuffers(window); 
    glfwPollEvents(); 
    } 
    glfwDestroyWindow(window); 
    glfwTerminate(); 
    exit(EXIT_SUCCESS); 
} 
+3

Avez-vous vérifié ce que 'glGetError' vous dit? Dans un profil de base, vous devez utiliser un VAO. – BDL

+0

Merci @BDL - non, je n'avais aucune idée que je devrais faire cela, je vais essayer de le faire maintenant ... EDIT: fait cela, et pour 3,2 am obtenir "' Erreur OpenGL ('post glVertexAttribPointer'): 1282 INVALID_OPERATION' ". .. – sdaau

Répondre

1

Merci à @BDL et son commentaire au sujet (objets tableau de vertex) VAO, je trouve How to use VBOs without VAOs with OpenGL core profile? - et en essayant des choses de là, j'ai trouvé que le seul changement au code OP ci-dessus, nécessaire si le dessin est sho WN en OpenGL 3.2, est la suivante:

... 
    //~ gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); 
    glfwSwapInterval(1); 
    #ifdef DO_OPENGL_THREE 
    // https://stackoverflow.com/a/30057424/277826: 
    // "You can however just create and bind a VAO and forget about it (keep it bound)." 
    GLuint VAO; 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 
    #endif 
    // NOTE: OpenGL error checks have been omitted for brevity 
    glGenBuffers(1, &vertex_buffer); 
... 

Une fois cette section avec VAO est, il n'y a pas plus d'erreurs OpenGL imprimées, et le dessin est OK.