211 lines
5.3 KiB
Java
211 lines
5.3 KiB
Java
package com.mojang.blaze3d.vertex;
|
|
|
|
import com.mojang.blaze3d.buffers.BufferType;
|
|
import com.mojang.blaze3d.buffers.BufferUsage;
|
|
import com.mojang.blaze3d.buffers.GpuBuffer;
|
|
import com.mojang.blaze3d.platform.GlStateManager;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
import com.mojang.blaze3d.vertex.MeshData.DrawState;
|
|
import java.nio.ByteBuffer;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.renderer.CompiledShaderProgram;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.joml.Matrix4f;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class VertexBuffer implements AutoCloseable {
|
|
private final BufferUsage usage;
|
|
private final GpuBuffer vertexBuffer;
|
|
@Nullable
|
|
private GpuBuffer indexBuffer = null;
|
|
private int arrayObjectId;
|
|
@Nullable
|
|
private VertexFormat format;
|
|
@Nullable
|
|
private RenderSystem.AutoStorageIndexBuffer sequentialIndices;
|
|
private VertexFormat.IndexType indexType;
|
|
private int indexCount;
|
|
private VertexFormat.Mode mode;
|
|
|
|
public VertexBuffer(BufferUsage bufferUsage) {
|
|
this.usage = bufferUsage;
|
|
RenderSystem.assertOnRenderThread();
|
|
this.vertexBuffer = new GpuBuffer(BufferType.VERTICES, bufferUsage, 0);
|
|
this.arrayObjectId = GlStateManager._glGenVertexArrays();
|
|
}
|
|
|
|
public void upload(MeshData meshData) {
|
|
MeshData var2 = meshData;
|
|
|
|
label40: {
|
|
try {
|
|
if (this.isInvalid()) {
|
|
break label40;
|
|
}
|
|
|
|
RenderSystem.assertOnRenderThread();
|
|
DrawState drawState = meshData.drawState();
|
|
this.format = this.uploadVertexBuffer(drawState, meshData.vertexBuffer());
|
|
this.sequentialIndices = this.uploadIndexBuffer(drawState, meshData.indexBuffer());
|
|
this.indexCount = drawState.indexCount();
|
|
this.indexType = drawState.indexType();
|
|
this.mode = drawState.mode();
|
|
} catch (Throwable var6) {
|
|
if (meshData != null) {
|
|
try {
|
|
var2.close();
|
|
} catch (Throwable var5) {
|
|
var6.addSuppressed(var5);
|
|
}
|
|
}
|
|
|
|
throw var6;
|
|
}
|
|
|
|
if (meshData != null) {
|
|
meshData.close();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (meshData != null) {
|
|
meshData.close();
|
|
}
|
|
}
|
|
|
|
public void uploadIndexBuffer(ByteBufferBuilder.Result result) {
|
|
ByteBufferBuilder.Result var2 = result;
|
|
|
|
label46: {
|
|
try {
|
|
if (this.isInvalid()) {
|
|
break label46;
|
|
}
|
|
|
|
RenderSystem.assertOnRenderThread();
|
|
if (this.indexBuffer != null) {
|
|
this.indexBuffer.close();
|
|
}
|
|
|
|
this.indexBuffer = new GpuBuffer(BufferType.INDICES, this.usage, result.byteBuffer());
|
|
this.sequentialIndices = null;
|
|
} catch (Throwable var6) {
|
|
if (result != null) {
|
|
try {
|
|
var2.close();
|
|
} catch (Throwable var5) {
|
|
var6.addSuppressed(var5);
|
|
}
|
|
}
|
|
|
|
throw var6;
|
|
}
|
|
|
|
if (result != null) {
|
|
result.close();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (result != null) {
|
|
result.close();
|
|
}
|
|
}
|
|
|
|
private VertexFormat uploadVertexBuffer(DrawState drawState, @Nullable ByteBuffer buffer) {
|
|
boolean bl = false;
|
|
if (!drawState.format().equals(this.format)) {
|
|
if (this.format != null) {
|
|
this.format.clearBufferState();
|
|
}
|
|
|
|
this.vertexBuffer.bind();
|
|
drawState.format().setupBufferState();
|
|
bl = true;
|
|
}
|
|
|
|
if (buffer != null) {
|
|
if (!bl) {
|
|
this.vertexBuffer.bind();
|
|
}
|
|
|
|
this.vertexBuffer.resize(buffer.remaining());
|
|
this.vertexBuffer.write(buffer, 0);
|
|
}
|
|
|
|
return drawState.format();
|
|
}
|
|
|
|
@Nullable
|
|
private RenderSystem.AutoStorageIndexBuffer uploadIndexBuffer(DrawState drawState, @Nullable ByteBuffer buffer) {
|
|
if (buffer != null) {
|
|
if (this.indexBuffer != null) {
|
|
this.indexBuffer.close();
|
|
}
|
|
|
|
this.indexBuffer = new GpuBuffer(BufferType.INDICES, this.usage, buffer);
|
|
return null;
|
|
} else {
|
|
RenderSystem.AutoStorageIndexBuffer autoStorageIndexBuffer = RenderSystem.getSequentialBuffer(drawState.mode());
|
|
if (autoStorageIndexBuffer != this.sequentialIndices || !autoStorageIndexBuffer.hasStorage(drawState.indexCount())) {
|
|
autoStorageIndexBuffer.bind(drawState.indexCount());
|
|
}
|
|
|
|
return autoStorageIndexBuffer;
|
|
}
|
|
}
|
|
|
|
public void bind() {
|
|
BufferUploader.invalidate();
|
|
GlStateManager._glBindVertexArray(this.arrayObjectId);
|
|
}
|
|
|
|
public static void unbind() {
|
|
BufferUploader.invalidate();
|
|
GlStateManager._glBindVertexArray(0);
|
|
}
|
|
|
|
public void draw() {
|
|
RenderSystem.drawElements(this.mode.asGLMode, this.indexCount, this.getIndexType().asGLType);
|
|
}
|
|
|
|
private VertexFormat.IndexType getIndexType() {
|
|
RenderSystem.AutoStorageIndexBuffer autoStorageIndexBuffer = this.sequentialIndices;
|
|
return autoStorageIndexBuffer != null ? autoStorageIndexBuffer.type() : this.indexType;
|
|
}
|
|
|
|
public void drawWithShader(Matrix4f matrix4f, Matrix4f matrix4f2, @Nullable CompiledShaderProgram compiledShaderProgram) {
|
|
if (compiledShaderProgram != null) {
|
|
RenderSystem.assertOnRenderThread();
|
|
compiledShaderProgram.setDefaultUniforms(this.mode, matrix4f, matrix4f2, Minecraft.getInstance().getWindow());
|
|
compiledShaderProgram.apply();
|
|
this.draw();
|
|
compiledShaderProgram.clear();
|
|
}
|
|
}
|
|
|
|
public void close() {
|
|
this.vertexBuffer.close();
|
|
if (this.indexBuffer != null) {
|
|
this.indexBuffer.close();
|
|
this.indexBuffer = null;
|
|
}
|
|
|
|
if (this.arrayObjectId >= 0) {
|
|
RenderSystem.glDeleteVertexArrays(this.arrayObjectId);
|
|
this.arrayObjectId = -1;
|
|
}
|
|
}
|
|
|
|
public VertexFormat getFormat() {
|
|
return this.format;
|
|
}
|
|
|
|
public boolean isInvalid() {
|
|
return this.arrayObjectId == -1;
|
|
}
|
|
}
|