Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
component:gpu:zh [2023/10/30 14:44]
hfsr [Budget and Energy Costs]
component:gpu:zh [2023/12/27 02:03] (current)
hfsr [资源配额与能耗]
Line 3: Line 3:
 此组件由[[item:​graphics_card:​zh|显卡]]提供。对简单程序而言只需使用[[api:​term:​zh|term(终端) API]]即可满足需求。而为了实现更复杂的操作或提高运行性能,你可能会需要直接与GPU交互。 此组件由[[item:​graphics_card:​zh|显卡]]提供。对简单程序而言只需使用[[api:​term:​zh|term(终端) API]]即可满足需求。而为了实现更复杂的操作或提高运行性能,你可能会需要直接与GPU交互。
  
-OC 1.3中的2级与3级屏幕有16色调色板。调色板的作用是决定显示RGB颜色时使用的具体颜色。+OC 1.3中的2级与3级屏幕有一个16色调色板。调色板的作用是决定显示RGB颜色时使用的具体颜色。
  
-级屏幕而言,调色板包含的颜色即为屏幕能显示的所有颜色,默认为Minecraft的16种标准颜色。这种特性带来的副作用是你可以使用如这样的写法:`gpu.setBackground(colors.red,​ true)`(使用color API而不是16进制颜色,见函数的描述)。请注意**这种写法仅可用于2级屏幕**。+2级屏幕而言,调色板包含的颜色即为屏幕能显示的所有颜色,默认为Minecraft的16种标准颜色。这种特性带来的副作用是你可以使用如这样的写法:`gpu.setBackground(colors.red,​ true)`(使用color API而不是16进制颜色,见下文函数的描述)。请注意**这种写法仅可用于2级屏幕**。
  
 3级屏幕也有可编辑的16色调色板,同时还有240色的固定调色板。可编辑调色板默认为灰度值,其余的240色为缩减过的RGB颜色值,与OC模组早期版本的情况相同。 3级屏幕也有可编辑的16色调色板,同时还有240色的固定调色板。可编辑调色板默认为灰度值,其余的240色为缩减过的RGB颜色值,与OC模组早期版本的情况相同。
Line 16: Line 16:
   此处的组件API列表已经很长了,因此新加入的显存API在此页面下方自己的章节处列出。  ​   此处的组件API列表已经很长了,因此新加入的显存API在此页面下方自己的章节处列出。  ​
   这些函数在1.7.5 Developer builds版本的OC加入,会在下个发行版(OC 1.8)推出。  ​   这些函数在1.7.5 Developer builds版本的OC加入,会在下个发行版(OC 1.8)推出。  ​
 +\\
 - `bind(address:​ string[, reset: boolean=true]):​ boolean[, string]`  ​ - `bind(address:​ string[, reset: boolean=true]):​ boolean[, string]`  ​
-  尝试将GPU绑定到地址对应的屏幕。若成功返回`true`,若失败返回`false`和一条报错信息。若`reset`参数为`true`则重置屏幕的设置。 +  尝试将GPU绑定到定屏幕。若成功返回`true`,若失败返回`false`和一条报错信息。若`reset`参数为`true`则重置屏幕的设置。 ​  
-  一个GPU同一时间只能被绑定到一块屏幕。在其上进行的一切操作都会在所绑定的屏幕上进行。如果你希望同时控制多块屏幕,则需要在电脑中安装多张显卡。+  一个GPU同一时间只能被绑定到一块屏幕。在其上进行的一切操作都会在所绑定的屏幕上进行。如果你希望同时控制多块屏幕,则需要在电脑中安装多张显卡。 ​  
 +\\
 - `getScreen():​string`  ​ - `getScreen():​string`  ​
-  获取GPU绑定的屏幕的地址。此函数自1.3.2起添加。+  获取GPU绑定的屏幕的地址。此函数自1.3.2起添加。 ​  
 +\\
 - `getBackground():​ number, boolean`  ​ - `getBackground():​ number, boolean`  ​
   获取当前的背景色。背景色会被应用于一切其他操作改动的“像素”上。   获取当前的背景色。背景色会被应用于一切其他操作改动的“像素”上。
