BufferBuilder.java

com.mojang.blaze3d.vertex.BufferBuilder

信息

  • 全限定名:com.mojang.blaze3d.vertex.BufferBuilder
  • 类型:public class
  • 包:com.mojang.blaze3d.vertex
  • 源码路径:src/main/java/com/mojang/blaze3d/vertex/BufferBuilder.java
  • 起始行号:L13
  • 实现:VertexConsumer
  • 职责:

    TODO

字段/常量

  • MAX_VERTEX_COUNT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L14
    • 说明:

      TODO

  • NOT_BUILDING

    • 类型: long
    • 修饰符: private static final
    • 源码定位: L15
    • 说明:

      TODO

  • UNKNOWN_ELEMENT

    • 类型: long
    • 修饰符: private static final
    • 源码定位: L16
    • 说明:

      TODO

  • IS_LITTLE_ENDIAN

    • 类型: boolean
    • 修饰符: private static final
    • 源码定位: L17
    • 说明:

      TODO

  • buffer

    • 类型: ByteBufferBuilder
    • 修饰符: private final
    • 源码定位: L18
    • 说明:

      TODO

  • vertexPointer

    • 类型: long
    • 修饰符: private
    • 源码定位: L19
    • 说明:

      TODO

  • vertices

    • 类型: int
    • 修饰符: private
    • 源码定位: L20
    • 说明:

      TODO

  • format

    • 类型: VertexFormat
    • 修饰符: private final
    • 源码定位: L21
    • 说明:

      TODO

  • mode

    • 类型: VertexFormat.Mode
    • 修饰符: private final
    • 源码定位: L22
    • 说明:

      TODO

  • fastFormat

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L23
    • 说明:

      TODO

  • fullFormat

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L24
    • 说明:

      TODO

  • vertexSize

    • 类型: int
    • 修饰符: private final
    • 源码定位: L25
    • 说明:

      TODO

  • initialElementsToFill

    • 类型: int
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • offsetsByElement

    • 类型: int[]
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

  • elementsToFill

    • 类型: int
    • 修饰符: private
    • 源码定位: L28
    • 说明:

      TODO

  • building

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L29
    • 说明:

      TODO

内部类/嵌套类型

构造器

public BufferBuilder(ByteBufferBuilder buffer, VertexFormat.Mode mode, VertexFormat format) @ L31

  • 构造器名:BufferBuilder
  • 源码定位:L31
  • 修饰符:public

参数:

  • buffer: ByteBufferBuilder
  • mode: VertexFormat.Mode
  • format: VertexFormat

说明:

TODO

方法

下面的方法块按源码顺序生成。

public MeshData build() @ L48

  • 方法名:build
  • 源码定位:L48
  • 返回类型:MeshData
  • 修饰符:public

参数:

说明:

TODO

public MeshData buildOrThrow() @ L57

  • 方法名:buildOrThrow
  • 源码定位:L57
  • 返回类型:MeshData
  • 修饰符:public

参数:

说明:

TODO

private void ensureBuilding() @ L66

  • 方法名:ensureBuilding
  • 源码定位:L66
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private MeshData storeMesh() @ L72

  • 方法名:storeMesh
  • 源码定位:L72
  • 返回类型:MeshData
  • 修饰符:private

参数:

说明:

TODO

private long beginVertex() @ L87

  • 方法名:beginVertex
  • 源码定位:L87
  • 返回类型:long
  • 修饰符:private

参数:

说明:

TODO

private long beginElement(VertexFormatElement element) @ L100

  • 方法名:beginElement
  • 源码定位:L100
  • 返回类型:long
  • 修饰符:private

参数:

  • element: VertexFormatElement

说明:

TODO

private void endLastVertex() @ L116

  • 方法名:endLastVertex
  • 源码定位:L116
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private static void putRgba(long pointer, int argb) @ L133

  • 方法名:putRgba
  • 源码定位:L133
  • 返回类型:void
  • 修饰符:private static

参数:

  • pointer: long
  • argb: int

说明:

TODO

private static void putPackedUv(long pointer, int packedUv) @ L138

  • 方法名:putPackedUv
  • 源码定位:L138
  • 返回类型:void
  • 修饰符:private static

参数:

  • pointer: long
  • packedUv: int

说明:

TODO

