How to initialize OpenGL context using PyGame instead of GLUT

I try to start with OpenGL, using the Python and PyGame.

I'm going to use instead of GLUT PyGame to perform all initialization, opening windows, input processing, etc.

However, my shaders will not compile if you do not specify the exact version of OpenGL and profile.

They 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, for example:

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

which does not specify the exact version of OpenGL version 3.3 and CORE_PROFILE, the same program will fail when you try to compile the shaders:

RuntimeError: ( 'Fault compile shader (0): 0: 2 (10): error: GLSL 3.30 Version not supported The supported:. 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 to do it with PyGame?

+6
source share
2 answers

I think:

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

It may be what you are looking for. He shows how to use vertex shaders and fragment shaders in pygame and PyOpenGL. If you are not using PyOpenGL then you need it. To download it, simply run:

pip install PyOpenGL

in command line / terminal

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

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

I have included a short exemplary example of what I think you're trying to do this by using some 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() : Morgan Borman -------------- # 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() 1.0f, 1.0f); 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() 1.0) 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() pg.OPENGL) 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() 

He does not do anything except loading shaders in pygame. I believe that your main goal.

0
source

The problem is that pygame initializes the OpenGL context, which is either not modern enough, or you get the OpenGL "compatibility" profile instead of the "main" OpenGL profile.

This is actually a problem in itself Pygame, and I filed a bug about it. Pygmy humans correct this by adding appropriate functions to access OpenGL attributes. If you need to get around this, you can use ctypes to go to the SDL layer and set the OpenGL attributes.

Discussion, interim solutions and adding functions here:

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

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

0
source

All Articles