Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glewInit() returning "Unknown Error" #417

Open
Sclerosi opened this issue Aug 5, 2024 · 37 comments
Open

glewInit() returning "Unknown Error" #417

Sclerosi opened this issue Aug 5, 2024 · 37 comments

Comments

@Sclerosi
Copy link

Sclerosi commented Aug 5, 2024

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
Copy link
Owner

What does glxinfo say?

@Sclerosi
Copy link
Author

Sclerosi commented Aug 5, 2024

$ glxinfo 
name of display: :0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4

@Sclerosi
Copy link
Author

Sclerosi commented Aug 5, 2024

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
Copy link
Owner

glxinfo looks healthy to me. Will look into it.

@nigels-com
Copy link
Owner

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

@Sclerosi
Copy link
Author

Sclerosi commented Aug 6, 2024

It returns 4

@Sclerosi
Copy link
Author

Sclerosi commented Aug 6, 2024

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

@nigels-com
Copy link
Owner

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
Copy link
Owner

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

@nigels-com
Copy link
Owner

glew.c

@Sclerosi
Copy link
Author

Sclerosi commented Aug 6, 2024

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
Copy link
Owner

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
Copy link
Author

Sclerosi commented Aug 6, 2024

dot == 0

So that seems to be the issue.

@nigels-com
Copy link
Owner

And what is the value of s?

/* query opengl version */
  s = getString(GL_VERSION);
  printf("%s\n", s);

@Sclerosi
Copy link
Author

Sclerosi commented Aug 6, 2024

dot=0
s==(null)

@nigels-com
Copy link
Owner

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
Copy link
Author

Sclerosi commented Aug 7, 2024

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
Copy link
Owner

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

@Sclerosi
Copy link
Author

Sclerosi commented Aug 7, 2024

Does GLEW typically run into issues with arch?

@Sclerosi
Copy link
Author

Sclerosi commented Aug 7, 2024

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
Copy link
Owner

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
Copy link
Author

Sclerosi commented Aug 7, 2024

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
Copy link
Owner

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

@Sclerosi
Copy link
Author

Sclerosi commented Aug 7, 2024

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
Copy link
Owner

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

@Sclerosi
Copy link
Author

Sclerosi commented Aug 8, 2024

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
Copy link

Mango0x45 commented Aug 19, 2024

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
Copy link

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
Copy link

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
Copy link
Owner

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
Copy link

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
Copy link

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
Copy link
Owner

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

@chenliangabc
Copy link

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
Copy link

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.

@danila-zol
Copy link

I have the same problem on openSUSE Leap 15.6

System

OS openSUSE Leap 15.6
Arch x86_64
GPU Nvidia GeForce GTX 1660 Super
DE GNOME 45.3 Wayland

glxinfo.txt
glewinfo.txt

Code to replicate the issue

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


int main(void)
{
	GLFWwindow* window;
	if (!glfwInit())
		exit(EXIT_FAILURE);

	window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
	if (!window) {
		glfwTerminate();
		exit(EXIT_FAILURE); 
	} 

	glfwMakeContextCurrent(window);

	GLenum error = glGetError();
	if (error != GL_NO_ERROR)
	{
		std::cout << "OpenGL Error: " << error << std::endl;
	}

	GLenum glewinit = glewInit();
	if (glewinit != GLEW_OK) {
		std::cout << "GLEW error: " << glewGetErrorString(glewinit) << std::endl;
		exit(EXIT_FAILURE);
	}

	glfwDestroyWindow(window);
	glfwTerminate();
	exit(EXIT_SUCCESS);
}

It fails with Unkown error

Workarounds

Interestingly enough the problem goes away when linking to system libglfw.so provided from the repo rather than the one I've compiled myself following their standard compile instructions. The issue also goes away if I compile GLEW with make SYSTEM=linux-egl as suggested by @Mango0x45.

@danila-zol
Copy link

I've been able to pin point specific version of glfw that causes this crash. If I compile and link to glfw 3.3.10 (the one also shipped by openSUSE Leap repos) everything works fine, but if I link to glfw 3.4 then glewInit() returns Unknown error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants