Create geometry shader using python opengl (PyOpenGL) failed

ghz 11hours ago ⋅ 1 views

I want to create geometry_shader using glCreateShader(GL_GEOMETRY_SHADER), but I get error.

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    geometry_shader = glCreateShader(GL_GEOMETRY_SHADER)
  File "errorchecker.pyx", line 53, in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError (src/errorchecker.c:1218)
OpenGL.error.GLError: GLError(
        err = 1280,
        description = b'invalid enumerant',
        baseOperation = glCreateShader,
        cArguments = (GL_GEOMETRY_SHADER,),
        result = 0
)

My environment: Python version:3.6.7 OpenGL core profile version string: 4.5 (Core Profile) Mesa 18.0.5 OS version: ubuntu 18.04(ubuntu 16.04 tested same) From this site I know that the minimum version is 3.2. So it should not be version issue. Is it possible the bug of python wrapper of opengl? Here is my test code.

import glfw
from OpenGL.GL import *
glfw.init()
glfw.window_hint(glfw.SAMPLES, 4)
window_size = (800, 600)
window = glfw.create_window(*window_size, 'Vehicle Model', None, None)
glfw.make_context_current(window)
vertice_shader = glCreateShader(GL_VERTEX_SHADER)
geometry_shader = glCreateShader(GL_GEOMETRY_SHADER)
glfw.terminate()

Answer

The error you're encountering is related to an invalid enumerant passed to the glCreateShader function:

OpenGL.error.GLError: GLError(
        err = 1280,
        description = b'invalid enumerant',
        baseOperation = glCreateShader,
        cArguments = (GL_GEOMETRY_SHADER,),
        result = 0
)

This error usually means that the OpenGL implementation is unable to handle the value you passed for GL_GEOMETRY_SHADER. There are a few potential reasons for this:

1. Geometry Shader Not Supported in the Context

Even though your environment (OpenGL 4.5) theoretically supports geometry shaders, they might not be enabled in the current OpenGL context or might not be supported by the driver you're using.

You mentioned you're using Mesa 18.0.5, which is a common open-source implementation of OpenGL on Linux. However, it's possible that either:

  • Mesa drivers are not correctly exposing geometry shader functionality in your environment.
  • Your current OpenGL context does not support geometry shaders.

You can check whether geometry shaders are supported by your OpenGL context by querying the OpenGL extensions:

from OpenGL.GL import *
import glfw

# Initialize GLFW and create a window
glfw.init()
glfw.window_hint(glfw.SAMPLES, 4)
window = glfw.create_window(800, 600, 'OpenGL Test', None, None)
glfw.make_context_current(window)

# Check for geometry shader support
if glGetString(GL_EXTENSIONS).find(b"GL_ARB_geometry_shader4") == -1:
    print("Geometry Shader support not available.")
else:
    print("Geometry Shader support available.")

# Clean up
glfw.terminate()

2. Ensure the Correct OpenGL Context

Check the OpenGL version and context you are running to make sure that your OpenGL context supports geometry shaders. You can query the OpenGL version using:

print(glGetString(GL_VERSION))

If your version is 3.2 or later (which is required for geometry shaders), but the context is not set up correctly, it could result in the error you are seeing. Make sure that you are creating the window with the proper OpenGL version and profile hints:

glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_VERSION_MAJOR, 3)
glfw.window_hint(glfw.OPENGL_VERSION_MINOR, 2)

This will ensure that the window is created with the appropriate version of OpenGL that supports geometry shaders.

3. Check for OpenGL Version at Runtime

Since your error indicates that GL_GEOMETRY_SHADER is not recognized, you can explicitly query whether geometry shaders are supported at runtime with a method like:

def is_geometry_shader_supported():
    version = glGetString(GL_VERSION).decode('utf-8')
    if version >= "3.2":
        print("OpenGL version is 3.2 or higher, geometry shaders should be supported.")
        return True
    return False

4. Check for Correct Usage of OpenGL Enum

Ensure that GL_GEOMETRY_SHADER is correctly defined in the OpenGL context you're working with. Sometimes the enums for shaders might be different in some Python OpenGL bindings or environments. In case you're using a wrapper, check if there are any specific nuances to how the GL_GEOMETRY_SHADER enum is defined.

Example of Proper Code (with Checks):

Here’s a more complete version of your code that checks if geometry shaders are supported, creates the correct OpenGL context, and catches potential errors:

import glfw
from OpenGL.GL import *

def is_geometry_shader_supported():
    version = glGetString(GL_VERSION).decode('utf-8')
    if version >= "3.2":
        return True
    return False

glfw.init()
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_VERSION_MAJOR, 3)
glfw.window_hint(glfw.OPENGL_VERSION_MINOR, 2)

window = glfw.create_window(800, 600, 'OpenGL Test', None, None)
if not window:
    print("Failed to create OpenGL window")
    glfw.terminate()

glfw.make_context_current(window)

# Check if geometry shaders are supported
if is_geometry_shader_supported():
    print("Geometry Shader support available.")
    try:
        geometry_shader = glCreateShader(GL_GEOMETRY_SHADER)
        print("Geometry shader created successfully.")
    except Exception as e:
        print(f"Error creating geometry shader: {e}")
else:
    print("Geometry Shader support not available.")

# Clean up
glfw.terminate()

5. Update Your OpenGL Drivers

In some cases, the issue might be due to outdated or buggy drivers. Make sure your graphics drivers (Mesa, Nvidia, etc.) are up to date.

For example, on Ubuntu, you can update your drivers with the following commands:

sudo apt update
sudo apt upgrade

Alternatively, if you are using a proprietary Nvidia driver, you can try updating the driver from the official Nvidia site or using the nvidia-driver package from your distribution’s package manager.

Summary of Steps:

  1. Verify Geometry Shader Support: Ensure that the OpenGL context supports geometry shaders (check for extension GL_ARB_geometry_shader4 or OpenGL version 3.2+).
  2. Check OpenGL Version: Ensure your context has the correct OpenGL version (3.2+).
  3. Create Proper OpenGL Context: Make sure the context hints are set correctly in GLFW.
  4. Update Drivers: Ensure your graphics drivers are up to date.