**This is an old revision of the document!**

组件:GPU

此组件由显卡提供。对简单程序而言只需使用term(终端) API即可满足需求。而为了实现更复杂的操作或提高运行性能,你可能会需要直接与GPU交互。

OC 1.3中的2级与3级屏幕有16色的调色板。调色板的作用是决定显示RGB颜色时使用的具体颜色。

对二级屏幕而言,调色板包含的颜色即为屏幕能显示的所有颜色,默认为Minecraft的16种标准颜色。这种特性带来的副作用是你可以使用例如这样的写法:gpu.setBackground(colors.red, true)(使用color API而不是16进制颜色,见函数的描述)。请注意这种写法仅可用于2级屏幕

3级屏幕也有可编辑的16色调色板,同时还有240色的固定调色板。可编辑调色板默认为灰度值,其余的240色为缩减过的RGB颜色值,与OC模组早期版本的情况相同。

组件名:gpu

回调函数:

  • 显存缓冲区
    此处的组件API列表已经很长了,因此新加入的显存API在此页面下方自己的章节处列出。
    这些函数在1.7.5 Developer builds版本的OC加入,会在下个发行版(OC 1.8)推出。
  • bind(address: string[, reset: boolean=true]): boolean[, string]
    尝试将GPU绑定到给定地址对应的屏幕。若成功返回true,若失败返回false和一条报错信息。若reset参数为true则重置屏幕的设置。 一个GPU同一时间只能被绑定到一块屏幕。在其上进行的一切操作都会在所绑定的屏幕上进行。如果你希望同时控制多块屏幕,则需要在电脑中安装多张显卡。
  • getScreen():string
    获取GPU绑定的屏幕的地址。此函数自1.3.2起添加。
  • getBackground(): number, boolean
    获取当前的背景色。背景色会被应用于一切其他操作改动的“像素”上。 请注意返回值可能是16进制的RGB颜色值,即0xRRGGBB,也可能是调色板索引号。第二个返回值代表了第一个返回值是上述哪一种(true代表调色板颜色, false代表RGB颜色值)。
  • setBackground(color: number[, isPaletteIndex: boolean]): number[, index]
    设定应用于此后其他操作修改的“像素”上的背景色。返回值为旧背景色,为其实际值(即未被压缩到当前设定的色彩空间的值)。第一个返回值为先前颜色的RGB颜色值。若颜色来自调色板,则第二个返回值为其在调色板中的索引号,否则为nil
    请注意调用时给定的颜色值需要为16进制RGB颜色值,即0xRRGGBB。这是为了能统一颜色操作,而无需考虑屏幕或GPU支持的色深。
  • getForeground(): number, boolean
    类似getBackground,但是为前景色。
  • setForeground(color: number[, isPaletteIndex: boolean]): number[, index]
    类似setBackground,但是为前景色。
  • getPaletteColor(index: number): number
    获取调色盘中指定索引号对应颜色的RGB颜色值。
  • setPaletteColor(index: number, value: number): number
    设定调色盘中指定索引号对应颜色的RGB颜色值。
  • maxDepth(): number
    获取GPU与其绑定屏幕支持的最大色深(二者取较小值)。
  • getDepth(): number
    获取GPU/屏幕当前设定的色深,单位为位(bit)。值可为1、4或8。
  • setDepth(bit: number): string
    设定要使用的色深。最大值可以为硬件支持的最大色深。若给定值超出范围或无效则会抛出错误。返回值为旧的色深,取值可为下列字符串之一:OneBitFourBitEightBit
  • maxResolution(): number, number
    获取GPU与其绑定屏幕支持的最大分辨率(二者取较小值)。
  • getResolution(): number, number
    获取当前设定的分辨率。
  • setResolution(width: number, height: number): boolean
    设定分辨率。最大值可以为硬件支持的最大分辨率。若给定值超出范围或无效则会抛出错误。若分辨率成功修改则返回true(尝试将分辨率设定为与当前分辨率相同也可能会返回false),若失败则返回false
  • getViewport(): number, number
    获取当前可见区域的分辨率。
  • setViewport(width: number, height: number): boolean
    设定当前可见区域的分辨率。若修改成功则返回true(尝试将分辨率设定为与当前分辨率相同也可能会返回false),若失败则返回false。此操作会使得屏幕分辨率看上去降低,但实际分辨率仍然不变。超出指定区域左上角的字符只是隐藏不显示,此功能是为了能在屏幕外渲染或显示内容,并在需要时将它们复制到可视区域内。改动分辨率会将可见区域修改为与分辨率相同。
  • getSize(): number, number
    获取显卡绑定到的屏幕的尺寸,大小为格。对单方块屏幕和机器人而言只有一个。
    已废弃,请改用screen.getAspectRatio()
  • get(x: number, y: number): string, number, number, number or nil, number or nil
    获取指定坐标处当前显示的字符。第二个与第二个返回值是前景和背景色,形式为16进制值。若颜色来自调色盘,第四个和第五个返回值将代表颜色的调色板索引号,否则为nil
  • set(x: number, y: number, value: string[, vertical:boolean]): boolean
    向屏幕写一条字符串,从指定坐标开始。字符串将会被直接复制到屏幕缓冲区,仅复制到单行。这意味着就算有换行符给定字符串也不会换行,换行符只会被以特殊字符的形式显示,字符串不会以多行显示。若字符串被成功传输给缓冲区则返回true,若失败则返回false
    第四个参数为可选参数,若为true可以使给定文本竖行显示。
  • copy(x: number, y: number, width: number, height: number, tx: number, ty: number): boolean
    将屏幕缓冲区的一部分复制到另一个位置。复制来源为矩形,由xywidthheight参数决定。目标位置由x + txy + tywidthheight决定(即txty为相对坐标)。若成功返回true,若失败返回false
  • fill(x: number, y: number, width: number, height: number, char: string): boolean
    用指定字符填充屏幕缓冲区中的一个矩形区域。目标矩形区域由xy坐标以及矩形的width(宽度)和height(高度)决定。填充字符参数char必须是长度为1的字符串,即单个字符。若成功返回true,若失败返回false
    请注意用空格( )填充屏幕通常耗能更少,因为此操作被视为“清除”操作(见配置文件)。

