0

I'm currently having some issues with OpenGL development on Windows 8. I am doing the setup of OpenGL for a project that does work in Linux.

We use both glfw and glew in this project.

My actual problem is that glGenVertexArrays is null and when it is called it crashes and I get an access violation. glGenVertexArrays is not the first gl call using glew that is called.

I linked glew and glfw to the visual studio project using the win32 libs following this tutorial: http://www.41post.com/5178/programming/opengl-configuring-glfw-and-glew-in-visual-cplusplus-express

The following code is the initialization code:

glfwSetErrorCallback(error_callback);

    if (!glfwInit())
    {
        LOG_FATAL << "Failed to init glfw context";
        exit(EXIT_FAILURE);
    }

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

    m_window = glfwCreateWindow(1240, 480, "Rubix", NULL, NULL);

    if (!m_window)
    {
        glfwTerminate();
        LOG_FATAL << "Failed to create glfw window";
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(m_window);

    #ifdef WIN32
    //glewExperimental = GL_TRUE;
    GLenum glewinit = glewInit();

    if (glewinit != GLEW_OK)
    {
        std::cout << "Glew not okay! " << glewinit;
        exit(EXIT_FAILURE);
    }
    #endif

    glfwSwapInterval(1);
    glfwSetKeyCallback(m_window, key_callback);

    LOG_INFO << "glfw OpenGL context ready";

    initGL();

The following code is called to display a cube:

float points[] = {
        0.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f, 1.0f,
        0.0f, 1.0f, 1.0f, 1.0f
    };

    float normals[] = {
        0.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f, 1.0f,
        0.0f, 1.0f, 1.0f, 1.0f
    };

    unsigned short index_array[] = {
        0, 3, 2,
        0, 2, 1,
        0, 1, 5,
        0, 5, 4,
        1, 2, 6, 
        1, 6, 5,
        2, 3, 7,
        2, 7, 6,
        3, 0, 4,
        3, 4, 7,
        4, 5, 6,
        4, 6, 7,
    };

    GLuint points_vbo;
    glGenBuffers (1, &points_vbo);
    glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
    glBufferData (GL_ARRAY_BUFFER, 32 * sizeof (float), points, GL_STATIC_DRAW);

    GLuint normals_vbo;
    glGenBuffers (1, &normals_vbo);
    glBindBuffer (GL_ARRAY_BUFFER, normals_vbo);
    glBufferData (GL_ARRAY_BUFFER, 32 * sizeof (float), normals, GL_STATIC_DRAW);

    GLuint index_buffer_object;
    glGenBuffers (1, &index_buffer_object);
    glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, index_buffer_object);
    glBufferData (GL_ELEMENT_ARRAY_BUFFER, 48 * sizeof (unsigned short), index_array, GL_STATIC_DRAW);

    glGenVertexArrays (1, &m_vao);
    glBindVertexArray (m_vao);
    glEnableVertexAttribArray (0);
    glEnableVertexAttribArray (1);

    glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
    glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer (GL_ARRAY_BUFFER, normals_vbo);
    glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_object);

    glBindVertexArray(0);

    // Creating program

    Program program;

    program.emplace_back("pos.vert", GL_VERTEX_SHADER);
    program.emplace_back("smooth.frag", GL_FRAGMENT_SHADER);

    program.link();

    program.clearShaders();

    m_program = program.getProgram();

I did try the glewExperimental = GL_TRUE; With this the code runs, but it does not display anything.

The gpu I am using is a nvidia GT 730M and it does support opengl up to 4.2.

I also ran the glewinfo.exe which says that the glGenVertexArrays should be OK. Also I noticed that when I open the glcorearb.h located (with visual studio 2013) in my gl folder under Windows kits, most of the versions in opengl are greyed out and I think the problem might be linked to that.

2 Answers2

0

Your code does not check if the required runtime prerequisites are met and hence it doesn't catch the case, if an insufficient OpenGL environment is present. Most likely the OpenGL drivers are improperly installed which is why GLEW can't initialize the function pointers you need.

Note that Microsoft is sabotaging OpenGL and strips away the OpenGL ICD in the drivers installed through Windows Update or the initial Windows setup. Please double check, that drivers you've downloaded directly from the NVidia website are properly installed.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I have installed my drivers via Nvidia's tool GeForce Experience. They are the latest drivers for my GPU. – Alexandre C.-Hamelin Apr 15 '15 at 21:08
  • I just tested and glGetString(GL_VENDOR);" returns intel even though I did change the settings in the nvidia control panel to use it instead of the intel integrated gpu... – Alexandre C.-Hamelin Apr 15 '15 at 21:10
  • Actually, my setting in nvidia's control panel was for the release .exe and I'm testing with the debug .exe. I added the debug .exe to the profiles aswell and it still crashes. – Alexandre C.-Hamelin Apr 15 '15 at 21:18
  • @AlexandreCoulon-Hamelin: There's a trick to force the use of the NVidia GPU in Optimus systems. It's described in the Optimus Usage Guide and this StackOverflow answer mentions it: http://stackoverflow.com/a/14041061/524368 – I suggest you put that enablement variable export into your program as well (the source file with the `main` or `WinMain` function should suffice). – datenwolf Apr 15 '15 at 21:35
  • now that I added the .exe in my debug folder to the nvidia control panel it does use my nvidia gpu. glGetString(GL_VENDOR) returns nvidia – Alexandre C.-Hamelin Apr 15 '15 at 21:45
  • @AlexandreCoulon-Hamelin: Uh, I just saw that you're checking for a macro of name `WIN32` to call *glewInit*. Why? You have to call *glewInit* on every OS, if you want to call GLEW. But more worrysome, the macro you're looking for is actually called `_WIN32` so very likely that part didn't get compiled in. I suggest you remove that conditional compilation alltogether. – datenwolf Apr 15 '15 at 22:35
0

Alright, the issue was that visual studio was not using the right GPU. To fix it I went in the Nvidia control panel -> Manage 3D Settings -> Program settings and added both my debug exe and release exe.

The reason why it didn't work after that is that I forgot to try it out with glewExperimental set to true.

After setting both does things my problem was fixed.