mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-18 05:22:42 +01:00
Remove whitespace, simplify link, eof newline
@@ -5,7 +5,6 @@ The OpenGL renderer implementation is based around the idea of batching as many
|
||||
Draw commands are queued in so-called command buffers, named after the constructs in the OpenGL `GL_NV_command_list` extension and Vulkan API. There are three possible draw calls and their parameters are defined in structs that can be found in the `src/drawing/engines/opengl/DrawCommands.h` file. The parameters are derived directly from the OpenGL implementation before it was optimized.
|
||||
|
||||
## Texture map
|
||||
|
||||
To be able to execute many draw commands that access textures in one draw call, they all need to be accessible from the fragment shader simultaneously. Most OpenGL implementations only allow up to 32 texture samplers in a single shader, which is way too limited. There are two possible approaches to expose many textures to the shader at once: array textures and texture atlases. The OpenGL renderer in OpenRCT2 uses a hybrid approach: an array texture of atlases.
|
||||
|
||||
Pure array textures were quickly dismissed, because those too are limited to only 2048 elements on most implementations. Given that some frames contain over 10k+ sprites with many unique textures, this is simply not scalable enough. It was proposed to use multiple samplers in combination with multiple arrays, but unfortunately GLSL does not allow selecting a sampler using a dynamic index. Iterating over all of them would be bad for performance.
|
||||
@@ -19,11 +18,9 @@ Here are two examples of what atlases look like in the array texture (from Rende
|
||||
Once a texture is in an atlas like that, the draw command only needs 2 parameters to access the texture: the index of the atlas and the top-left to bottom-right coordinates within the atlas. The bottom-right coordinates are based on the actual size of the image and not the entire power-of-two block. As many atlases are created as needed when new textures come in, and the system can scale up to 2048 atlases simultaneously on most implementations.
|
||||
|
||||
## Rectangles and lines
|
||||
|
||||
Rectangles and lines are added to the command buffers, but are currently still processed as individual draw calls. This is because nearly all rectangles currently depend on previously rendered contents for correct transparency, and lines are so rarely used that it's not worth optimising them.
|
||||
|
||||
## Sprites and instanced rendering
|
||||
|
||||
Sprites make up over 99% of the draw calls per frame, so this is where effort was focused on when optimising the OpenGL renderer. Once the sprite command buffer is flushed, the parameters of each individual draw call are turned into a GPU friendly format and written to a vertex buffer. These parameters include the bounds, tertiary colour, texture atlas index, atlas coordinates, and so on. It may also include an atlas index and coordinates for a mask texture (raw sprites and masked sprites are combined). This data represents instance data for instanced rendering with `glDrawArraysInstanced`. The old shaders used uniforms to set the data for each sprite, and they were modified to instead load the data from the instance buffer. Instance data is provided as vertex attributes that are loaded per-instance with `glVertexAttribDivisor`.
|
||||
|
||||
## Conclusion
|
||||
@@ -32,4 +29,4 @@ When viewing most of the intro parks at a resolution of 2560x1440, up to 30,000
|
||||
Are there more optimization opportunities left? Definitely. The sprites are currently drawn by instancing over just 6 vertices (a quad), which is not something that drivers and GPUs are very fond of. It may be possible to achieve even higher frame rates by generating all of the vertices and not using instancing, but initial attempts to do this actually yielded worse performance. It is probably wise to explore more obvious opportunities first, like changing the OpenGL renderer to do dirt-only drawing. Initial tests have shown that this can lead to very significantly improved frame rates.
|
||||
|
||||
## Issues
|
||||
See [OpenGL-renderengine-issues](OpenGL-renderengine-issues)
|
||||
See [[OpenGL renderengine issues]]
|
||||
|
||||
Reference in New Issue
Block a user