-  请注意返回值可能是16进制的RGB颜色值,即`0xRRGGBB`,也可能是调色板索引号。第二个返回值代表了第一个返回值是上述哪一种(`true`代表调色板颜色, `false`代表RGB颜色值)。+  请注意返回值可能是16进制的RGB颜色值,即`0xRRGGBB`,也可能是调色板索引号。第二个返回值代表了第一个返回值是上述哪一种(`true`代表调色板颜色, `false`代表RGB颜色值)。 ​  
 +\\
 - `setBackground(color:​ number[, isPaletteIndex:​ boolean]): number[, index]`  ​ - `setBackground(color:​ number[, isPaletteIndex:​ boolean]): number[, index]`  ​
   设定应用于此后其他操作修改的“像素”上的背景色。返回值为旧背景色,为其实际值(即未被压缩到当前设定的色彩空间的值)。第一个返回值为先前颜色的RGB颜色值。若颜色来自调色板,则第二个返回值为其在调色板中的索引号,否则为`nil`。  ​   设定应用于此后其他操作修改的“像素”上的背景色。返回值为旧背景色,为其实际值(即未被压缩到当前设定的色彩空间的值)。第一个返回值为先前颜色的RGB颜色值。若颜色来自调色板,则第二个返回值为其在调色板中的索引号,否则为`nil`。  ​
-  请注意调用时给定的颜色值需要为16进制RGB颜色值,即`0xRRGGBB`。这是为了能统一颜色操作,无需考虑屏幕或GPU支持的色深。+  请注意调用时给定的颜色值需要为16进制RGB颜色值,即`0xRRGGBB`。这是为了能统一颜色操作,无需考虑屏幕或GPU支持的色深。 ​  
 +\\
 - `getForeground():​ number, boolean`  ​ - `getForeground():​ number, boolean`  ​
-  类似`getBackground`,但是为前景色。+  类似`getBackground`,但是为前景色。 ​  
 +\\
 - `setForeground(color:​ number[, isPaletteIndex:​ boolean]): number[, index]`  ​ - `setForeground(color:​ number[, isPaletteIndex:​ boolean]): number[, index]`  ​
-  类似`setBackground`,但是为前景色。+  类似`setBackground`,但是为前景色。 ​  
 +\\
 - `getPaletteColor(index:​ number): number`  ​ - `getPaletteColor(index:​ number): number`  ​
-  获取调色盘中指定索引号对应颜色的RGB颜色值。+  获取调色盘中指定索引号对应颜色的RGB颜色值。 ​  
 +\\
 - `setPaletteColor(index:​ number, value: number): number`  ​ - `setPaletteColor(index:​ number, value: number): number`  ​
-  设定调色盘中指定索引号对应颜色的RGB颜色值。+  设定调色盘中指定索引号对应颜色的RGB颜色值。 ​  
 +\\
 - `maxDepth():​ number`  ​ - `maxDepth():​ number`  ​
-  获取GPU与其绑定屏幕支持的最大色深(二者取较小值)。+  获取GPU与其绑定屏幕支持的最大色深(二者取较小值)。 ​  
 +\\
 - `getDepth():​ number`  ​ - `getDepth():​ number`  ​
-  获取GPU/​屏幕当前设定的色深,单位为位(bit)。值可为1、4或8。+  获取GPU/​屏幕当前设定的色深,单位为位(bit)。值可为1、4或8。 ​  
 +\\
 - `setDepth(bit:​ number): string`  ​ - `setDepth(bit:​ number): string`  ​
