Package: pygame-shaders
Pygame ShadersEasily integrate shaders into your new or existing pygame projectsThis project allows for GLSL shaders to easily be intergrated with either your new or existing Pygame projects without having to touch OpenGL.importpygameimportpygame_shaderspygame.init()screen=pygame.display.set_mode((600,600),pygame.OPENGL|pygame.DOUBLEBUF|pygame.HWSURFACE)#Create an opengl renderable display.display=pygame.Surface((600,600))#Create a new surface, this will be where you do all your pygame renderingdisplay.set_colorkey((0,0,0))#Make all black on the display transparentshader=pygame_shaders.Shader(size=(600,600),display=(600,600),pos=(0,0),vertex_path="shaders/vertex.txt",fragment_path="shaders/default_frag.txt")#Load your shader!whileTrue:pygame_shaders.clear((100,100,100))#Fill with the color you would like in the backgrounddisplay.fill((0,0,0))#Fill with the color you set in the colorkey#Your pygame code here.pygame.draw.rect(display,(255,0,0),(20,20,20,20))#Draw a red rectangle to the display at (20, 20)shader.render(display)#Render the display onto the OpenGL display with the shaders!pygame.display.flip()Overviewpygame_shaders.Shader-> Initializes a new shader.pygame_shaders.Shader(shader_size:Tuple[int],window_size:Tuple[int],position:Tuple[int],vertex_shader_path:str,fragment_shader_path:str)pygame_shaders.Shader.render-> Renders a shader to the display. If a surface is passed the shader will be rendered onto that Surface before being rendered onto the main display.pygame_shaders.Shader.render(surface:Optional[pygame.Surface])pygame_shaders.Shader.send-> Allows for uniforms to be passed to a shader.pygame_shaders.Shader.send(variable_name:str,data:List[float])pygame_shaders.clear-> Clears the display with a color.pygame_shaders.clear(color:Tuple[int])TutorialInstallationTo install pygame shaders. Simpily runpip install --upgrade pygame_shadersYour First ShaderOnce you have pygame_shaders installed, creating a shader is simple:shader=pygame_shaders.Shader(shader_size:Tuple[int],window_size:Tuple[int],position:Tuple[int],vertex_shader_path:str,fragment_shader_path:str)However before we can create any shaders. We must create our Pygame display. For this tutorial I will create a (600, 600) display. It is important for this display to contain the pygame.OPENGL, pygame.DOUBLEBUF and pygame.HWSURFACE flags. As this will allow us to render to the display using OpenGL.screen=pygame.display.set_mode((600,600),pygame.OPENGL|pygame.DOUBLEBUF|pygame.HWSURFACE)Now that this display has been marked as an OpenGL display, we will no longer be able to use any of Pygame's rendering functionality on this display. So lets create a regular Pygame surface. We will use this for all of our games rendering. For this tutorial ill keep the Surface the same size as the display but you could make it smaller or larger if you like.display=pygame.Surface((600,600))Note: When using pygame_shaders. Its good practice to set a transparent color for the surface so we can apply a background shader later. To do this I will set the color key to black.display.set_colorkey((0,0,0))Finally! Lets create our shader. For this tutorial our shader will simpily take our Surface we created above and render it to the OpenGL display. The vertex and fragment shader will look like this.vertex.glsl:#version 330 corelayout(location=0)invec3vertexPos;layout(location=1)invec2vertexTexCoord;outvec3fragmentColor;outvec2fragmentTexCoord;voidmain(){gl_Position=vec4(vertexPos,1.0);fragmentColor=vertexColor;fragmentTexCoord=vertexTexCoord;}fragment.glsl:#version 330 coreinvec3fragmentColor;invec2fragmentTexCoord;outvec4color;uniformsampler2DimageTexture;voidmain(){color=texture(imageTexture,fragmentTexCoord);}Note: All vertex shaders requirelayout (location=0) in vec3 vertexPos;andlayout (location=1) in vec3 vertexTexCoord;if you would like to access texture coordinates.Now lets create our Pygame shader! Ill give it a size the same as our display (600, 600) and a position of (0, 0) Note: (0, 0) in a shader = middle of the screen.shader=pygame_shaders.Shader(size=(600,600),display=(600,600),pos=(0,0),vertex_path="shaders/vertex.txt",fragment_path="shaders/default_frag.txt")Congrats! You have created your first shader using pygame_shaders!Using the shaderNow that you have created your shader. Its time to use it. Right now our code looks something like this:importpygameimportpygame_shadersscreen=pygame.display.set_mode((600,600),pygame.OPENGL|pygame.DOUBLEBUF|pygame.HWSURFACE)display=pygame.Surface((600,600))display.set_colorkey((0,0,0))shader=pygame_shaders.Shader(size=(600,600),display=(600,600),pos=(0,0),vertex_path="shaders/vertex.txt",fragment_path="shaders/default_frag.txt")This is all the setup the shader requires. Now you can continue with your Pygame project as normal. With the exception of a few things.First things first, at the top of your games main loop addpygame,shaders.clear(BG_COLOR)this will clear the display with your color of choice. Lets go with (100, 100, 100)pygame_shaders.clear((100,100,100))From here you can go on as normal. Using pygames usual rendering functions. Just remember to blit to the pygame.Surface and not the OpenGL display.Finally, when updating the display remeber to addshader.render(display)this will take the display surface and render it to the OpenGL display we created earlier. Remember, this will apply the shader (vertex.glsl and fragment.glsl) you wrote above.Putting everything together looks like this:importpygameimportpygame_shaderspygame.init()screen=pygame.display.set_mode((600,600),pygame.OPENGL|pygame.DOUBLEBUF|pygame.HWSURFACE)display=pygame.Surface((600,600))display.set_colorkey((0,0,0))shader=pygame_shaders.Shader(size=(600,600),display=(600,600),pos=(0,0),vertex_path="shaders/vertex.txt",fragment_path="shaders/default_frag.txt")whileTrue:pygame_shaders.clear((100,100,100))#Fill with the color you would like in the backgrounddisplay.fill((0,0,0))#Fill with the color you set in the colorkeyforeventinpygame.event.get():ifevent.type==pygame.QUIT:pygame.quit()pygame.draw.rect(display,(255,0,0),(20,20,20,20))#Draw a red rectangle to the display at (20, 20)shader.render(display)#Render the display onto the OpenGL display with the shaders!pygame.display.flip()Congratulations! You have created your first shader using pygame_shaders!