nigels-com / glew

The OpenGL Extension Wrangler Library
Other
2.62k stars 614 forks source link

glewInit() returning "Unknown Error" #417

Open Sclerosi opened 1 month ago

Sclerosi commented 1 month ago

Triangle.cpp

#include <GL/glew.h> 
#include <GL/gl.h>  
#include <GL/glut.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdio.h> 

//docs.GL helps

int main(void)
{

    GLFWwindow* window;
    /* Initialize the library */
    if (!glfwInit())
        return -1;
    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    std::cout << glGetString(GL_VERSION) << std::endl; 
    std::cout << glGetString(GL_RENDERER) << std::endl; 

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    printf("Error: '%s'\n", glewGetErrorString(err));
    if(err != GLEW_OK) {
      std::cout << "Problem!" << std::endl;
      return -1;
    }
    std::cout << glGetString(GL_VERSION) << std::endl; 

    float positions[6] = {
      -0.5f, -0.5f, 
      0.0f, 0.5f, 
      0.5f, -0.5f 
    };

    unsigned int buffer; 
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer); 
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);

    /* Make the window's context current */

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);
        // glDrawElements(GL_TRIANGLES, 3, 0); 

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

I haven't been able to find any solutions to my problem, and glewInit() returning "Unknown Error" is not helping much unfortunately.

Im working with: 4.6 (Compatibility Profile) Mesa 24.1.5-arch1.1 Mesa Intel(R) HD Graphics 520 (SKL GT2)

So linux may be the issue, but I am just looking for some clarification.

Thank you for any help you are able to provide as I cannot seem to understand my issue.

nigels-com commented 1 month ago

What does glxinfo say?

Sclerosi commented 1 month ago
$ glxinfo 
name of display: :0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4
Sclerosi commented 1 month ago

The entire thing is quite long, but it is in this text file if the top doesn't provide enough information. glxinfo.txt

nigels-com commented 1 month ago

glxinfo looks healthy to me. Will look into it.

nigels-com commented 1 month ago

Could you also provide the numeric value of the error code from glewInit() ?

Sclerosi commented 1 month ago

It returns 4

Sclerosi commented 1 month ago

I'm running it now and glewGetErrorString() returns "Missing GL version", instead of "Unknown error" (IDK why)

nigels-com commented 1 month ago

If you're able to put some printfs in the function glewContextInit and recompile it...

Is glewGetProcAddress failing? What is the string returned by getString? What are the major and minor versions detected?

  #ifdef _WIN32
  getString = glGetString;
  #else
  getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString");
  if (!getString)
    return GLEW_ERROR_NO_GL_VERSION;
  #endif

  /* query opengl version */
  s = getString(GL_VERSION);
  dot = _glewStrCLen(s, '.');
  if (dot == 0)
    return GLEW_ERROR_NO_GL_VERSION;

  major = s[dot-1]-'0';
  minor = s[dot+1]-'0';

  if (minor < 0 || minor > 9)
    minor = 0;
  if (major<0 || major>9)
    return GLEW_ERROR_NO_GL_VERSION;

It's an unusual problem you're having, if I had to guess it's glewGetProcAddress due to the way OpenGL is being linked - in some new-fangled and not quite backwards compatible way.

nigels-com commented 1 month ago

I could make a change to return a different error code for the glewGetProcAddress null check, perhaps.

nigels-com commented 1 month ago

glew.c

Sclerosi commented 1 month ago

i added some printf()'s (likely incorrectly as I am not particularly familiar with C) and now the section you outlined looks like this:

getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString");
  printf("%s\n", getString); 
  if (!getString) {
    return GLEW_ERROR_NO_GL_VERSION;
  }
  #endif

  /* query opengl version */
  s = getString(GL_VERSION);
  dot = _glewStrCLen(s, '.');
  if (dot == 0)
    return GLEW_ERROR_NO_GL_VERSION;

  major = s[dot-1]-'0';
  minor = s[dot+1]-'0';

  printf("%d\n", major); 
  printf("%d\n", minor); 

  if (minor < 0 || minor > 9)
    minor = 0;
  if (major<0 || major>9)
    return GLEW_ERROR_NO_GL_VERSION;

  if (major == 1 && minor == 0)
  {
    return GLEW_ERROR_GL_VERSION_10_ONLY;
  }

I feel as if I am using them improperly because getString returns something indecipherable when I print it treating it like a char* (It also gives a warning that it may be a lossy conversion) : (��H�U)

(I also added an int main() { glewContextInit(); } at the bottom)

nigels-com commented 1 month ago

getString is a pointer to a function, so that's a useful diagnostic, next check if dot is zero.

  dot = _glewStrCLen(s, '.');
  printf("dot=%d\n", dot);
  if (dot == 0)
    return GLEW_ERROR_NO_GL_VERSION;

(Actually my C feels a bit rusty)

Sclerosi commented 1 month ago