-  设定要使用的色深。最大值可以为硬件支持的最大色深。若给定值超出范围或无效则会抛出错误。返回值为旧的色深,取值可为下列字符串之一:`OneBit`、`FourBit`或`EightBit`。+  设定要使用的色深。最大值可以为硬件支持的最大色深。若给定值超出范围或无效则会抛出错误。返回值为旧的色深,取值可为下列字符串之一:`OneBit`、`FourBit`或`EightBit`。 ​  
 +\\
 - `maxResolution():​ number, number`  ​ - `maxResolution():​ number, number`  ​
-  获取GPU与其绑定屏幕支持的最大分辨率(二者取较小值)。+  获取GPU与其绑定屏幕支持的最大分辨率(二者取较小值)。 ​  
 +\\
 - `getResolution():​ number, number`  ​ - `getResolution():​ number, number`  ​
-  获取当前设定的分辨率。+  获取当前设定的分辨率。 ​  
 +\\
 - `setResolution(width:​ number, height: number): boolean`  ​ - `setResolution(width:​ number, height: number): boolean`  ​
-  设定分辨率。最大值可以为硬件支持的最大分辨率。若给定值超出范围或无效则会抛出错误。若分辨率成功修改则返回`true`(尝试将分辨率设定为与当前分辨率相同也可能会返回`false`),若失败则返回`false`。+  设定分辨率。最大值可以为硬件支持的最大分辨率。若给定值超出范围或无效则会抛出错误。若分辨率成功修改则返回`true`(尝试将分辨率设定为与当前分辨率相同也可能会返回`false`),若失败则返回`false`。 ​  
 +\\
 - `getViewport():​ number, number`  ​ - `getViewport():​ number, number`  ​
-  获取当前可见区域的分辨率。+  获取可见区域的分辨率。 ​  
 +\\
 - `setViewport(width:​ number, height: number): boolean`  ​ - `setViewport(width:​ number, height: number): boolean`  ​
-  设定当前可见区域的分辨率。若修改成功则返回`true`(尝试将分辨率设定为与当前分辨率相同也可能会返回`false`),若失败则返回`false`。此操作会使得屏幕分辨率看上去降低,但实际分辨率仍然不变。超出指定区域左上角的字符只是隐藏不显示,此功能是为了能在屏幕外渲染或显示内容,并在需要时将它们复制到可视区域内。改动分辨率会将可见区域修改为与分辨率相同。+  设定可见区域的分辨率。若修改成功则返回`true`(尝试将分辨率设定为与当前分辨率相同也可能会返回`false`),若失败则返回`false`。此操作会使得屏幕分辨率看上去降低,但实际分辨率仍然不变。超出指定区域左上角的字符只是隐藏不显示,此功能是为了能在屏幕外渲染或显示内容,并在需要时将它们复制到可视区域内。改动分辨率会将可见区域修改为与分辨率相同。 ​  
 +\\
 - <​del>​`getSize():​ number, number`  ​ - <​del>​`getSize():​ number, number`  ​
-  获取显卡绑定到的屏幕的尺寸,大小为格。对单方块屏幕和机器人而言只有一个。</​del>​ 已废弃,请改用`screen.getAspectRatio()`。+  获取显卡绑定到的屏幕的尺寸,大小为格。对单方块屏幕和机器人而言只有一个。</​del>​ 已废弃,请改用`screen.getAspectRatio()`。 ​  
 +\\
 - `get(x: number, y: number): string, number, number, number or nil, number or nil`  ​ - `get(x: number, y: number): string, number, number, number or nil, number or nil`  ​
-  获取指定坐标处当前显示的字符。第二个与第二个返回值是前景和背景色,形式为16进制值。若颜色来自调色盘,第四个和第五个返回值将代表颜色的调色板索引号,否则为`nil`。+  获取指定坐标处当前显示的字符。第二个与第二个返回值是前景和背景色,形式为16进制值。若颜色来自调色盘,第四个和第五个返回值将代表颜色的调色板索引号,否则为`nil`。 ​  
 +\\
 - `set(x: number, y: number, value: string[, vertical:​boolean]):​ boolean`  ​ - `set(x: number, y: number, value: string[, vertical:​boolean]):​ boolean`  ​
   向屏幕写一条字符串,从指定坐标开始。字符串将会被直接复制到屏幕缓冲区,仅复制到单行。这意味着就算有换行符给定字符串也不会换行,换行符只会被以特殊字符的形式显示,字符串不会以多行显示。若字符串被成功传输给缓冲区则返回`true`,若失败则返回`false`。 ​     向屏幕写一条字符串,从指定坐标开始。字符串将会被直接复制到屏幕缓冲区,仅复制到单行。这意味着就算有换行符给定字符串也不会换行,换行符只会被以特殊字符的形式显示,字符串不会以多行显示。若字符串被成功传输给缓冲区则返回`true`,若失败则返回`false`。 ​  