public VertexConsumer addVertex(float x, float y, float z) @ L147

  • 方法名:addVertex
  • 源码定位:L147
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • x: float
  • y: float
  • z: float

说明:

TODO

public VertexConsumer setColor(int r, int g, int b, int a) @ L157

  • 方法名:setColor
  • 源码定位:L157
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • r: int
  • g: int
  • b: int
  • a: int

说明:

TODO

public VertexConsumer setColor(int color) @ L170

  • 方法名:setColor
  • 源码定位:L170
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • color: int

说明:

TODO

public VertexConsumer setUv(float u, float v) @ L180

  • 方法名:setUv
  • 源码定位:L180
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • u: float
  • v: float

说明:

TODO

public VertexConsumer setUv1(int u, int v) @ L191

  • 方法名:setUv1
  • 源码定位:L191
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • u: int
  • v: int

说明:

TODO

public VertexConsumer setOverlay(int packedOverlayCoords) @ L196

  • 方法名:setOverlay
  • 源码定位:L196
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • packedOverlayCoords: int

说明:

TODO

public VertexConsumer setUv2(int u, int v) @ L206

  • 方法名:setUv2
  • 源码定位:L206
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • u: int
  • v: int

说明:

TODO

public VertexConsumer setLight(int packedLightCoords) @ L211

  • 方法名:setLight
  • 源码定位:L211
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • packedLightCoords: int

说明:

TODO

private VertexConsumer uvShort(short u, short v, VertexFormatElement element) @ L221

  • 方法名:uvShort
  • 源码定位:L221
  • 返回类型:VertexConsumer
  • 修饰符:private

参数:

  • u: short
  • v: short
  • element: VertexFormatElement

说明:

TODO

public VertexConsumer setNormal(float x, float y, float z) @ L231

  • 方法名:setNormal
  • 源码定位:L231
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • x: float
  • y: float
  • z: float

说明:

TODO

public VertexConsumer setLineWidth(float width) @ L243

  • 方法名:setLineWidth
  • 源码定位:L243
  • 返回类型:VertexConsumer
  • 修饰符:public

参数:

  • width: float

说明:

TODO

private static byte normalIntValue(float c) @ L253

  • 方法名:normalIntValue
  • 源码定位:L253
  • 返回类型:byte
  • 修饰符:private static

参数:

  • c: float

说明:

TODO

public void addVertex(float x, float y, float z, int color, float u, float v, int overlayCoords, int lightCoords, float nx, float ny, float nz) @ L257

  • 方法名:addVertex
  • 源码定位:L257
  • 返回类型:void
  • 修饰符:public

