Skip to content

使用绘制上下文

本文假设您已经看过基本渲染概念

DrawContext 是控制渲染的核心类。 它提供了诸多渲染图形、文字、纹理的方法,此外还用来操纵 MatrixStackBufferBuilder

绘制图形

使用 DrawContext 绘制矩形十分容易。 如果您想绘制三角形或其他不规则图形,您需要使用 BufferBuilder 手动添加图形顶点信息。

绘制矩形

您可以使用 DrawContext#fill 方法来绘制一个实心矩形。

java
int rectangleX = 10;
int rectangleY = 10;
int rectangleWidth = 100;
int rectangleHeight = 50;
// x1, y1, x2, y2, color
context.fill(rectangleX, rectangleY, rectangleX + rectangleWidth, rectangleY + rectangleHeight, 0xFF0000FF);

矩形

绘制边框

假设我们想勾勒出我们刚才绘制的矩形的轮廓。 我们可以使用 DrawContext#drawBorder 方法来绘制轮廓。

java
// x, y, width, height, color
context.drawBorder(rectangleX, rectangleY, rectangleWidth, rectangleHeight, 0xFFFF0000);

带边框的矩形

绘制线条

我们可以使用 DrawContext#drawHorizontalLineDrawContext#drawVerticalLine 来绘制线条。

java
// Let's split the rectangle in half using a green line.
// x, y1, y2, color
context.drawVerticalLine(rectangleX + rectangleWidth / 2, rectangleY, rectangleY + rectangleHeight, 0xFF00FF00);

线条

裁剪

DrawContext 有一套内建的裁剪功能。 它可以用来裁剪渲染区域。 这个功能在绘制某些元素时十分有用,比如悬浮提示,或者其他不应该超出指定渲染区域的界面元素。

使用裁剪功能

TIP

裁剪区域可以内嵌! 但是请一定配对 enableScissordisableScissor,否则错误的裁剪区域将影响到其他界面元素。

要启用裁剪功能,只需调用 DrawContext#enableScissor 方法。 同样地,调用 DrawContext#disableScissor 方法以禁用裁剪功能。

java
// Let's create a scissor region that covers a middle bar section of the screen.
int scissorRegionX = 200;
int scissorRegionY = 20;
int scissorRegionWidth = 100;

// The height of the scissor region is the height of the screen minus the height of the top and bottom bars.
int scissorRegionHeight = this.height - 40;

// x1, y1, x2, y2
context.enableScissor(scissorRegionX, scissorRegionY, scissorRegionX + scissorRegionWidth, scissorRegionY + scissorRegionHeight);

// Let's fill the entire screen with a color gradient, it should only be visible in the scissor region.
// x1, y1, x2, y2, color1, color2
context.fillGradient(0, 0, this.width, this.height, 0xFFFF0000, 0xFF0000FF);

// Disable the scissor region.
context.disableScissor();

裁剪区域

如您所见,即使我们让游戏尝试用渐变色铺满整个界面,它却只能在裁剪区域内绘制。

绘制纹理

注意,不存在唯一“正确”的绘制纹理的方法,因为 drawTexture 有很多重载。 本节内容只会涵盖最常用的方法。

绘制整个纹理

一般来说,我们推荐您使用需要指定 textureWidthtextureHeight 参数的 drawTexture 方法重载。 因为如果使用不指定的重载, DrawContext 会假设您的纹理文件尺寸是 256x256,而您的纹理文件不一定是这个尺寸,于是渲染结果就不一定正确。

java
Identifier texture = new Identifier("minecraft", "textures/block/deepslate.png");
// texture, x, y, u, v, width, height, textureWidth, textureHeight
context.drawTexture(texture, 90, 90, 0, 0, 16, 16, 16, 16);

绘制整个纹理

绘制纹理的一部分

在这个情形中,我们需要指定纹理区域的 uv。 这俩参数用于指定纹理区域左上角的坐标。另外,regionWidthregionHeight 参数用于指定纹理区域的尺寸。

我们以此纹理为例。

配方书纹理

如果我们只希望绘制包含放大镜的区域,我们可以使用如下 uvregionWidthregionHeight 值:

java
Identifier texture2 = new Identifier("fabric-docs-reference", "textures/gui/test-uv-drawing.png");
int u = 10, v = 13, regionWidth = 14, regionHeight = 14;
// texture, x, y, width, height, u, v, regionWidth, regionHeight, textureWidth, textureHeight
context.drawTexture(texture2, 90, 190, 14, 14, u, v, regionWidth, regionHeight, 256, 256);

绘制纹理的一部分

绘制文字

DrawContext 提供了许多不言自明的渲染文字的方法,您可以自行尝试,此处不再赘述。

假设我们想在界面上绘制 Hello World。 我们可以使用 DrawContext#drawText 方法来完成。

java
// TextRenderer, text (string, or Text object), x, y, color, shadow
context.drawText(client.textRenderer, "Hello, world!", 10, 200, 0xFFFFFFFF, false);

绘制文字