-  第四个参数为可选参数,若为`true`可以使给定文本竖行显示。+  第四个参数为可选参数,若为`true`可以使给定文本竖行显示。 ​  
 +\\
 - `copy(x: number, y: number, width: number, height: number, tx: number, ty: number): boolean`  ​ - `copy(x: number, y: number, width: number, height: number, tx: number, ty: number): boolean`  ​
- ​将屏幕缓冲区的一部分复制到另一个位置。复制来源为矩形,由`x`、`y`、`width`与`height`参数决定。目标位置由`x + tx`、`y + ty`、`width`与`height`决定(即`tx`和`ty`为相对坐标)。若成功返回`true`,若失败返回`false`。+ ​将屏幕缓冲区的一部分复制到另一个位置。复制来源为矩形,由`x`、`y`、`width`与`height`参数决定。目标位置由`x + tx`、`y + ty`、`width`与`height`决定(即`tx`和`ty`为相对坐标)。若成功返回`true`,若失败返回`false`。 ​   
 +\\
 - `fill(x: number, y: number, width: number, height: number, char: string): boolean`  ​ - `fill(x: number, y: number, width: number, height: number, char: string): boolean`  ​
   用指定字符填充屏幕缓冲区中的一个矩形区域。目标矩形区域由`x`与`y`坐标以及矩形的`width`(宽度)和`height`(高度)决定。填充字符参数`char`必须是长度为1的字符串,即单个字符。若成功返回`true`,若失败返回`false`。  ​   用指定字符填充屏幕缓冲区中的一个矩形区域。目标矩形区域由`x`与`y`坐标以及矩形的`width`(宽度)和`height`(高度)决定。填充字符参数`char`必须是长度为1的字符串,即单个字符。若成功返回`true`,若失败返回`false`。  ​
Line 101: Line 121:
 ----------- -----------
  
-请注意,哪怕是在切换色深后,原始的颜色值对(`number`型的“数`bool`型的“是否为调色板颜色)也会保留。实际在屏幕上渲染的颜色会被更新以符合新色深的限制,但是原始的24位RGB颜色值(或是调色板索引号)也不会丢失。例如,在处于1位色深模式下调用`gpu.getBackground`函数也会返回在先前的色深模式下指定的24位RGB颜色值。+请注意,哪怕是在切换色深后,原始的颜色值对(代表数据的`number`值与代表是否为调色板颜色的`bool`型值)也会保留。实际在屏幕上渲染的颜色会被更新以符合新色深的限制,但是原始的24位RGB颜色值(或是调色板索引号)也不会丢失。例如,在处于1位色深模式下调用`gpu.getBackground`函数也会返回在先前的色深模式下指定的24位RGB颜色值。
  
  
Line 107: Line 127:
 ============== ==============
  
-显卡的内部有显存,你可以将他们以页的形式进行分配。你可以自定义页大小(宽与高都需要大于0)。每次分配都会从显卡的显存中扣除宽度x高度的大小。高级别GPU的显存比低级别的多。页缓冲区的工作方式类似于隐藏不渲染的[[component:​screen:​zh|屏幕]],有其自己的宽度、高度和色深。GPU缓冲区支持的最大色深由GPU的等级决定。重启电脑将会释放所有的缓冲区。+显卡的内部有显存,你可以将他们以页的形式进行分配。你可以自定义页大小(宽与高都需要大于0)。每次分配都会从显卡的显存中扣除`宽度*高度`的大小。高级别GPU的显存比低级别的多。页缓冲区的工作方式类似于隐藏不渲染的[[component:​screen:​zh|屏幕]],有其自己的宽度、高度和色深。GPU缓冲区支持的最大色深由GPU的等级决定。重启电脑将会释放所有的缓冲区。
  
