Search code examples
pythonopenglglslshaderpyopengl

PyOpenGL OpenGL Version on MacOs


I've been told to switch legacy profile to core profile from other stackoverflow posts but I can't seem to find a way to do that. So I'm positing a more updated error post to help me figure out a way.

CODE:

import glfw, numpy
from OpenGL.GL import *
import OpenGL.GL.shaders


def main():
    if not glfw.init():
        return

    window = glfw.create_window(800,600,"My OpenGL Window", None, None)

    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)

    triangle = [-0.5, -0.5, 0.0,
                0.5, -0.5, 0.0,
                0.0, 0.5, 0.0]

    triangle = numpy.array(triangle, dtype = numpy.float32)

    vertex_shader = """
    #version 460
    in vec3 position;

    void main()
    {
        gl_Position = position;
    }

    """

    fragment_shader = """
    #version 460
    void main()
    {
        gl_FragColor = vec4(1.0f,0.0f,0.0f,1.0f);
    }
    """

    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
                                              OpenGL.GL.shaders.compileShader(fragment_shader,GL_FRAGMENT_SHADER))

    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 36, triangle, GL_STATIC_DRAW)

    position = glGetAttribLocation(shader, "position")
    glVertexAttribPoint(position, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(position)

    glUseProgram(shader)



    glClearColor(0.2, 0.3, 0.2, 1.0)
    while not glfw.window_should_close(window):
        glfw.poll_events()

        glClear(GL_COLOR_BUFFER_BIT)

        glDrawArrays(GL_TRIANGLES, 0, 3)

        glfw.swap_buffers(window)

    glfw.terminate()

if __name__ == "__main__":
    main()

I keep getting this error

Traceback (most recent call last):

File "/Users/Datboi/Desktop/Python/Opengl/main.py", line 71, in <module>
    main()
File "/Users/Datboi/Desktop/Python/Opengl/main.py", line 43, in main
    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/OpenGL/GL/shaders.py", line 226, in compileShader
    shaderType,
RuntimeError: ('Shader compile failure (0): b"ERROR: 0:2: \'\' :  version \'460\' is not supported\\n"', [b'\n    #version 460\n    in vec3 position;\n    \n    void main()\n    {\n        gl_Position = position;\n    }\n\n    '], GL_VERTEX_SHADER)

I can't seem to find anything to fix this issue. I'm new to OpenGL/PyOpenGL and couldn't find any posts that have asked roughly the same question


Solution

  • ERROR: 0:2: \'\' : version \'460\' is not supported

    is caused because you don't specify the OpenGL version before you create the window. Since your system only support OpenGL verison 4.1, you have to add the follwong lines of code. See also OpenGL Development on OS X:

    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1)
    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    window = glfw.create_window(800,600,"My OpenGL Window", None, None)
    

    If you solve that issue, then you'll face the next issue:

    While gl_Position is a Homogeneous coordinates, the vertex shader input variable position is of type vec3.

    The assignment of gl_Position = position causes the ERROR:

    assignment of incompatible types

    You can solve this issue by changing the vertex shader. Either change the assignment

    #version 410 core
    in vec3 position;
    
    void main()
    {
        gl_Position = vec4(position, 1.0);
    }
    

    or change the type of the input variable:

    #version 410 core
    in vec4 position;
    
    void main()
    {
        gl_Position = position;
    }
    

    Since gl_FragColor is deprecated in core version 4.60, you have to declare a fragment shader output variable instead of using the deprecated built in output variable gl_FragColor:

     #version 410 core
    
     out vec4 frag_color; 
    
     void main()
     {
        frag_color = vec4(1.0f,0.0f,0.0f,1.0f);
     }
    

    Further there is a typo in your program. It has to be glVertexAttribPointer instead of glVertexAttribPoint.

    Note, in a core profile OpenGL Context, you have to use a Vertex Array Object, because the default vertex array object 0 is not valid in a core profile.

    ok im getting this error now

    kages/OpenGL/GL/shaders.py", line 108, in check_validate glGetProgramInfoLog( self ), RuntimeError: Validation failure (0): b'Validation Failed: No vertex array object bound.\n'

    Create and bind vertex array object after the OpenGL context has become current:

    glfw.make_context_current(window)
    
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)
    
    shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
                                              OpenGL.GL.shaders.compileShader(fragment_shader,GL_FRAGMENT_SHADER))