参数:

  • x: float
  • y: float
  • z: float
  • color: int
  • u: float
  • v: float
  • overlayCoords: int
  • lightCoords: int
  • nx: float
  • ny: float
  • nz: float

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class BufferBuilder implements VertexConsumer {
    private static final int MAX_VERTEX_COUNT = 16777215;
    private static final long NOT_BUILDING = -1L;
    private static final long UNKNOWN_ELEMENT = -1L;
    private static final boolean IS_LITTLE_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN;
    private final ByteBufferBuilder buffer;
    private long vertexPointer = -1L;
    private int vertices;
    private final VertexFormat format;
    private final VertexFormat.Mode mode;
    private final boolean fastFormat;
    private final boolean fullFormat;
    private final int vertexSize;
    private final int initialElementsToFill;
    private final int[] offsetsByElement;
    private int elementsToFill;
    private boolean building = true;
 
    public BufferBuilder(ByteBufferBuilder buffer, VertexFormat.Mode mode, VertexFormat format) {
        if (!format.contains(VertexFormatElement.POSITION)) {
            throw new IllegalArgumentException("Cannot build mesh with no position element");
        } else {
            this.buffer = buffer;
            this.mode = mode;
            this.format = format;
            this.vertexSize = format.getVertexSize();
            this.initialElementsToFill = format.getElementsMask() & ~VertexFormatElement.POSITION.mask();
            this.offsetsByElement = format.getOffsetsByElement();
            boolean isFullFormat = format == DefaultVertexFormat.ENTITY;
            boolean isBlockFormat = format == DefaultVertexFormat.BLOCK;
            this.fastFormat = isFullFormat || isBlockFormat;
            this.fullFormat = isFullFormat;
        }
    }
 
    public @Nullable MeshData build() {
        this.ensureBuilding();
        this.endLastVertex();
        MeshData mesh = this.storeMesh();
        this.building = false;
        this.vertexPointer = -1L;
        return mesh;
    }
 
    public MeshData buildOrThrow() {
        MeshData buffer = this.build();
        if (buffer == null) {
            throw new IllegalStateException("BufferBuilder was empty");
        } else {
            return buffer;
        }
    }
 
    private void ensureBuilding() {
        if (!this.building) {
            throw new IllegalStateException("Not building!");
        }
    }
 
    private @Nullable MeshData storeMesh() {
        if (this.vertices == 0) {
            return null;
        } else {
            ByteBufferBuilder.Result vertexBuffer = this.buffer.build();
            if (vertexBuffer == null) {
                return null;
            } else {
                int indices = this.mode.indexCount(this.vertices);
                VertexFormat.IndexType indexType = VertexFormat.IndexType.least(this.vertices);
                return new MeshData(vertexBuffer, new MeshData.DrawState(this.format, this.vertices, indices, this.mode, indexType));
            }
        }
    }
 
    private long beginVertex() {
        this.ensureBuilding();
        this.endLastVertex();
        if (this.vertices >= 16777215) {
            throw new IllegalStateException("Trying to write too many vertices (>16777215) into BufferBuilder");
        } else {
            this.vertices++;
            long pointer = this.buffer.reserve(this.vertexSize);
            this.vertexPointer = pointer;
            return pointer;
        }
    }
 
    private long beginElement(VertexFormatElement element) {
        int oldElements = this.elementsToFill;
        int newElements = oldElements & ~element.mask();
        if (newElements == oldElements) {
            return -1L;
        } else {
            this.elementsToFill = newElements;
            long vertexPointer = this.vertexPointer;
            if (vertexPointer == -1L) {
                throw new IllegalArgumentException("Not currently building vertex");
            } else {
                return vertexPointer + this.offsetsByElement[element.id()];
            }
        }
    }
 
    private void endLastVertex() {
        if (this.vertices != 0) {
            if (this.elementsToFill != 0) {
                String missingElements = VertexFormatElement.elementsFromMask(this.elementsToFill)
                    .map(this.format::getElementName)
                    .collect(Collectors.joining(", "));
                throw new IllegalStateException("Missing elements in vertex: " + missingElements);
            } else {
                if (this.mode == VertexFormat.Mode.LINES) {
                    long pointer = this.buffer.reserve(this.vertexSize);
                    MemoryUtil.memCopy(pointer - this.vertexSize, pointer, this.vertexSize);
                    this.vertices++;
                }
            }
        }
    }
 
    private static void putRgba(long pointer, int argb) {
        int abgr = ARGB.toABGR(argb);
        MemoryUtil.memPutInt(pointer, IS_LITTLE_ENDIAN ? abgr : Integer.reverseBytes(abgr));
    }
 
    private static void putPackedUv(long pointer, int packedUv) {
        if (IS_LITTLE_ENDIAN) {
            MemoryUtil.memPutInt(pointer, packedUv);
        } else {
            MemoryUtil.memPutShort(pointer, (short)(packedUv & 65535));
            MemoryUtil.memPutShort(pointer + 2L, (short)(packedUv >> 16 & 65535));
        }
    }
 
    @Override
    public VertexConsumer addVertex(float x, float y, float z) {
        long pointer = this.beginVertex() + this.offsetsByElement[VertexFormatElement.POSITION.id()];
        this.elementsToFill = this.initialElementsToFill;
        MemoryUtil.memPutFloat(pointer, x);
        MemoryUtil.memPutFloat(pointer + 4L, y);
        MemoryUtil.memPutFloat(pointer + 8L, z);
        return this;
    }
 
    @Override
    public VertexConsumer setColor(int r, int g, int b, int a) {
        long pointer = this.beginElement(VertexFormatElement.COLOR);
        if (pointer != -1L) {
            MemoryUtil.memPutByte(pointer, (byte)r);
            MemoryUtil.memPutByte(pointer + 1L, (byte)g);
            MemoryUtil.memPutByte(pointer + 2L, (byte)b);
            MemoryUtil.memPutByte(pointer + 3L, (byte)a);
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setColor(int color) {
        long pointer = this.beginElement(VertexFormatElement.COLOR);
        if (pointer != -1L) {
            putRgba(pointer, color);
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setUv(float u, float v) {
        long pointer = this.beginElement(VertexFormatElement.UV0);
        if (pointer != -1L) {
            MemoryUtil.memPutFloat(pointer, u);
            MemoryUtil.memPutFloat(pointer + 4L, v);
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setUv1(int u, int v) {
        return this.uvShort((short)u, (short)v, VertexFormatElement.UV1);
    }
 
    @Override
    public VertexConsumer setOverlay(int packedOverlayCoords) {
        long pointer = this.beginElement(VertexFormatElement.UV1);
        if (pointer != -1L) {
            putPackedUv(pointer, packedOverlayCoords);
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setUv2(int u, int v) {
        return this.uvShort((short)u, (short)v, VertexFormatElement.UV2);
    }
 
    @Override
    public VertexConsumer setLight(int packedLightCoords) {
        long pointer = this.beginElement(VertexFormatElement.UV2);
        if (pointer != -1L) {
            putPackedUv(pointer, packedLightCoords);
        }
 
        return this;
    }
 
    private VertexConsumer uvShort(short u, short v, VertexFormatElement element) {
        long pointer = this.beginElement(element);
        if (pointer != -1L) {
            MemoryUtil.memPutShort(pointer, u);
            MemoryUtil.memPutShort(pointer + 2L, v);
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setNormal(float x, float y, float z) {
        long pointer = this.beginElement(VertexFormatElement.NORMAL);
        if (pointer != -1L) {
            MemoryUtil.memPutByte(pointer, normalIntValue(x));
            MemoryUtil.memPutByte(pointer + 1L, normalIntValue(y));
            MemoryUtil.memPutByte(pointer + 2L, normalIntValue(z));
        }
 
        return this;
    }
 
    @Override
    public VertexConsumer setLineWidth(float width) {
        long pointer = this.beginElement(VertexFormatElement.LINE_WIDTH);
        if (pointer != -1L) {
            MemoryUtil.memPutFloat(pointer, width);
        }
 
        return this;
    }
 
    private static byte normalIntValue(float c) {
        return (byte)((int)(Mth.clamp(c, -1.0F, 1.0F) * 127.0F) & 0xFF);
    }
 
    @Override
    public void addVertex(float x, float y, float z, int color, float u, float v, int overlayCoords, int lightCoords, float nx, float ny, float nz) {
        if (this.fastFormat) {
            long pointer = this.beginVertex();
            MemoryUtil.memPutFloat(pointer + 0L, x);
            MemoryUtil.memPutFloat(pointer + 4L, y);
            MemoryUtil.memPutFloat(pointer + 8L, z);
            putRgba(pointer + 12L, color);
            MemoryUtil.memPutFloat(pointer + 16L, u);
            MemoryUtil.memPutFloat(pointer + 20L, v);
            long lightStart;
            if (this.fullFormat) {
                putPackedUv(pointer + 24L, overlayCoords);
                lightStart = pointer + 28L;
            } else {
                lightStart = pointer + 24L;
            }
 
            putPackedUv(lightStart + 0L, lightCoords);
            if (this.fullFormat) {
                MemoryUtil.memPutByte(lightStart + 4L, normalIntValue(nx));
                MemoryUtil.memPutByte(lightStart + 5L, normalIntValue(ny));
                MemoryUtil.memPutByte(lightStart + 6L, normalIntValue(nz));
            }
        } else {
            VertexConsumer.super.addVertex(x, y, z, color, u, v, overlayCoords, lightCoords, nx, ny, nz);
        }
    }
}

引用的其他类

  • ByteBufferBuilder

    • 引用位置: 参数/字段
  • MeshData

    • 引用位置: 方法调用/构造调用/返回值
    • 关联成员: DrawState(), MeshData(), MeshData.DrawState()
  • VertexConsumer

    • 引用位置: 实现/返回值
  • VertexFormat

    • 引用位置: 参数/字段/方法调用
    • 关联成员: VertexFormat.IndexType.least()
  • VertexFormatElement

    • 引用位置: 参数/方法调用
    • 关联成员: VertexFormatElement.elementsFromMask()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.toABGR()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.clamp()