-每个缓冲区都有序号,GPU会查找下一个可用序号。序号零(0)有特殊用途,它是为屏幕保留的。无论GPU是否绑定到屏幕,你都可以分配页,设定它们是否启用,以及对它们进行读写。连接与断开屏幕,甚至是绑定到新屏幕,都不会释放GPU的页;而当电脑关机或重启时,页会被释放。每个GPU都有其独立的显存和页。+每个缓冲区都有序号,GPU会查找下一个可用序号。序号零(0)有特殊用途,它是为屏幕保留的。无论GPU是否绑定到屏幕,你都可以分配页,设定它们是否启用,以及对它们进行读写。连接与断开屏幕,甚至是绑定到新屏幕,都不会释放GPU的页;而当电脑关机或重启时,页会被释放。每个GPU都有其独立的显存和页。
  
 资源配额与能耗 资源配额与能耗
 ----------- -----------
  
-对显存的更新操作(set、copy和fill等)几乎没有消耗。这些操作不会耗能,也不会消耗额外资源配额。每次直接组件调用(GPU方法即为直接调用)都只消耗很少的系统资源配额,但是GPU本身在显存更新操作中不会增加资源消耗。将显存传输到屏幕时会有一定的资源消耗,类似于屏幕更新时产生的资源消耗。传输脏的(修改过的)显存后备缓冲区需要一次性消耗一定的资源,消耗的量随源缓冲区的大小而增加。而后续从干净的后备缓冲区到屏幕的传输只需要消耗极少的资源。+对显存的更新操作(set、copy和fill等)几乎没有消耗。这些操作不会耗能,也不会额外消耗资源配额。每次直接组件调用(GPU方法即为直接调用)都只消耗很少的系统资源配额,但是GPU本身在显存更新操作中不会增加资源消耗。将显存传输到屏幕时会有一定的资源消耗,类似于屏幕更新时产生的资源消耗。传输脏的(修改过的)显存后备缓冲区需要一次性消耗一定的资源,消耗的量随源缓冲区的大小而增加。而后续从干净的后备缓冲区到屏幕的传输只需要消耗极少的资源。
  
 - `getActiveBuffer():​ number`  ​ - `getActiveBuffer():​ number`  ​
-  返回当前选中缓冲区的编号。0被保留给屏幕,且就算没有屏幕也有可能会返回0。+  返回当前选中缓冲区的编号。0被保留给屏幕,且就算没有屏幕也有可能会返回0。 ​  
 +\\
 - `setActiveBuffer(index:​ number): number`  ​ - `setActiveBuffer(index:​ number): number`  ​
-  将活动缓冲区设定为`index`。0被保留给屏幕,且就算没有屏幕也可以设定。若编号无效则返回`nil`(0就算在没有屏幕的情况下也有效)。+  将活动缓冲区设定为`index`。0被保留给屏幕,且就算没有屏幕也可以设定。若编号无效则返回`nil`(0就算在没有屏幕的情况下也有效)。 ​  
 +\\
 - `buffers(): table`  ​ - `buffers(): table`  ​
-  返回包含当前所有页编号的数组(列表中不包含0,此编号保留给屏幕)。+  返回包含当前所有页编号的数组(列表中不包含0,此编号保留给屏幕)。 ​  
 +\\
 - `allocateBuffer([width:​ number, height: number]): number`  ​ - `allocateBuffer([width:​ number, height: number]): number`  ​
