DoubleBuffering
Implementation of screen buffer for OpenComputers mod
Install / Use
/learn @IgorTimofeev/DoubleBufferingREADME
LEGACY ALERT
This library is no longer supported, since it has become part of the MineOS Screen API. Potential bugs will not be fixed
About
DoubleBuffering is a low-level library for efficient usage of GPU resources and rendering data on screen as fast as possible. For example, our 3D-engine with dynamic lighting, as well as a small game based on raycasting are realised with this library. And they give out acceptable FPS values:


The main concept of library is very simple: there are 6 tables stored in the RAM and containing information about pixels on the screen. The first 3 tables stores what is displayed at the moment, and the other 3 tables - what user is drawing to screen buffer in this moment. After performing all the drawing operations, user calls the buffer.drawChanges () function: library will automatically detect changed pixels, groups them into an temporary buffer by color values to reduce GPU calls, and finnaly will display result on screen.
Compared with standard linear rendering, the rendering with this library time is reduced by hundreds and thousands of times. The picture below shows this:

The price of such speed is an increased consumption of RAM. To minimize it, library uses the one-dimensional structure of the pixel data tables instead of the three-dimensional one. To obtain pixel data, special methods are used that convert screen coordinates to screen buffer indices and vice versa, more about this is written below in Auxiliary methods section.
In addition, this library doesn't access any Lua table directly, replacing them with constants aliases and avoiding calculation of hashes: for example, instead of instead of gpu.setBackground(...) library uses GPUSetBackground(...). With a competent implementation, this extremeley increases perfomance without loading Lua GC.
| Contents | | ----- | | Installation | | Main methods: | | buffer.getResolution | | buffer.setResolution | | buffer.bindScreen | | buffer.bindGPU | | Rendering methods: | | buffer.drawChanges | | buffer.setDrawLimit | | buffer.getDrawLimit | | buffer.copy | | buffer.paste | | buffer.set | | buffer.get | | buffer.drawRectangle | | buffer.clear | | buffer.drawText | | buffer.drawImage | | buffer.drawLine | | buffer.drawEllipse | | Semi-pixel rendering methods: | | buffer.semiPixelSet | | buffer.drawSemiPixelSquare | | buffer.drawSemiPixelLine | | buffer.drawSemiPixelEllipse | | buffer.drawSemiPixelCurve | | Auxiliary methods: | | buffer.flush | | buffer.getIndexByCoordinates | | buffer.getCoordinatesByIndex | | buffer.rawSet | | buffer.rawGet | | buffer.getCurrentFrameTables | | buffer.getNewFrameTables |
Installation
The easiest way is to use automatic installer that will download all necessary files for you via single command:
pastebin run vTM8nbSZ
However, you can download dependencies manually, if required. They are listed in the following table:
| Dependency | Description | Documentation | | ------ | ------ | ------ | | doubleBuffering | This library | - | | advancedLua | Addition to standard Lua libraries with a variety of functions: fast table serialization, text wrapping, binary data processing, etc. | https://github.com/Igor... | | color | Extrusion and packaging of color channels, conversion of the RGB color model to HSB and vice versa, the implementation of alpha blending, the generation of color transitions and the conversion of color into an 8-bit format for the OpenComputers palette | https://github.com/Igor... | | image | Implementation of the image standard for OpenComputers and basic methods of their processing: transpose, crop, rotate, reflection, etc. | - | | OCIF | The OpenComputers Image Format module for the image library, written with regard to the features of the mod and realizing effective compression of pixel data | - |
Main methods
buffer.getResolution(): int width, int height
Get screen buffer resolution. There's also buffer.getWidth() and buffer.getHeight() methods for your comfort.
buffer.setResolution( width, height )
| Type | Parameter | Description | | ------ | ------ | ------ | | int | width | Screen buffer width | | int | height | Screen buffer height |
Set screen buffer and GPU resolution. Content of buffer will be cleared with black pixels and whitespace symbol.
buffer.bindScreen( address )
| Type | Parameter | Description | | ------ | ------ | ------ | | string | address | Screen component address |
Bind the GPU used by library to the specified screen component address. Content of buffer will be cleared with black pixels and whitespace symbol.
buffer.bindGPU( address )
| Type | Parameter | Description | | ------ | ------ | ------ | | string | address | GPU component address |
Set the GPU component address is used by library. Content of buffer will be cleared with black pixels and whitespace symbol.
buffer.getGPUProxy( ): table GPUProxy
Get a pointer to currently bound GPU component proxy.
Rendering methods
buffer.drawChanges( [force] )
| Type | Parameter | Description | | ------ | ------ | ------ | | [boolean | force] | Force content drawing |
Draw contents of screen buffer on screen. If optional argument force is specified, then the contents of screen buffer will be drawn completely and regardless of the changed pixels.
buffer.setDrawLimit( x1, y1, x2, y2 )
| Type | Parameter | Description | | ------ | ------ | ------ | | int | x1 | First point coordinate of draw limit by x-axis | | int | y1 | First point coordinate of draw limit by y-axis | | int | x2 | Second point coordinate of draw limit by x-axis | | int | y2 | Second point coordinate of draw limit by y-axis |
Set buffer draw limit to the specified values. In this case, any operations that go beyond the limits will be ignored. By default, the buffer always has a drawing limit in the ranges x ∈ [1; buffer.width] and y ∈ [1; buffer.height]
buffer.getDrawLimit( ): int x1, int y1, int x2, int y2
Get currently set draw limit
buffer.copy( x, y, width, height ): table pixelData
| Type | Parameter | Description | | ------ | ------ | ------ | | int | x | Copied area coordinate by x-axis | | int | y | Copied area coordinate by y-axis | | int | width | Copied area width | | int | height | Copied area height |
Copy content of specified area from screen buffer and return it as a table. Later it can be used with buffer.paste(...).
buffer.paste( x, y, pixelData )
| Type | Parameter | Description | | ------ | ------ | ------ | | int | x | Paste coordinate by x-axis | | int | y | Paste coordinate by y-axis | | table | pixelData | Table with copied screen buffer data |
Paste the copied contents of screen buffer to the specified coordinates.
buffer.set( x, y, background, foreground, symbol )
| Type | Parameter | Description | | ------ | ------ | ------ | | int | x | Screen coordina