dot == 0

So that seems to be the issue.

nigels-com commented 1 month ago

And what is the value of s?

/* query opengl version */
  s = getString(GL_VERSION);
  printf("%s\n", s);
Sclerosi commented 1 month ago
dot=0
s==(null)
nigels-com commented 1 month ago

glGetString should only be returning nullptr if an error is generated. I wouldn't really expect GLEW to do more here than error out.

What's the Linux distro and version, and what's the computer brand and model?

Sclerosi commented 1 month ago

Computer brand: DELL Computer Model: Inspiron 13-7353 Linux Distro: Arch Linux version: Linux-6.10.3.arch1-2 but its a rolling release distro

nigels-com commented 1 month ago

Ah, Arch! It's like you're sending bug reports from the future. I'm on Ubuntu 22.04 here.

Sclerosi commented 1 month ago

Does GLEW typically run into issues with arch?

Sclerosi commented 1 month ago

While I was running through glew.c, it seems as if the getString() function seems to be the issue for me. As it returns null when s is assigned to its return value.

Do you know where it comes from?

I tried recompiling with glGetString() replacing it but it ran into the same issue.

If I tried a printf() statement like:

printf("%s\n", glGetString(GL_VERSION); 

or

printf("%s\n", getString(GL_VERSION)); 

or even if I just gave "GL_VERSION_4_6" as an input, it segfaults (and when I replace getString() with a variable assigned to that value it still segfaults, even if don't run it in glew.c and do it somewhere else entirely with the libraries linked and the headers included)

glGetString(GL_VERSION) works fine whenever I use the same function in C++, it only breaks for me in c.

nigels-com commented 1 month ago

No, I shouldn't complain about Arch. It seems like there is something sorta broken with glGetString on your setup, compared to traditional and specified behaviour on Linux. So you're perhaps an early warning system that GLEW is going to need to handle something slightly different. I have an old computer I can try putting Arch on, it's Intel graphics but likely a much older chip than yours.

One other diagnostic, does glewinfo also crash? If not, what's the output?

Sclerosi commented 1 month ago

glewinfo doesn't crash thankfully, the output is quite long though.

I have glewinfo's output in this textfile, if that helps.

glewinfo.txt

I took a peek and just looked for "init" and found this:

GL_EXT_shader_non_constant_global_initializers: 
    MISSING

I don't know what it necessarily does or if it is required.

It would be cool to think of my issues being a potential future warning, although I would wager its more likely I am missing something or making a small mistake (I am quite new to programming so its likely not an issue with the software).

nigels-com commented 1 month ago

Do double-check that you're definitely making the context current, before calling glewInit.

Sclerosi commented 1 month ago

I did invoke glfwMakeContextCurrent() before glewInit(), but when I combed through my code I forgot that I had left in glewGetErrorString(1), instead of glewGetErrorString(err) somehow.

The "Missing GL Version error" was actually my mistake, it still says unknown error when I run my program and have the correct glewGetErrorString() argument ( glewGetErrorString(err) )

(Everything below "Problem!" in the code I have written is irrelevant as it returns, so looking through my code is less arduous than it may seem, this also is the entire fire, there is nothing obscured)

int main(int argc, char**argv)
{

    GLFWwindow* window;
    /* Initialize the library */
    if (!glfwInit())
        return -1;
    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    std::cout << glGetString(GL_VERSION) << std::endl; 
    std::cout << glGetString(GL_RENDERER) << std::endl; 

    GLenum err = glewInit();
    printf("Error: '%s'\n", glewGetErrorString(err));
    std::cout << err << '\n' << GLEW_OK << '\n';
    if(err != GLEW_OK) {
      err = glGetError(); 
    //  std::cout << err << std::endl; 
      std::cout << "Problem!" << std::endl;
      return -1;
    }

    std::cout << glGetString(GL_VERSION) << std::endl; 

    float positions[6] = {
      -0.5f, -0.5f, 
      0.0f, 0.5f, 
      0.5f, -0.5f 
    };

    unsigned int buffer; 
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer); 
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);

    /* Make the window's context current */

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);
        // glDrawElements(GL_TRIANGLES, 3, 0); 

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

I made a copy of the edited glew.c file in the directory where my triangle.cpp file is, and I included it in the header.

GLEW does not have an issue with retrieving the GL_VERSION, as this is the output of the executed triangle binary:

4.6 (Compatibility Profile) Mesa 24.1.5-arch1.1 // glGetString(GL_VERSION) 
Mesa Intel(R) HD Graphics 520 (SKL GT2) // glGetString(GL_RENDERER) 
dot=1 
s==4.6 (Compatibility Profile) Mesa 24.1.5-arch1.1 // Able to retrieve getString(GL_VERSION) 
4 // Major 
6 // Minor 
Error: 'Unknown error' // ??? 
4 // GLenum err value 
0 // GLEW_OK value 
Problem! // Uh oh 