-  分配一个大小为`width`x`height`的新页(默认大小为GPU的最大分辨率)。返回此缓冲区的编号,若剩余显存不足则报错。即使GPU未绑定到屏幕也可以分配缓冲区。编号0永久保留给屏幕,因此分配出的缓冲区的编号最小从1开始。+  分配一个大小为`width`x`height`的新页(默认大小为GPU的最大分辨率)。返回此缓冲区的编号,若剩余显存不足则报错。即使GPU未绑定到屏幕也可以分配缓冲区。编号0永久保留给屏幕,因此分配缓冲区的编号最小从1开始。 ​  
 +\\
 - `freeBuffer([index:​ number]): boolean`  ​ - `freeBuffer([index:​ number]): boolean`  ​
-  移除编号为`index`(默认为当前缓冲区编号)的缓冲区。若成功移除此缓冲区则返回`true`。如果你移除了当前选中的缓冲区,GPU会自动切换回编号0(为屏幕保留)。+  移除编号为`index`(默认为当前缓冲区编号)的缓冲区。若成功移除此缓冲区则返回`true`。如果你移除了当前选中的缓冲区,GPU会自动切换回编号0(为屏幕保留)。 ​  
 +\\
 - `freeAllBuffers()`  ​ - `freeAllBuffers()`  ​
-   ​移除全部缓冲区,释放所有显存。在调用此函数后活动缓冲区编号一定为0。+   ​移除全部缓冲区,释放所有显存。在调用此函数后活动缓冲区编号一定为0。 ​  
 + \\
 - `totalMemory():​ number`  ​ - `totalMemory():​ number`  ​
-  返回GPU的显存总量。此值不包括屏幕。+  返回GPU的显存总量。此值不包括屏幕。 ​  
 +\\
 - `freeMemory():​ number`  ​ - `freeMemory():​ number`  ​
-  返回未分配给缓冲区的空闲显存总量。此值不包括屏幕。+  返回未分配给缓冲区的空闲显存总量。此值不包括屏幕。 ​  
 +\\
 - `getBufferSize([index:​ number]): number, number`  ​ - `getBufferSize([index:​ number]): number, number`  ​
-  返回编号为`index`(默认为当前缓冲区编号的缓冲区的大小。若编号为0则返回屏幕的分辨率。若编号无效则返回`nil`。+  返回编号为`index`的缓冲区(默认为当前缓冲区)的大小。若编号为0则返回屏幕的分辨率。若编号无效则返回`nil`。 ​  
 +\\
 - `bitblt([dst:​ number, col: number, row: number, width: number, height: number, src: number, fromCol: number, fromRow: number])`  ​ - `bitblt([dst:​ number, col: number, row: number, width: number, height: number, src: number, fromCol: number, fromRow: number])`  ​
   将一个矩形区域从缓冲区复制到缓冲区,从屏幕复制到缓冲区或从缓冲区复制到屏幕。  ​   将一个矩形区域从缓冲区复制到缓冲区,从屏幕复制到缓冲区或从缓冲区复制到屏幕。  ​
Line 142: Line 171:
   * src = 当前缓冲区   * src = 当前缓冲区
   * fromCol, fromRow = 1,​1  ​   * fromCol, fromRow = 1,​1  ​
-  bitblt(位块传输)函数在反复调用时应当执行得很快。若缓冲区是脏的,那么与目标对象同步缓冲区的初始成本会更高。如果你需要大量进行更新,导致频繁进行位块传输,那么可以考虑分配数量多而尺寸小的缓冲区。如果你希望使用一个静态缓冲区(很少或不进行更新),那么分配大的缓冲区即可。  ​+  bitblt(位块传输)在反复进行时应当执行得很快。若缓冲区是脏的,那么与目标对象同步缓冲区的初始成本会更高。如果你需要大量进行更新,导致频繁进行位块传输,那么可以考虑分配数量多而尺寸小的缓冲区。如果你希望使用一个静态缓冲区(很少或不进行更新),那么分配大的缓冲区即可。  ​
   操作成功后会返回`true`。   操作成功后会返回`true`。