使用例:

snippet.lua
local component = require("component")
local gpu = component.gpu --获取首选GPU组件
local w, h = gpu.getResolution()
gpu.fill(1, 1, w, h, " ") --清空屏幕
gpu.setForeground(0x000000)
gpu.setBackground(0xFFFFFF)
gpu.fill(1, 1, w/2, h/2, "X") --填充屏幕的左上四分之一区域
gpu.copy(1, 1, w/2, h/2, w/2, h/2) --将屏幕的左上四分之一复制到右下

GPU色深

色深(参见gpu.setDepthgpu.getDepth)可以为1、4或8位,前景与背景色的色深可以不同。这三种色深分别可以提供2、16和256色。

颜色值(传递给gpu.setBackgroundgpu.setForegroundnumber型参数)会被解释为每通道8位的RGB颜色值(24位色)或某个调色板索引号。

RGB颜色

调用setBackgroundsetForeground时需要用到前景色与背景色,它们由value(数字型)和is_palette(布尔型)这一对变量定义(后者为可选)。

is_palettefalse(或nil),value将被理解为24位RGB颜色值(0xRRGGBB),无论色深如何。但是给定颜色将会被取近似值为当前色深中与其最接近的颜色。单色的情况下,只有0会近似为0,任何非零值都会近似为1(代表使用设定好的那种颜色)。在4位色的情况下,会近似取调色盘中最接近的颜色。在8位色的情况下,会近似取可用的256种颜色种最接近的颜色。256种可用颜色如下表所示:

图片由Eunomiac制作

Palette Color

