9
votes

I'm trying to start with OpenGL, using Python and PyGame.

I'm going to use PyGame instead of GLUT to do all the initializing, windows opening, input handling, etc.

However, my shaders are failing to compile, unless I specify exactly the version of OpenGL and profile.

They do compile with GLUT initialization from the book:

glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(400, 400)

# this is what I need
glutInitContextVersion(3, 3)
glutInitContextProfile(GLUT_CORE_PROFILE)

glutCreateWindow("main")

But, with simple PyGame initialization like this:

pygame.init()
display = (400, 400)
pygame.display.set_mode(display, pygame.DOUBLEBUF|pygame.OPENGL)

which doesn't specify exact OpenGL version 3.3 and CORE_PROFILE, the same program would fail when trying to compile shaders:

RuntimeError: ('Shader compile failure (0): 0:2(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES\n', ['\n #version 330 core\n layout(location = 0) in vec4 position;\n void main()\n {\n gl_Position = position;\n }\n '], GL_VERTEX_SHADER)

My question is: how do I do this initialization with PyGame?

2
Did you ever solve this ?Oly

2 Answers

2
votes

The problem is that pygame is initializing an OpenGL context that either isn't modern enough or you are getting a "compatibility" OpenGL profile instead of a "core" OpenGL profile.

This is actually an issue in pygame itself, and I filed a bug about it. The pygame folks are fixing it by adding the appropriate functions to get at the OpenGL attributes. If you need to work around it, you can use ctypes to dig down to the SDL layer and set the OpenGL attributes.

Discussion, interim solutions, and feature add pull here:

https://github.com/pygame/pygame/issues/1124#issuecomment-507021897

https://github.com/pygame/pygame/pull/1127

0
votes

I think this:

https://gist.github.com/MorganBorman/4243336

might be what your looking for. It shows how to use vertex shaders and fragment shaders in pygame and PyOpenGL. If your not using PyOpenGL, then your gonna have to. To download it, just run :

pip install PyOpenGL

in your command prompt/terminal

If that does not work, I recommend taking a look at the PyOpenGL installation page for more details:

http://pyopengl.sourceforge.net/documentation/installation.html

I included a short boiled down example of what I think your trying to do using some of the code from the link.

import OpenGL.GL as GL
import OpenGL.GL.shaders
import pygame as pg


#-------------not my code, credit to: Morgan Borman--------------#
vertex_shader = """
#version 330
in vec4 position;
void main()
{
   gl_Position = position;
}
"""

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

def main():
    pg.init()

    #-------------not my code, credit to: Morgan Borman--------------#
    GL.glClearColor(0.5, 0.5, 0.5, 1.0)
    GL.glEnable(GL.GL_DEPTH_TEST)

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

    DISPLAY_DIMENSIONS = (640, 480)
    display = pg.display.set_mode(DISPLAY_DIMENSIONS, pg.DOUBLEBUF | pg.OPENGL)
    clock = pg.time.Clock()
    FPS = 60

    while True:
        clock.tick(FPS)
        for e in pg.event.get():
            if e.type == pg.QUIT:
                return


        pg.display.flip()

if __name__ == '__main__':
    try:
        main()
    finally:
        pg.quit()

It does not do anything but load shaders in pygame. Which i believe is your main goal.