High Level Peripherals
作者:rebot | 分类:模组
Minecraft 版本: 1.21.1
平台: neoforge
High Level Peripherals
A CC:Tweaked monitor peripheral that actually keeps up with what you want to build.
A fork of Tom's Peripherals, rebuilt to be far more usable, stable, and complete —
bigger screens, real GPU-rendered shaders, full mouse/touch input, and a cleaner API
that doesn't fight you.
✨ Features
?️ Big, sharp monitors
Build arrays up to 32x32 blocks (admin-adjustable up to 64x64), with per-block
resolution up to 4096x4096. Draw with a full 2D API — filled shapes, gradients, text
with custom fonts, image loading, double buffering — all running server-side, synced
to every client automatically.
⚡ Real GPU shaders, not Lua math
Write a small GLSL-like shader once and it renders live on every viewer's own
graphics card, at their own framerate, completely decoupled from the server tick.
No more choking the game with per-pixel Lua raymarching — the shader engine handles
that with zero Lua involved per pixel. Includes first-class raytracing primitives
(sphere/plane/box intersection) so you're not hand-rolling ray math from scratch.
gpu.compileShader([[
color = vec3(uv.x, uv.y, sin(time));
]])
That's it — it's already rendering.
?️ Full mouse input
Click, right-click, drag, and scroll directly on a monitor's screen face, with
pixel-accurate coordinates delivered straight to your script. Respects whatever
controls the player has configured — no hardcoded key assumptions. Perfect for
building actual interactive UIs, not just static displays.
? 3D immediate-mode rendering
An OpenGL-1-style API (glBegin/glVertex/glTranslate/glRotate/lighting) for
building real 3D scenes on a monitor without writing a shader — great for models,
diagrams, or simple games.
? Brightness control
Scale a monitor's output brightness in nits, from dim ambient displays to
eye-searingly bright — applies to both drawn pixels and live shaders.
? Room to build big
Generous default VRAM budget (~2 GiB per screen) shared across framebuffers, images,
and shader textures, with server-configurable limits for bigger builds.
Why this fork?
Tom's Peripherals gave monitors and a GPU peripheral, but hit real ceilings fast —
low resolution limits, no shader rendering, no mouse input, and a handful of
long-standing multiblock/sync bugs. High Level Peripherals keeps the same familiar
peripheral.find("tm_monitor") API you already know, and pushes every one of those
ceilings out — so your builds stop being limited by the peripheral and start being
limited by your imagination.
Getting started
local gpu = peripheral.find("tm_monitor")
gpu.fill(0x000000)
gpu.drawText(10, 10, "Hello, HLPS!", 0xFFFFFF)
Full API reference below.
Docs
tm_monitor Lua API Reference
Complete reference for the monitor peripheral: 2D drawing, text, images, the 3D
immediate-mode API, mouse/scroll input, and the shader engine.
1. Limits
| Limit | Value |
|---|---|
| Grid size | Up to 32x32 blocks by default (maxScreenSize, 1-64). Over limit → every call throws. |
gpu.setSize(n) |
64–4096 px/axis, default 1024. |
gpu.setGpuResolution(w, h) |
64–4096 px/axis, or (0,0) for auto. |
| VRAM budget | ~2 GiB default (maxVRAMSize), shared across framebuffer/images/buffers/textures. |
2. Color format
Packed 0xRRGGBB ints, or (r,g,b[,a]) 0-255 each.
- Alpha
0or255→ opaque. - Alpha
1..254→ source-over blend:out = (src*a + dst*(255-a)) / 255. getPixel/getpxreturn0xRRGGBB(alpha stripped).
3. Sizing
| Call | Effect |
|---|---|
gpu.setSize(n) |
Per-block resolution, one axis. Total canvas is (blocksWide*n) x (blocksTall*n). |
gpu.getSize() |
→ width, height, cols, rows, blockSize. |
gpu.getResolution() |
→ width, height. |
gpu.refreshSize() |
Forces a re-scan of the array's grid layout. |
gpu.debugTiling() |
→ string dump of live server-side tiling state, for diagnosing a wrong-looking array. |
Keep setSize low (64-256) if drawing per-pixel in Lua — use the shader engine
(section 8) instead for anything procedural.
4. Basic 2D drawing
All coordinates are 1-based.
| Call | Notes |
|---|---|
gpu.fill([color]) |
Fills the canvas. Default black. |
gpu.clear([color]) |
Alias of fill. |
gpu.setPixel(x, y, color) |
Out-of-bounds writes ignored. |
gpu.getPixel(x, y) |
→ int, 0 if out of bounds. |
gpu.filledRectangle(x, y, w, h, [color]) |
Throws if out of bounds. |
gpu.rectangle(x, y, w, h, [color]) |
Outline only. |
gpu.line(x1, y1, x2, y2, [color]) |
Bresenham. |
gpu.lineS(x1, y1, x2, y2, [color]) |
Alternate algorithm. |
gpu.circle(cx, cy, r, [color]) |
Outline. |
gpu.fillCircle(cx, cy, r, [color]) |
Filled. |
gpu.triangle(x1,y1, x2,y2, x3,y3, [color]) |
Outline. |
gpu.fillTriangle(x1,y1, x2,y2, x3,y3, [color]) |
Filled. |
gpu.gradientRectangle(x, y, w, h, c1, c2, [vertical]) |
Linear interpolation between two colors. |
gpu.copy(srcX, srcY, w, h, dstX, dstY) |
Overlap-safe. Capped at 64M px. |
gpu.scroll(dx, dy, [fillColor]) |
Shifts canvas; exposed area filled. Same cap. |
gpu.drawBuffer(x, y, w, scale, ...pixels) |
Row-major pixels as vararg numbers, not a table. |
5. Double buffering
gpu.setDoubleBuffered(true)
-- ... draw calls ...
gpu.flush() -- presents + syncs
gpu.sync() pushes the framebuffer directly (throttled internally) — not usually
needed outside double-buffering/shader flows.
6. Text
| Call | Notes |
|---|---|
gpu.drawText(x, y, text, [fg=-1], [bg=-1], [size=1], [pad=1]) |
-1 skips that layer. |
gpu.drawTextSmart(x, y, text, [fg], [bg], [forceUnicode=false], [size=1], [pad=1]) |
Auto ASCII/unicode fonts (ASCII draws at 2x size). |
gpu.getTextLength(text, [size=1], [pad=1]) |
→ pixel width. |
gpu.getFont() |
→ name, editable. |
gpu.setFont(name) |
No-op if font doesn't exist. |
gpu.drawChar(x, y, charIndex, [fg], [bg], [size=1]) |
Draws one glyph, 1-based index. |
gpu.addNewChar(char, width, ...16 numbers) |
→ int. Font must be editable. |
gpu.delChar(char) / gpu.freeChars() / gpu.clearChars() |
Glyph management. |
gpu.setFontDefaultCharID(id) / gpu.getFontDefaultCharID() |
Fallback glyph. |
7. Images and buffers
| Call | Returns |
|---|---|
gpu.newImage(w, h) |
Blank LuaImage. |
gpu.imageFromBuffer(w, ...pixels) |
LuaImage from raw pixel data. |
gpu.decodeImage(bufferRef) / gpu.decodeImage(...bytes) |
Decodes PNG/etc. |
gpu.newBuffer([initialCapacity=32]) |
Growable LuaByteBuffer. |
gpu.drawImage(x, y, image) |
Draws, clipped to canvas. |
All charge VRAM (w*h*4 bytes) up front and throw if over budget.
8. The shader engine
Write a small GLSL-like program once; it runs per-pixel on the real GPU, no Lua
involved.
gpu.compileShader([[
float sdSphere(vec3 p, float r) { return length(p) - r; }
uniform float speed;
color = vec3(uv.x, uv.y, sin(time * speed));
]])
gpu.setUniform("speed", 2.0)
There's no main — code after the function defs runs top-to-bottom; color is the
pixel output. gpu.clearShader() returns to normal 2D drawing.
gpu.isGpuMode()→truewhile a shader is live.gpu.setUniform(name, value)/gpu.setUniform3(name, x, y, z)— live-update, no recompile.gpu.setGpuResolution(w, h)— resolution the shader renders at (independent of
setSize). Match your array'scols:rowsshape or don't call it.
A live shader has no ongoing tie to the computer that started it — it stops only if
the last attached computer disconnects, or you call gpu.clearShader().
texture() isn't GPU-accelerated yet — a texture-sampling shader compiles fine
but won't auto-render. Drive it yourself:
gpu.compileShader(src)
gpu.uploadTexture(0, w, h, pixels)
while true do
gpu.runShader(os.clock())
gpu.sync()
sleep(0)
end
Shader language
- Two types:
float,vec3. - Predefined:
color(write this),uv(.x/.y0..1,.y=0at top),res,time. uniform <float|vec3> name;- Functions:
<float|vec3> name(params) { ...; return expr; }. No recursion. Must
appear before any other top-level statement, includinguniformdeclarations. - Control flow:
if/else,for (init; cond; update) {},break;,return expr;. - Operators:
+ - * /, unary- !, comparisons,&& ||,.x .y .zswizzle.
vec3 * floatworks;float * vec3does not. - Built-ins:
vec3(f,f,f),sin cos tan sqrt abs floor fract exp pow mod min max step clamp mix smoothstep length dot cross normalize reflect,texture(slot, u, v). - Raytracing builtins (return nearest positive hit distance, or
-1.0for a miss):
intersectSphere(ro, rd, center, radius),intersectPlane(ro, rd, planeY),
intersectBox(ro, rd, center, halfSize).
9. Memory
| Call | Returns |
|---|---|
gpu.getUsedMemory() |
Bytes currently used. |
gpu.getMaxMemory() |
VRAM budget for this peripheral. |
10. Mouse & scroll input
Fires only while looking at the screen face with no GUI open. Sneaking has no effect.
Keyboard input isn't captured here — that's a separate keyboard peripheral.
| Event | Args | Trigger |
|---|---|---|
tm_monitor_touch |
side, x, y, soft |
Whichever button is bound to "use" (right-click by default). soft is always false. |
tm_monitor_mouse |
side, x, y, button, action |
Mouse button press/release. |
tm_monitor_scroll |
side, x, y, dir |
dir is 1 (up) or -1 (down). |
tm_monitor_drag |
side, x, y, button |
Cursor moved this tick while held. Once per client tick. |
x, y are screen-absolute (1-based) across the whole array.
while true do
local ev, side, x, y, button, action = os.pullEvent("tm_monitor_mouse")
gpu.setPixel(x, y, 0xFF0000)
gpu.sync()
end
11. 3D immediate-mode API
gpu3d = gpu.createWindow3D(...)
gpu3d.glFrustum(70, 0.1, 100)
gpu3d.glLoadIdentity()
gpu3d.glTranslate(0, 0, -5)
gpu3d.glDirLight(0, -1, 0)
gpu3d.glBegin(4) -- triangles
gpu3d.glColor(0xFF0000)
gpu3d.glVertex(-1, -1, 0)
gpu3d.glVertex( 1, -1, 0)
gpu3d.glVertex( 0, 1, 0)
gpu3d.glEnd()
gpu3d.render()
gpu3d.sync()
| Call | Notes |
|---|---|
glFrustum(fov, near, far) |
Perspective projection. |
glDirLight(x, y, z) |
Directional light. |
glLoadIdentity() / glPushMatrix() / glPopMatrix() |
Model matrix stack. |
glTranslate / glScale / glRotate(angleDeg, x,y,z) |
|
glBegin([mode=4]) / glEnd() |
Start/finish a primitive. |
glVertex(x,y,z) |
Appends a vertex with current color/UV. |
glTexCoord(u,v) |
UV for the next vertex. |
glColor(color) |
Packed int or (r,g,b[,a]). |
glEnable(3553) / glDisable(3553) |
Only GL_TEXTURE_2D supported. |
glGenTextures() / glDeleteTextures / glBindTexture / glTexImage |
Texture management. |
getConstants() |
GL constant name→value table. |
render() |
Culls, lights, clips, projects, sorts, blits since last clear(). |
clear() |
Wipes canvas + triangles + resets matrix/depth buffer. |
12. Performance
All drawing is server-side Java, always — singleplayer, LAN, or dedicated. Pushing
pixels to the client is the one real client cost, done via a bulk memory copy.
Per-pixel Lua drawing (raymarching, plasma, etc.) will choke a client — use the shader
engine instead, which runs on the GPU with zero Lua per pixel.
13. Brightness (nits)
gpu.setBrightness(200) -- 2x normal
print(gpu.getBrightness())
nits / 100 scales final pixel output — 100 is default (1.0x). Applies to both CPU
drawing and GPU shaders. Values that would exceed 255 clip instead of wrapping. Range
is server-configurable (minBrightnessNits/maxBrightnessNits, default 10–400).
请登录后举报
暂无评论,抢个沙发吧~