Skip to content
MarkelZ edited this page Dec 13, 2023 · 6 revisions

Other questions

If your question does not appear here, feel free to open an issue in the issue tracker.

How can I access the OpenGL objects of the engine?

Take a look at Accessing OpenGL Objects.

How can I repeat a tileable texture?

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))

How can I permanently update a texture?

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.

How can I apply two shaders in series to the same texture?

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.

I have a memory leak, how can I fix it?

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:

  1. Use pygame to draw text with the current FPS on a Surface object.
  2. Turn the Surface object into a OpenGL Texture object using this engine's surface_to_texture function.
  3. 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.

Why does my game run so slowly?

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.

Why does my texture look pixelated when I scale it?

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)

Why does my texture look blurry when I upscale it?

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)