FAQ
If your question does not appear here, feel free to open an issue in the issue tracker.
Take a look at Accessing OpenGL Objects.
When drawing a texture with render
, you can set the section
argument to a pygame.Rect
rectangle that is larger than the texture itself. For example, if you assign section
the dimensions of the screen, the engine will repeat the texture to cover the whole screen:
engine.render(texture, engine.screen, section=pygame.Rect(0, 0, screen_width, screen_height))
You can use layers for this, with engine.make_layer()
. You can render the texture to a layer that has the same
dimensions and use a shader with the effect you want (e.g. change the color). The
texture of the layer is layer.texture
, so you can just render this layer once during
initialization and use its texture for future renders.
You can create a new layer with the texture's dimensions using engine.make_layer()
, and render the texture to the layer with the first shader. Then, you can use the layer's texture and render it to the screen with the second shader. Done!
There's one thing you should be careful about though. Let's say that you need to render three shaders in series. You could do the same, create a new intermediate layer, and render the texture to it with the first shader. Now, to apply the second shader we can't just render it to the screen because we want to apply a third shader too, so one could try to render the texture of the intermediate layer onto itself. This is bad! You cannot take the texture of a layer and render it to this same layer. Instead, you need to use a double buffer method. So, you create two layers, A and B, and now you can chain as many shaders as you want by rendering A to B and then B to A. Hope this makes sense. My lighting engine needed precisely this, double_buff.py.
One way that memory leaks are commonly introduced with this engine is by forgetting to free the data of a temporary texture.
For example, if you want to render some text onto the screen to show the FPS of the game, you may be doing this:
- Use
pygame
to draw text with the current FPS on aSurface
object. - Turn the
Surface
object into a OpenGLTexture
object using this engine'ssurface_to_texture
function. - Render the texture with the engine's
render_texture
method.
Since you are creating a new texture in every frame of the game, you will have a memory leak unless you free the data of the temporary textures. To do so, you need to call release
on the texture after you render it:
texture.release()
You can also call release()
on other objects, such as Shader
and Layer
.
If your game runs slowly but in examples/example2.py
you can
render 1000 sprites at 60+ FPS, chances are that you are performing an expensive operation in every frame. This may include:
- Calling
surface_to_texture
in every frame with large textures. - Calling
load_texture
in every frame. - Calling
load_shader_from_path
in every frame. - Allocating a lot of memory in the fragment shader.
To solve these issues, load all the resources during initialization.
If the problem persists, you can open an issue in the issue tracker.
If you don't want the texture to look pixelated, you need to import LINEAR
from pygame_render import LINEAR
and set the filter of your texture to LINEAR
texture.filter = (LINEAR, LINEAR)
This also works with the texture of a layer:
layer.texture.filter = (LINEAR, LINEAR)
When upscaling, if you want the texture to look pixelated instead of blurry, you need to import NEAREST
from pygame_render import NEAREST
and set the filter of your texture to NEAREST
texture.filter = (NEAREST, NEAREST)
This also works with the texture of a layer:
layer.texture.filter = (NEAREST, NEAREST)