The issue is still unknown it seems.

nigels-com commented 1 month ago

Perhaps then, build in debug mode and step through glewInit. Confirm if it is glewContextInit that fails, or glxewInit.

Sclerosi commented 1 month ago

It doesn't seem to be able to grab my display: in glxewInit():

Display* display;
  int major, minor;
  const GLubyte* extStart;
  const GLubyte* extEnd;
  /* initialize core GLX 1.2 */
  if (_glewInit_GLX_VERSION_1_2()) return GLEW_ERROR_GLX_VERSION_11_ONLY;
  /* check for a display */
  display = glXGetCurrentDisplay();
  printf("display==%s\n", display);
  if (display == NULL) return GLEW_ERROR_NO_GLX_DISPLAY;

display returns null

Mango0x45 commented 3 weeks ago

I am having a similar issue. The following code on Arch fails with ‘main: failed to initialize GLEW: Unknown error’:

#include <err.h>
#include <stddef.h>
#include <stdlib.h>

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

int
main(void)
{
    if (glfwInit() == 0)
        errx(1, "failed to initialize GLFW");

    GLFWwindow *win = glfwCreateWindow(640, 400, "Hello, World!", NULL, NULL);
    if (win == NULL)
        errx("failed to create window");

    glfwMakeContextCurrent(win);
    GLenum e = glewInit();
    if (e != GLEW_OK)
        errx("failed to initialize GLEW: %s", glewGetErrorString(e));

    while (!glfwWindowShouldClose(win)) {
        /* ... */
    }

    glfwTerminate();
    return EXIT_SUCCESS;
}

You can view my output of glewinfo here if it’s helpful.

Mango0x45 commented 3 weeks ago

Ah, seems to be an issue with me being on Wayland. I was able to fix this by building with make SYSTEM=linux-egl

chenliangabc commented 3 weeks ago

Perhaps then, build in debug mode and step through glewInit. Confirm if it is glewContextInit that fails, or glxewInit.

I have the same problem。I use wxGLCanvas (wxWidgets build with gtk2) , glewInit is ok , it return 4 when wxWidgets(build with gtk3, glXGetCurrentDisplay() retrun NULL.

Platform and version information

wxWidgets version : 3.2.2.1
glew version: 2.2.0
OS and its version: Ubuntu20.04
GTK version: gtk3(3.24.20) gtk2(2.24.32)
GDK backend :X11
Desktop environment :Gnome
nigels-com commented 3 weeks ago

Hello @chenliangabc if you could attach the output of glxinfo and glewinfo, would appreciate it. I am concerned that this could be a problem on Ubuntu 20.04.

chenliangabc commented 3 weeks ago

Hello @chenliangabc if you could attach the output of glxinfo and glewinfo, would appreciate it. I am concerned that this could be a problem on Ubuntu 20.04.

@nigels-com glxinfo.txt glewinfo.txt

chenliangabc commented 2 weeks ago

Hello @chenliangabc if you could attach the output of glxinfo and glewinfo, would appreciate it. I am concerned that this could be a problem on Ubuntu 20.04.

@nigels-com glxinfo.txt glewinfo.txt

@nigels-com Hello, can you see the problem from the output

nigels-com commented 2 weeks ago

@chenliangabc Your glxinfo and glewinfo look perfectly normal to me.

chenliangabc commented 2 weeks ago

I use glXGetProcAddressARBto get the opengl function address instead glewInit, it works. I looked at the glewInit source code, and it does something else. Does it matter if I don't do these extra things.

Perhaps then, build in debug mode and step through glewInit. Confirm if it is glewContextInit that fails, or glxewInit.

I have the same problem。I use wxGLCanvas (wxWidgets build with gtk2) , glewInit is ok , it return 4 when wxWidgets(build with gtk3, glXGetCurrentDisplay() retrun NULL.

Platform and version information

wxWidgets version : 3.2.2.1
glew version: 2.2.0
OS and its version: Ubuntu20.04
GTK version: gtk3(3.24.20) gtk2(2.24.32)
GDK backend :X11
Desktop environment :Gnome
chenliangabc commented 2 weeks ago

Perhaps then, build in debug mode and step through glewInit. Confirm if it is glewContextInit that fails, or glxewInit.

I have the same problem。I use wxGLCanvas (wxWidgets build with gtk2) , glewInit is ok , it return 4 when wxWidgets(build with gtk3, glXGetCurrentDisplay() retrun NULL.

Platform and version information

wxWidgets version : 3.2.2.1
glew version: 2.2.0
OS and its version: Ubuntu20.04
GTK version: gtk3(3.24.20) gtk2(2.24.32)
GDK backend :X11
Desktop environment :Gnome

Sorry, is wxWidgtes build problem, wxUSE_GLCANVAS_EGL is OFF by default under GTK2, but is ON by default under GTK3. I didn't notice that.