Is this a bug or I'm missing something?

I have a small program with GLFW and GLEW that simple draw a triangle, but the issue is… I don’t have a shader program, vertex and fragment shader, but the triangle is still being draw for some reason. I’m new to opengl programming but I think this is not the expected behaviour for opengl core profile, we should have a program and shaders to actually draw a triangle in the window isn’t?

If so, is this an issue with intel drivers? I’ve updated my drivers to the latest version and the triangle is still being rendered without specifying a shader program, vertex and fragment shader.

My CPU: i5-7500
My GPU: Intel HD 630
Driver Version (latest): 31.0.101.2135

My Code:

#include <cstdio>
#include <cstdlib>

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

int main()
{
    // win/gl context initialization...
    if (!glfwInit()) {
        fprintf(stderr, "GLFW initialization fail!\n");
        exit(EXIT_FAILURE);
    }

    // use gl 3.3 and core profile
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    GLFWwindow *window = glfwCreateWindow(640, 480, "glfw", nullptr, nullptr);
    if (!window) {
        fprintf(stderr, "GLFW window creation fail!\n");
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);

    fprintf(stdout, "OpenGL Version: %s\n", glGetString(GL_VERSION));

    GLenum err = glewInit();
    if (err != GLEW_OK) {
        fprintf(stderr, "GLEW initialization fail!\n");
        exit(EXIT_FAILURE);
    }

    // >> configure triangle
    float vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };

    unsigned int vao, vbo;

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);

    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
    glEnableVertexAttribArray(0);
    // << configure triangle

    // main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        
        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
    }

    // exit
    glfwTerminate();

    exit(EXIT_SUCCESS);
}

output:

This is strange to me and is confusing me a bit, as I was expecting nothing to appear in the window, but the triangle is there. If anyone can explain why this is happening, I would be grateful, thanks.

The code you’ve written should not work, so there is some sort of bug somewhere. It may be that GLFW isn’t giving you a proper core context, or the GL implementation isn’t giving you a proper core context.

1 Like

This seems very clear? glspec3.3core, 2.11 Vertex Shaders, page 54:

If UseProgram … 0, then the current rendering state refers to an invalid program object, and the results of vertex and fragment shader execution are undefined.

So if it draws a triangle, or doesn’t draw a triangle, or formats the hard drive, all results are equally correct.

1 Like

I’ve heard somewhere a few years ago that some implementations of OpenGL offer a simple default shader program when none is currently bound (that is 0), which could be a nice “feature”.

Implementations are free to do anything when you invoke undefined behavior.

1 Like

So this is a thing that I just need to ignore. And just for more informations, if I remove the vao bind from main loop the application crashes after few seconds. Anyway, thx guys

Yes, you can safely ignore weird things that implementations do whenever you misuse the API. In a perfect world, the OpenGL API, when used correctly, should behave exactly the same everywhere.

VAOs are not optional in modern core profile OpenGL. You have to have one valid VAO bound, when you invoke draw calls.

1 Like