mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-25 03:55:11 +01:00
Updated MapRendering (markdown)
parent
bd8d546a5d
commit
7f59118275
86
Map-Rendering.md
Normal file
86
Map-Rendering.md
Normal file
@ -0,0 +1,86 @@
|
||||
# Introduction
|
||||
Minecraft maps usually hold a 128x128 image representing an aerial view of an area.
|
||||
This is done by saving a 128x128 image inside the map data and rendering it.
|
||||
|
||||
The thing is... the server decides the contents, and there is no requirement to show an aerial view.
|
||||
This means that maps can serve as arbitrary 128x128 textures which can then be used for custom blocks, graphics and more.
|
||||
|
||||
# Writing map data - Low level API
|
||||
Minestom does not save map data for you, but it will send it for you.
|
||||
At the most basic level, map framebuffers (the 128x128 pixel area the server draws on) hold the 1-byte indices of colors in a pre-determined color palette, but not RGB.
|
||||
|
||||
Once you have selected a map ID to write to (see [MapMeta](https://github.com/Minestom/Minestom/blob/master/src/main/java/net/minestom/server/item/metadata/MapMeta.java) for more information), you can write its contents via a `MapDataPacket`:
|
||||
|
||||
```java
|
||||
MapDataPacket mapData = new MapDataPacket();
|
||||
mapData.mapId = YOUR_MAP_ID;
|
||||
mapData.data = YOUR_PIXELS;
|
||||
mapData.x = X_START;
|
||||
mapData.z = Z_START;
|
||||
mapData.rows = ROW_COUNT;
|
||||
mapData.columns = COLUMN_COUNT;
|
||||
```
|
||||
|
||||
* `mapId` is an `int` to be able to reference which map to change.
|
||||
* `data` is a `byte[]` array which holds the indices inside the color palette. Its size should be at least `rows*columns`.
|
||||
* `x` is an unsigned byte (stored inside a `short`) which represents the X coordinate of the left-most pixel to write. Ranges from 0 to 127 (inclusive).
|
||||
* `y` is an unsigned byte (stored inside a `short`) which represents the Y coordinate of the top-most pixel to write. Ranges from 0 to 127 (inclusive).
|
||||
* `rows` is an unsigned byte (stored inside a `short`) which represents the number of rows to update.
|
||||
* `rows` is an unsigned byte (stored inside a `short`) which represents the number of columns to update.
|
||||
|
||||
Pixels are stored in a row-major configuration (ie index is defined by `x+width*y`). Attempting to write pixels outside of the 128x128 area WILL crash and/or disconnect the client, so be careful. Minestom does not check which area you are writing to.
|
||||
|
||||
You can then send the packet to player through `PlayerConnection#sendPacket(ServerPacket)`
|
||||
|
||||
# Framebuffers - High level API
|
||||
While directly writing to the pixel buffer is fast and easy for simple graphics, it is rapidly cumbersome to write each pixel individually.
|
||||
For this reason, Minestom provides framebuffers: a high-level API for rendering onto maps.
|
||||
|
||||
Framebuffers are split into 2 categories: `Framebuffer` and `LargeFramebuffer`.
|
||||
The difference is that `Framebuffer` is meant to render to a single map (so resolution limited to 128x128), while `LargeFramebuffer` can render to any framebuffer size, by rendering over multiple maps. Large framebuffers offer a method to create `Framebuffer` views to help with rendering onto a map.
|
||||
|
||||
Once you have finished rendering on your framebuffer, you can ask it to prepare the `MapDataPacket` for you.
|
||||
|
||||
```java
|
||||
MapDataPacket mapData = new MapDataPacket();
|
||||
mapData.mapId = YOUR_MAP_ID;
|
||||
Framebuffer fb = //...
|
||||
// some render code
|
||||
fb.preparePacket(packet);
|
||||
```
|
||||
|
||||
Framebuffers have 3 default flavors provided by Minestom: Direct, Graphics2D and GLFW-Capable.
|
||||
|
||||
## `DirectFramebuffer` / `LargeDirectFramebuffer`
|
||||
Direct framebuffers are very close to writing directly the pixel buffer inside `MapDataPacket`.
|
||||
They hold an internal `byte[]` representing the colors on the map, which can be accessed and modified through `get` and `set` respectively.
|
||||
The entire internal buffer is also exposed via `getColors()` (you can modify it from the returned value).
|
||||
|
||||
Example use:
|
||||
```java
|
||||
DirectFramebuffer fb = new DirectFramebuffer();
|
||||
byte[] colors = fb.getColors();
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
colors[i] = MapColors.COLOR_CYAN.baseColor();
|
||||
}
|
||||
fb.set(0,0, MapColors.DIRT.baseColor());
|
||||
```
|
||||
|
||||
## `Graphics2DFramebuffer` / `LargeGraphics2DFramebuffer`
|
||||
As the name suggests, these framebuffers allow usage of the Graphics2D API from the AWT library included in the Java standard library.
|
||||
Access the `Graphics2D` object through `getRenderer()` and render your content on it.
|
||||
|
||||
Example use:
|
||||
```java
|
||||
Graphics2D renderer = framebuffer.getRenderer();
|
||||
renderer.setColor(Color.BLACK);
|
||||
renderer.clearRect(0, 0, 128, 128);
|
||||
renderer.setColor(Color.WHITE);
|
||||
renderer.drawString("Hello from", 0, 10);
|
||||
renderer.drawString("Graphics2D!", 0, 20);
|
||||
```
|
||||
|
||||
Graphics2D framebuffers also support getting/setting pixels individually if necessary.
|
||||
|
||||
## GLFW-Capable buffers
|
||||
[This is an article all to itself.](https://github.com/Minestom/Minestom/wiki/GLFWMapRendering)
|
@ -1 +0,0 @@
|
||||
WIP
|
Loading…
Reference in New Issue
Block a user