When is_palette is true, value is interpreted as palette index [0, 16). If you switch from a higher bit density to monochrome note that the color value from the palette is used to determine zero vs the nonzero monochrome color. It is an error to specify a paletted color (i.e. an index value and true) in 1 bit depth.

Changing Depth

Note that the original color pair (the value number and palette bool) are preserved (background and foreground each) even when switching bit depths. The actual rendering on the screen will update to respect the new depth, but the original 24bit rgb value (or palette index) is not lost. For example, calling gpu.getBackground while in 1 bit mode will return the original 24 bit rgb value specified from any previous color depth.

Video Ram Buffers

A GPU card has internal memory that you can allocate into pages. You can specify a custom page size (width and height each must be greater than zero). The total memory of a GPU is reduced by the width*height of an allocation. Each tier of gpu has more total memory than the last. Each page buffer acts like an offscreen Screen with its own width, height, and color. The max color depth of a gpu buffer is based on the gpu tier. Rebooting a machine releases all bufffers.

Each page buffer has its own index; the gpu finds the next available index. Index zero (0) has a special meaning, it is reserved for the screen. Whether a gpu is bound to a screen or not, you can allocate pages, set them active, and read/write to them. Attaching and detaching a screen, even binding to a new screen, does not release the gpu pages. When a computer shuts off or reboots, the pages are released. Each GPU has its own video memory and pages.

Budget and Energy Costs

Updates to vram (set, copy, fill, etc) are nearly free. They have no energy cost and no additional budget cost. Every direct component invoke (and these gpu methods are direct) has a tiny system minimum budget cost, but the gpu itself in these vram updates adds no additional cost. When bitblt'ing the vram to the screen there is some cost, similar to how updates to the screen normally incur a cost. A dirty (modified) vram back buffer has a one time budget cost that increases with the size of the source buffer. Subsequent bitblts from a clean back buffer to the screen have extremely low costs.

  • getActiveBuffer(): number
    Returns the index of the currently selected buffer. 0 is reserved for the screen, and may return 0 even when there is no screen
  • setActiveBuffer(index: number): number
    Sets the active buffer to index. 0 is reserved for the screen and can be set even when there is no screen. Returns nil for an invalid index (0 is valid even with no screen)
  • buffers(): table
    Returns an array of all current page indexes (0 is not included in this list, that is reserved for the screen).
  • allocateBuffer([width: number, height: number]): number
    Allocates a new buffer with dimensions width*heigh (gpu max resolution by default). Returns the index of this new buffer or error when there is not enough video memory. A buffer can be allocated even when there is no screen bound to this gpu. Index 0 is always reserved for the screen and thus the lowest possible index of an allocated buffer is always 1.
  • freeBuffer([index: number]): boolean
    Removes buffer at index (default: current buffer index). Returns true if the buffer was removed. When you remove the currently selected buffer, the gpu automatically switches back to index 0 (reserved for a screen)
  • freeAllBuffers()
    Removes all buffers, freeing all video memory. The buffer index is always 0 after this call.
  • totalMemory(): number
    Returns the total memory size of the gpu vram. This does not include the screen.
  • freeMemory(): number
    Returns the total free memory not allocated to buffers. This does not include the screen.
  • getBufferSize([index: number]): number, number
    Returns the buffer size at index (default: current buffer index). Returns the screen resolution for index 0. Returns nil for invalid indexes
  • bitblt([dst: number, col: number, row: number, width: number, height: number, src: number, fromCol: number, fromRow: number])
    Copy a region from buffer to buffer, screen to buffer, or buffer to screen. Defaults:
    • dst = 0, the screen
    • col, row = 1,1
    • width, height = resolution of the destination buffer
    • src = the current buffer
    • fromCol, fromRow = 1,1 bitblt should preform very fast on repeated use. If the buffer is dirty there is an initial higher cost to sync the buffer with the destination object. If you have a large number of updates to make with frequent bitblts, consider making multiple and smaller buffers. If you plan to use a static buffer (one with few or no updatse), then a large buffer is just fine. Returns true on success

目录